@@ -460,6 +460,12 @@ open class NSNumber : NSValue {
460
460
CFNumberGetValue ( _cfObject, kCFNumberSInt128Type, & value)
461
461
return . init( truncatingIfNeeded: value. low)
462
462
}
463
+
464
+ private var int128Value : CFSInt128Struct {
465
+ var value = CFSInt128Struct ( high: 0 , low: 0 )
466
+ CFNumberGetValue ( _cfObject, kCFNumberSInt128Type, & value)
467
+ return value
468
+ }
463
469
464
470
open var floatValue : Float {
465
471
var value : Float = 0
@@ -516,22 +522,26 @@ open class NSNumber : NSValue {
516
522
}
517
523
518
524
open func compare( _ otherNumber: NSNumber ) -> ComparisonResult {
519
- switch ( objCType . pointee , otherNumber. objCType . pointee ) {
520
- case ( 0x66 , _) , ( _, 0x66 ) , ( 0x66 , 0x66 ) : fallthrough // 'f' float
521
- case ( 0x64 , _) , ( _, 0x64 ) , ( 0x64 , 0x64 ) : // 'd' double
525
+ switch ( _cfNumberType ( ) , otherNumber. _cfNumberType ( ) ) {
526
+ case ( kCFNumberFloatType , _) , ( _, kCFNumberFloatType ) : fallthrough
527
+ case ( kCFNumberDoubleType , _) , ( _, kCFNumberDoubleType ) :
522
528
let ( lhs, rhs) = ( doubleValue, otherNumber. doubleValue)
529
+ // Apply special handling for NaN as <, >, == always return false
530
+ // when comparing with NaN
531
+ if lhs. isNaN && rhs. isNaN { return . orderedSame }
532
+ if lhs. isNaN { return . orderedAscending }
533
+ if rhs. isNaN { return . orderedDescending }
534
+
523
535
if lhs < rhs { return . orderedAscending }
524
536
if lhs > rhs { return . orderedDescending }
525
537
return . orderedSame
526
- case ( 0x51 , _) , ( _, 0x51 ) , ( 0x51 , 0x51 ) : // 'q' unsigned long long
527
- let ( lhs, rhs) = ( uint64Value, otherNumber. uint64Value)
528
- if lhs < rhs { return . orderedAscending }
529
- if lhs > rhs { return . orderedDescending }
530
- return . orderedSame
531
- case ( _, _) :
532
- let ( lhs, rhs) = ( int64Value, otherNumber. int64Value)
533
- if lhs < rhs { return . orderedAscending }
534
- if lhs > rhs { return . orderedDescending }
538
+
539
+ default : // For signed and unsigned integers expand upto S128Int
540
+ let ( lhs, rhs) = ( int128Value, otherNumber. int128Value)
541
+ if lhs. high < rhs. high { return . orderedAscending }
542
+ if lhs. high > rhs. high { return . orderedDescending }
543
+ if lhs. low < rhs. low { return . orderedAscending }
544
+ if lhs. low > rhs. low { return . orderedDescending }
535
545
return . orderedSame
536
546
}
537
547
}
0 commit comments