@@ -489,6 +489,57 @@ extension Decimal : Strideable {
489
489
}
490
490
}
491
491
492
+ extension Decimal {
493
+ // (Used by `_powersOfTen` and `ulp`; note that the representation isn't compact.)
494
+ fileprivate init ( _length: UInt32 , _mantissa: ( UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 ) ) {
495
+ self . init ( _exponent: 0 , _length: _length, _isNegative: 0 , _isCompact: 0 ,
496
+ _reserved: 0 , _mantissa: _mantissa)
497
+ }
498
+ }
499
+
500
+ private let _powersOfTen = [
501
+ /*^00*/ 1 as Decimal ,
502
+ /*^01*/ Decimal ( _length: 1 , _mantissa: ( 0x000a , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
503
+ /*^02*/ Decimal ( _length: 1 , _mantissa: ( 0x0064 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
504
+ /*^03*/ Decimal ( _length: 1 , _mantissa: ( 0x03e8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
505
+ /*^04*/ Decimal ( _length: 1 , _mantissa: ( 0x2710 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
506
+ /*^05*/ Decimal ( _length: 2 , _mantissa: ( 0x86a0 , 0x0001 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
507
+ /*^06*/ Decimal ( _length: 2 , _mantissa: ( 0x4240 , 0x000f , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
508
+ /*^07*/ Decimal ( _length: 2 , _mantissa: ( 0x9680 , 0x0098 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
509
+ /*^08*/ Decimal ( _length: 2 , _mantissa: ( 0xe100 , 0x05f5 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
510
+ /*^09*/ Decimal ( _length: 2 , _mantissa: ( 0xca00 , 0x3b9a , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
511
+ /*^10*/ Decimal ( _length: 3 , _mantissa: ( 0xe400 , 0x540b , 0x0002 , 0 , 0 , 0 , 0 , 0 ) ) ,
512
+ /*^11*/ Decimal ( _length: 3 , _mantissa: ( 0xe800 , 0x4876 , 0x0017 , 0 , 0 , 0 , 0 , 0 ) ) ,
513
+ /*^12*/ Decimal ( _length: 3 , _mantissa: ( 0x1000 , 0xd4a5 , 0x00e8 , 0 , 0 , 0 , 0 , 0 ) ) ,
514
+ /*^13*/ Decimal ( _length: 3 , _mantissa: ( 0xa000 , 0x4e72 , 0x0918 , 0 , 0 , 0 , 0 , 0 ) ) ,
515
+ /*^14*/ Decimal ( _length: 3 , _mantissa: ( 0x4000 , 0x107a , 0x5af3 , 0 , 0 , 0 , 0 , 0 ) ) ,
516
+ /*^15*/ Decimal ( _length: 4 , _mantissa: ( 0x8000 , 0xa4c6 , 0x8d7e , 0x0003 , 0 , 0 , 0 , 0 ) ) ,
517
+ /*^16*/ Decimal ( _length: 4 , _mantissa: ( 0x0000 , 0x6fc1 , 0x86f2 , 0x0023 , 0 , 0 , 0 , 0 ) ) ,
518
+ /*^17*/ Decimal ( _length: 4 , _mantissa: ( 0x0000 , 0x5d8a , 0x4578 , 0x0163 , 0 , 0 , 0 , 0 ) ) ,
519
+ /*^18*/ Decimal ( _length: 4 , _mantissa: ( 0x0000 , 0xa764 , 0xb6b3 , 0x0de0 , 0 , 0 , 0 , 0 ) ) ,
520
+ /*^19*/ Decimal ( _length: 4 , _mantissa: ( 0x0000 , 0x89e8 , 0x2304 , 0x8ac7 , 0 , 0 , 0 , 0 ) ) ,
521
+ /*^20*/ Decimal ( _length: 5 , _mantissa: ( 0x0000 , 0x6310 , 0x5e2d , 0x6bc7 , 0x0005 , 0 , 0 , 0 ) ) ,
522
+ /*^21*/ Decimal ( _length: 5 , _mantissa: ( 0x0000 , 0xdea0 , 0xadc5 , 0x35c9 , 0x0036 , 0 , 0 , 0 ) ) ,
523
+ /*^22*/ Decimal ( _length: 5 , _mantissa: ( 0x0000 , 0xb240 , 0xc9ba , 0x19e0 , 0x021e , 0 , 0 , 0 ) ) ,
524
+ /*^23*/ Decimal ( _length: 5 , _mantissa: ( 0x0000 , 0xf680 , 0xe14a , 0x02c7 , 0x152d , 0 , 0 , 0 ) ) ,
525
+ /*^24*/ Decimal ( _length: 5 , _mantissa: ( 0x0000 , 0xa100 , 0xcced , 0x1bce , 0xd3c2 , 0 , 0 , 0 ) ) ,
526
+ /*^25*/ Decimal ( _length: 6 , _mantissa: ( 0x0000 , 0x4a00 , 0x0148 , 0x1614 , 0x4595 , 0x0008 , 0 , 0 ) ) ,
527
+ /*^26*/ Decimal ( _length: 6 , _mantissa: ( 0x0000 , 0xe400 , 0x0cd2 , 0xdcc8 , 0xb7d2 , 0x0052 , 0 , 0 ) ) ,
528
+ /*^27*/ Decimal ( _length: 6 , _mantissa: ( 0x0000 , 0xe800 , 0x803c , 0x9fd0 , 0x2e3c , 0x033b , 0 , 0 ) ) ,
529
+ /*^28*/ Decimal ( _length: 6 , _mantissa: ( 0x0000 , 0x1000 , 0x0261 , 0x3e25 , 0xce5e , 0x204f , 0 , 0 ) ) ,
530
+ /*^29*/ Decimal ( _length: 7 , _mantissa: ( 0x0000 , 0xa000 , 0x17ca , 0x6d72 , 0x0fae , 0x431e , 0x0001 , 0 ) ) ,
531
+ /*^30*/ Decimal ( _length: 7 , _mantissa: ( 0x0000 , 0x4000 , 0xedea , 0x4674 , 0x9cd0 , 0x9f2c , 0x000c , 0 ) ) ,
532
+ /*^31*/ Decimal ( _length: 7 , _mantissa: ( 0x0000 , 0x8000 , 0x4b26 , 0xc091 , 0x2022 , 0x37be , 0x007e , 0 ) ) ,
533
+ /*^32*/ Decimal ( _length: 7 , _mantissa: ( 0x0000 , 0x0000 , 0xef81 , 0x85ac , 0x415b , 0x2d6d , 0x04ee , 0 ) ) ,
534
+ /*^33*/ Decimal ( _length: 7 , _mantissa: ( 0x0000 , 0x0000 , 0x5b0a , 0x38c1 , 0x8d93 , 0xc644 , 0x314d , 0 ) ) ,
535
+ /*^34*/ Decimal ( _length: 8 , _mantissa: ( 0x0000 , 0x0000 , 0x8e64 , 0x378d , 0x87c0 , 0xbead , 0xed09 , 0x0001 ) ) ,
536
+ /*^35*/ Decimal ( _length: 8 , _mantissa: ( 0x0000 , 0x0000 , 0x8fe8 , 0x2b87 , 0x4d82 , 0x72c7 , 0x4261 , 0x0013 ) ) ,
537
+ /*^36*/ Decimal ( _length: 8 , _mantissa: ( 0x0000 , 0x0000 , 0x9f10 , 0xb34b , 0x0715 , 0x7bc9 , 0x97ce , 0x00c0 ) ) ,
538
+ /*^37*/ Decimal ( _length: 8 , _mantissa: ( 0x0000 , 0x0000 , 0x36a0 , 0x00f4 , 0x46d9 , 0xd5da , 0xee10 , 0x0785 ) ) ,
539
+ /*^38*/ Decimal ( _length: 8 , _mantissa: ( 0x0000 , 0x0000 , 0x2240 , 0x098a , 0xc47a , 0x5a86 , 0x4ca8 , 0x4b3b ) )
540
+ /*^39 is on 9 shorts.*/
541
+ ]
542
+
492
543
// The methods in this extension exist to match the protocol requirements of
493
544
// FloatingPoint, even if we can't conform directly.
494
545
//
@@ -729,9 +780,20 @@ extension Decimal {
729
780
}
730
781
731
782
public var ulp : Decimal {
732
- if !self . isFinite { return Decimal . nan }
783
+ guard isFinite else { return . nan }
784
+
785
+ let exponent : Int32
786
+ if isZero {
787
+ exponent = . min
788
+ } else {
789
+ let significand = Decimal ( _length: _length, _mantissa: _mantissa)
790
+ let maxPowerOfTen = _powersOfTen. count
791
+ let powerOfTen = _powersOfTen. firstIndex { $0 > significand } ?? maxPowerOfTen
792
+ exponent = _exponent &- Int32 ( maxPowerOfTen &- powerOfTen)
793
+ }
794
+
733
795
return Decimal (
734
- _exponent: _exponent , _length: 1 , _isNegative: 0 , _isCompact: 1 ,
796
+ _exponent: max ( exponent , - 128 ) , _length: 1 , _isNegative: 0 , _isCompact: 1 ,
735
797
_reserved: 0 , _mantissa: ( 0x0001 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 ) )
736
798
}
737
799
@@ -1227,14 +1289,14 @@ fileprivate func integerMultiplyByPowerOf10<T:VariableLengthNumber>(_ result: in
1227
1289
}
1228
1290
result = left
1229
1291
1230
- let maxpow10 = pow10 . count - 1
1292
+ let maxpow10 = _powersOfTen . count - 1
1231
1293
var error : NSDecimalNumber . CalculationError = . noError
1232
1294
1233
1295
while power > maxpow10 {
1234
1296
var big = T ( )
1235
1297
1236
1298
power -= maxpow10
1237
- let p10 = pow10 [ maxpow10]
1299
+ let p10 = _powersOfTen [ maxpow10]
1238
1300
1239
1301
if !isNegative {
1240
1302
error = integerMultiply ( & big, result, p10)
@@ -1256,7 +1318,7 @@ fileprivate func integerMultiplyByPowerOf10<T:VariableLengthNumber>(_ result: in
1256
1318
var big = T ( )
1257
1319
1258
1320
// Handle the rest of the power (<= maxpow10)
1259
- let p10 = pow10 [ Int ( power) ]
1321
+ let p10 = _powersOfTen [ Int ( power) ]
1260
1322
1261
1323
if !isNegative {
1262
1324
error = integerMultiply ( & big, result, p10)
@@ -1940,15 +2002,6 @@ fileprivate struct WideDecimal : VariableLengthNumber {
1940
2002
extension Decimal {
1941
2003
fileprivate static let maxSize : UInt32 = UInt32 ( NSDecimalMaxSize)
1942
2004
1943
- fileprivate init ( length: UInt32 , mantissa: ( UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 ) ) {
1944
- precondition ( length <= 15 )
1945
- self . _mantissa = mantissa
1946
- self . __exponent = 0
1947
- self . __lengthAndFlags = 0
1948
- self . __reserved = 0
1949
- self . _length = length
1950
- }
1951
-
1952
2005
fileprivate var isCompact : Bool {
1953
2006
get {
1954
2007
return _isCompact != 0
@@ -2207,50 +2260,6 @@ extension Decimal {
2207
2260
}
2208
2261
}
2209
2262
2210
- fileprivate let pow10 = [
2211
- /*^00*/ Decimal ( length: 1 , mantissa: ( 0x0001 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2212
- /*^01*/ Decimal ( length: 1 , mantissa: ( 0x000a , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2213
- /*^02*/ Decimal ( length: 1 , mantissa: ( 0x0064 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2214
- /*^03*/ Decimal ( length: 1 , mantissa: ( 0x03e8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2215
- /*^04*/ Decimal ( length: 1 , mantissa: ( 0x2710 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2216
- /*^05*/ Decimal ( length: 2 , mantissa: ( 0x86a0 , 0x0001 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2217
- /*^06*/ Decimal ( length: 2 , mantissa: ( 0x4240 , 0x000f , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2218
- /*^07*/ Decimal ( length: 2 , mantissa: ( 0x9680 , 0x0098 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2219
- /*^08*/ Decimal ( length: 2 , mantissa: ( 0xe100 , 0x05f5 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2220
- /*^09*/ Decimal ( length: 2 , mantissa: ( 0xca00 , 0x3b9a , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2221
- /*^10*/ Decimal ( length: 3 , mantissa: ( 0xe400 , 0x540b , 0x0002 , 0 , 0 , 0 , 0 , 0 ) ) ,
2222
- /*^11*/ Decimal ( length: 3 , mantissa: ( 0xe800 , 0x4876 , 0x0017 , 0 , 0 , 0 , 0 , 0 ) ) ,
2223
- /*^12*/ Decimal ( length: 3 , mantissa: ( 0x1000 , 0xd4a5 , 0x00e8 , 0 , 0 , 0 , 0 , 0 ) ) ,
2224
- /*^13*/ Decimal ( length: 3 , mantissa: ( 0xa000 , 0x4e72 , 0x0918 , 0 , 0 , 0 , 0 , 0 ) ) ,
2225
- /*^14*/ Decimal ( length: 3 , mantissa: ( 0x4000 , 0x107a , 0x5af3 , 0 , 0 , 0 , 0 , 0 ) ) ,
2226
- /*^15*/ Decimal ( length: 4 , mantissa: ( 0x8000 , 0xa4c6 , 0x8d7e , 0x0003 , 0 , 0 , 0 , 0 ) ) ,
2227
- /*^16*/ Decimal ( length: 4 , mantissa: ( 0x0000 , 0x6fc1 , 0x86f2 , 0x0023 , 0 , 0 , 0 , 0 ) ) ,
2228
- /*^17*/ Decimal ( length: 4 , mantissa: ( 0x0000 , 0x5d8a , 0x4578 , 0x0163 , 0 , 0 , 0 , 0 ) ) ,
2229
- /*^18*/ Decimal ( length: 4 , mantissa: ( 0x0000 , 0xa764 , 0xb6b3 , 0x0de0 , 0 , 0 , 0 , 0 ) ) ,
2230
- /*^19*/ Decimal ( length: 4 , mantissa: ( 0x0000 , 0x89e8 , 0x2304 , 0x8ac7 , 0 , 0 , 0 , 0 ) ) ,
2231
- /*^20*/ Decimal ( length: 5 , mantissa: ( 0x0000 , 0x6310 , 0x5e2d , 0x6bc7 , 0x0005 , 0 , 0 , 0 ) ) ,
2232
- /*^21*/ Decimal ( length: 5 , mantissa: ( 0x0000 , 0xdea0 , 0xadc5 , 0x35c9 , 0x0036 , 0 , 0 , 0 ) ) ,
2233
- /*^22*/ Decimal ( length: 5 , mantissa: ( 0x0000 , 0xb240 , 0xc9ba , 0x19e0 , 0x021e , 0 , 0 , 0 ) ) ,
2234
- /*^23*/ Decimal ( length: 5 , mantissa: ( 0x0000 , 0xf680 , 0xe14a , 0x02c7 , 0x152d , 0 , 0 , 0 ) ) ,
2235
- /*^24*/ Decimal ( length: 5 , mantissa: ( 0x0000 , 0xa100 , 0xcced , 0x1bce , 0xd3c2 , 0 , 0 , 0 ) ) ,
2236
- /*^25*/ Decimal ( length: 6 , mantissa: ( 0x0000 , 0x4a00 , 0x0148 , 0x1614 , 0x4595 , 0x0008 , 0 , 0 ) ) ,
2237
- /*^26*/ Decimal ( length: 6 , mantissa: ( 0x0000 , 0xe400 , 0x0cd2 , 0xdcc8 , 0xb7d2 , 0x0052 , 0 , 0 ) ) ,
2238
- /*^27*/ Decimal ( length: 6 , mantissa: ( 0x0000 , 0xe800 , 0x803c , 0x9fd0 , 0x2e3c , 0x033b , 0 , 0 ) ) ,
2239
- /*^28*/ Decimal ( length: 6 , mantissa: ( 0x0000 , 0x1000 , 0x0261 , 0x3e25 , 0xce5e , 0x204f , 0 , 0 ) ) ,
2240
- /*^29*/ Decimal ( length: 7 , mantissa: ( 0x0000 , 0xa000 , 0x17ca , 0x6d72 , 0x0fae , 0x431e , 0x0001 , 0 ) ) ,
2241
- /*^30*/ Decimal ( length: 7 , mantissa: ( 0x0000 , 0x4000 , 0xedea , 0x4674 , 0x9cd0 , 0x9f2c , 0x000c , 0 ) ) ,
2242
- /*^31*/ Decimal ( length: 7 , mantissa: ( 0x0000 , 0x8000 , 0x4b26 , 0xc091 , 0x2022 , 0x37be , 0x007e , 0 ) ) ,
2243
- /*^32*/ Decimal ( length: 7 , mantissa: ( 0x0000 , 0x0000 , 0xef81 , 0x85ac , 0x415b , 0x2d6d , 0x04ee , 0 ) ) ,
2244
- /*^33*/ Decimal ( length: 7 , mantissa: ( 0x0000 , 0x0000 , 0x5b0a , 0x38c1 , 0x8d93 , 0xc644 , 0x314d , 0 ) ) ,
2245
- /*^34*/ Decimal ( length: 8 , mantissa: ( 0x0000 , 0x0000 , 0x8e64 , 0x378d , 0x87c0 , 0xbead , 0xed09 , 0x0001 ) ) ,
2246
- /*^35*/ Decimal ( length: 8 , mantissa: ( 0x0000 , 0x0000 , 0x8fe8 , 0x2b87 , 0x4d82 , 0x72c7 , 0x4261 , 0x0013 ) ) ,
2247
- /*^36*/ Decimal ( length: 8 , mantissa: ( 0x0000 , 0x0000 , 0x9f10 , 0xb34b , 0x0715 , 0x7bc9 , 0x97ce , 0x00c0 ) ) ,
2248
- /*^37*/ Decimal ( length: 8 , mantissa: ( 0x0000 , 0x0000 , 0x36a0 , 0x00f4 , 0x46d9 , 0xd5da , 0xee10 , 0x0785 ) ) ,
2249
- /*^38*/ Decimal ( length: 8 , mantissa: ( 0x0000 , 0x0000 , 0x2240 , 0x098a , 0xc47a , 0x5a86 , 0x4ca8 , 0x4b3b ) )
2250
- /*^39 is on 9 shorts. */
2251
- ]
2252
-
2253
-
2254
2263
// Could be silently inexact for float and double.
2255
2264
extension Scanner {
2256
2265
0 commit comments