@@ -915,7 +915,7 @@ open class NSNumber : NSValue {
915
915
}
916
916
917
917
open var stringValue : String {
918
- return self . description
918
+ return description ( withLocale : nil )
919
919
}
920
920
921
921
/// Create an instance initialized to `value`.
@@ -958,86 +958,39 @@ open class NSNumber : NSValue {
958
958
}
959
959
}
960
960
961
- open func description( withLocale locale: Locale ? ) -> String {
962
- guard let locale = locale else { return self . description }
963
- switch _CFNumberGetType2 ( _cfObject) {
964
- case kCFNumberSInt8Type, kCFNumberCharType:
965
- return String ( format: " %d " , locale: locale, self . int8Value)
966
-
967
- case kCFNumberSInt16Type, kCFNumberShortType:
968
- return String ( format: " %hi " , locale: locale, self . int16Value)
969
-
970
- case kCFNumberSInt32Type:
971
- return String ( format: " %d " , locale: locale, self . int32Value)
961
+ private static let _numberFormatterForNilLocale : CFNumberFormatter = {
962
+ let formatter : CFNumberFormatter
963
+ formatter = CFNumberFormatterCreate ( nil , CFLocaleCopyCurrent ( ) , kCFNumberFormatterNoStyle)
964
+ CFNumberFormatterSetProperty ( formatter, kCFNumberFormatterMaxFractionDigits, 15 . _bridgeToObjectiveC ( ) )
965
+ return formatter
966
+ } ( )
972
967
973
- case kCFNumberIntType, kCFNumberLongType, kCFNumberNSIntegerType, kCFNumberCFIndexType:
974
- return String ( format: " %ld " , locale: locale, self . intValue)
975
-
976
- case kCFNumberSInt64Type, kCFNumberLongLongType:
977
- return String ( format: " %lld " , locale: locale, self . int64Value)
978
-
979
- case kCFNumberSInt128Type:
980
- let value = self . int128Value
981
- if value. high == 0 {
982
- return value. low. description // BUG: "%llu" doesnt work correctly and treats number as signed
983
- } else {
984
- // BUG: Note the locale is actually ignored here as this is converted using CFNumber.c:emit128()
985
- return String ( format: " %@ " , locale: locale, unsafeBitCast ( _cfObject, to: UnsafePointer< CFNumber> . self ) )
986
- }
987
-
988
- case kCFNumberFloatType, kCFNumberFloat32Type:
989
- return String ( format: " %0.7g " , locale: locale, self . floatValue)
990
-
991
- case kCFNumberFloat64Type, kCFNumberDoubleType:
992
- return String ( format: " %0.16g " , locale: locale, self . doubleValue)
968
+ open func description( withLocale locale: Locale ? ) -> String {
969
+ // CFNumberFormatterCreateStringWithNumber() does not like numbers of type
970
+ // SInt128Type, as it loses the type when looking it up and treats it as
971
+ // an SInt64Type, so special case them.
972
+ if _CFNumberGetType2 ( _cfObject) == kCFNumberSInt128Type {
973
+ return String ( format: " %@ " , unsafeBitCast ( _cfObject, to: UnsafePointer< CFNumber> . self ) )
974
+ }
993
975
994
- case kCFNumberCGFloatType:
995
- if Int . max == Int32 . max {
996
- return String ( format: " %0.7g " , locale: locale, self . floatValue)
997
- } else {
998
- return String ( format: " %0.16g " , locale: locale, self . doubleValue)
999
- }
1000
- default : fatalError ( " Unknown NSNumber Type " )
976
+ let aLocale = locale
977
+ let formatter : CFNumberFormatter
978
+ if ( aLocale == nil ) {
979
+ formatter = NSNumber . _numberFormatterForNilLocale
980
+ } else {
981
+ formatter = CFNumberFormatterCreate ( nil , aLocale? . _cfObject, kCFNumberFormatterDecimalStyle)
1001
982
}
983
+ return CFNumberFormatterCreateStringWithNumber ( nil , formatter, self . _cfObject) . _swiftObject
1002
984
}
1003
985
1004
986
override open var _cfTypeID : CFTypeID {
1005
987
return CFNumberGetTypeID ( )
1006
988
}
1007
989
1008
990
open override var description : String {
1009
- switch _CFNumberGetType2 ( _cfObject) {
1010
- case kCFNumberSInt8Type, kCFNumberCharType, kCFNumberSInt16Type, kCFNumberShortType,
1011
- kCFNumberSInt32Type, kCFNumberIntType, kCFNumberLongType, kCFNumberNSIntegerType, kCFNumberCFIndexType:
1012
- return self . intValue. description
1013
-
1014
- case kCFNumberSInt64Type, kCFNumberLongLongType:
1015
- return self . int64Value. description
1016
-
1017
- case kCFNumberSInt128Type:
1018
- let value = self . int128Value
1019
- if value. high == 0 {
1020
- return value. low. description
1021
- } else {
1022
- return String ( format: " %@ " , locale: nil , unsafeBitCast ( _cfObject, to: UnsafePointer< CFNumber> . self ) )
1023
- }
1024
-
1025
- case kCFNumberFloatType, kCFNumberFloat32Type:
1026
- return self . floatValue. description
1027
-
1028
- case kCFNumberFloat64Type, kCFNumberDoubleType:
1029
- return self . doubleValue. description
1030
-
1031
- case kCFNumberCGFloatType:
1032
- if Int . max == Int32 . max {
1033
- return self . floatValue. description
1034
- } else {
1035
- return self . doubleValue. description
1036
- }
1037
- default : fatalError ( " Unknown NSNumber Type " )
1038
- }
991
+ return description ( withLocale: nil )
1039
992
}
1040
-
993
+
1041
994
internal func _cfNumberType( ) -> CFNumberType {
1042
995
switch objCType. pointee {
1043
996
case 0x42 : return kCFNumberCharType
0 commit comments