double comparison fixes

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@32375 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2011-02-26 06:29:57 +00:00
parent 2258d6c8b7
commit 9a93ff4ceb
4 changed files with 56 additions and 81 deletions

View file

@ -1,3 +1,10 @@
2011-02-26 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSDecimal.m:
Fix NaN comparison in GSDecimalCompare()
* Source/NSNumber.m:
Better match OSX for double comparison.
2011-02-24 Richard Frith-Macdonald <rfm@gnu.org> 2011-02-24 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSNumber.m: * Source/NSNumber.m:

View file

@ -172,6 +172,14 @@ GSDecimalCompare(const GSDecimal *leftOperand, const GSDecimal *rightOperand)
int s1 = leftOperand->exponent + leftOperand->length; int s1 = leftOperand->exponent + leftOperand->length;
int s2 = rightOperand->exponent + rightOperand->length; int s2 = rightOperand->exponent + rightOperand->length;
if (leftOperand->validNumber != rightOperand->validNumber)
{
if (rightOperand->validNumber)
return NSOrderedDescending;
else
return NSOrderedAscending;
}
if (leftOperand->isNegative != rightOperand->isNegative) if (leftOperand->isNegative != rightOperand->isNegative)
{ {
if (rightOperand->isNegative) if (rightOperand->isNegative)

View file

@ -202,6 +202,7 @@ static NSDecimalNumber *one;
{ {
return maxNumber; return maxNumber;
} }
+ (NSDecimalNumber*) minimumDecimalNumber + (NSDecimalNumber*) minimumDecimalNumber
{ {
return minNumber; return minNumber;
@ -712,6 +713,10 @@ static NSDecimalNumber *one;
{ {
return NSOrderedSame; return NSOrderedSame;
} }
if (self == notANumber)
{
return NSOrderedAscending; // NaN is considered less than anything
}
if ([decimalNumber isKindOfClass: NSDecimalNumberClass]) if ([decimalNumber isKindOfClass: NSDecimalNumberClass])
{ {
NSDecimal d1 = [self decimalValue]; NSDecimal d1 = [self decimalValue];

View file

@ -101,6 +101,39 @@ if (value > other)\
}\ }\
return NSOrderedSame; return NSOrderedSame;
#define DCOMPARE(value, other) \
if (isnan(value)) \
{ \
if (isnan(other)) \
{ \
return NSOrderedSame; \
} \
else \
{ \
return NSOrderedAscending; \
} \
} \
else \
{ \
if (isnan(other)) \
{ \
if (value < 0.0) \
{ \
return NSOrderedAscending; \
} \
return NSOrderedDescending; \
} \
else if (value < other) \
{ \
return NSOrderedAscending; \
} \
else if (value > other) \
{ \
return NSOrderedDescending; \
} \
return NSOrderedSame; \
}
@implementation NSSignedIntegerNumber @implementation NSSignedIntegerNumber
- (NSComparisonResult) compare: (NSNumber*)aNumber - (NSComparisonResult) compare: (NSNumber*)aNumber
{ {
@ -164,33 +197,7 @@ return NSOrderedSame;
double other = [aNumber doubleValue]; double other = [aNumber doubleValue];
double value = [self doubleValue]; double value = [self doubleValue];
if (isnan(value)) DCOMPARE(value, other)
{
if (isnan(other))
{
return NSOrderedSame;
}
else
{
return NSOrderedAscending;
}
}
else
{
if (isnan(other))
{
return NSOrderedDescending;
}
else if (value < other)
{
return NSOrderedAscending;
}
else if (value > other)
{
return NSOrderedDescending;
}
return NSOrderedSame;
}
} }
default: default:
[NSException raise: NSInvalidArgumentException [NSException raise: NSInvalidArgumentException
@ -267,33 +274,7 @@ return NSOrderedSame;
double other = [aNumber doubleValue]; double other = [aNumber doubleValue];
double selfv = [self doubleValue]; double selfv = [self doubleValue];
if (isnan(selfv)) DCOMPARE(selfv, other)
{
if (isnan(other))
{
return NSOrderedSame;
}
else
{
return NSOrderedAscending;
}
}
else
{
if (isnan(other))
{
return NSOrderedDescending;
}
else if (selfv < other)
{
return NSOrderedAscending;
}
else if (selfv > other)
{
return NSOrderedDescending;
}
return NSOrderedSame;
}
} }
default: default:
[NSException raise: NSInvalidArgumentException [NSException raise: NSInvalidArgumentException
@ -336,33 +317,7 @@ return NSOrderedSame;
other = [aNumber doubleValue]; other = [aNumber doubleValue];
value = [self doubleValue]; value = [self doubleValue];
if (isnan(value)) DCOMPARE(value, other)
{
if (isnan(other))
{
return NSOrderedSame;
}
else
{
return NSOrderedAscending;
}
}
else
{
if (isnan(other))
{
return NSOrderedDescending;
}
else if (value < other)
{
return NSOrderedAscending;
}
else if (value > other)
{
return NSOrderedDescending;
}
return NSOrderedSame;
}
} }
@end @end