@@ -492,6 +492,57 @@ extension Decimal : Strideable {
492
492
}
493
493
}
494
494
495
+ extension Decimal {
496
+ // (Used by `_powersOfTen` and `ulp`; note that the representation isn't compact.)
497
+ fileprivate init ( _length: UInt32 , _mantissa: ( UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 ) ) {
498
+ self . init ( _exponent: 0 , _length: _length, _isNegative: 0 , _isCompact: 0 ,
499
+ _reserved: 0 , _mantissa: _mantissa)
500
+ }
501
+ }
502
+
503
+ private let _powersOfTen = [
504
+ /*^00*/ 1 as Decimal ,
505
+ /*^01*/ Decimal ( _length: 1 , _mantissa: ( 0x000a , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
506
+ /*^02*/ Decimal ( _length: 1 , _mantissa: ( 0x0064 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
507
+ /*^03*/ Decimal ( _length: 1 , _mantissa: ( 0x03e8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
508
+ /*^04*/ Decimal ( _length: 1 , _mantissa: ( 0x2710 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
509
+ /*^05*/ Decimal ( _length: 2 , _mantissa: ( 0x86a0 , 0x0001 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
510
+ /*^06*/ Decimal ( _length: 2 , _mantissa: ( 0x4240 , 0x000f , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
511
+ /*^07*/ Decimal ( _length: 2 , _mantissa: ( 0x9680 , 0x0098 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
512
+ /*^08*/ Decimal ( _length: 2 , _mantissa: ( 0xe100 , 0x05f5 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
513
+ /*^09*/ Decimal ( _length: 2 , _mantissa: ( 0xca00 , 0x3b9a , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
514
+ /*^10*/ Decimal ( _length: 3 , _mantissa: ( 0xe400 , 0x540b , 0x0002 , 0 , 0 , 0 , 0 , 0 ) ) ,
515
+ /*^11*/ Decimal ( _length: 3 , _mantissa: ( 0xe800 , 0x4876 , 0x0017 , 0 , 0 , 0 , 0 , 0 ) ) ,
516
+ /*^12*/ Decimal ( _length: 3 , _mantissa: ( 0x1000 , 0xd4a5 , 0x00e8 , 0 , 0 , 0 , 0 , 0 ) ) ,
517
+ /*^13*/ Decimal ( _length: 3 , _mantissa: ( 0xa000 , 0x4e72 , 0x0918 , 0 , 0 , 0 , 0 , 0 ) ) ,
518
+ /*^14*/ Decimal ( _length: 3 , _mantissa: ( 0x4000 , 0x107a , 0x5af3 , 0 , 0 , 0 , 0 , 0 ) ) ,
519
+ /*^15*/ Decimal ( _length: 4 , _mantissa: ( 0x8000 , 0xa4c6 , 0x8d7e , 0x0003 , 0 , 0 , 0 , 0 ) ) ,
520
+ /*^16*/ Decimal ( _length: 4 , _mantissa: ( 0x0000 , 0x6fc1 , 0x86f2 , 0x0023 , 0 , 0 , 0 , 0 ) ) ,
521
+ /*^17*/ Decimal ( _length: 4 , _mantissa: ( 0x0000 , 0x5d8a , 0x4578 , 0x0163 , 0 , 0 , 0 , 0 ) ) ,
522
+ /*^18*/ Decimal ( _length: 4 , _mantissa: ( 0x0000 , 0xa764 , 0xb6b3 , 0x0de0 , 0 , 0 , 0 , 0 ) ) ,
523
+ /*^19*/ Decimal ( _length: 4 , _mantissa: ( 0x0000 , 0x89e8 , 0x2304 , 0x8ac7 , 0 , 0 , 0 , 0 ) ) ,
524
+ /*^20*/ Decimal ( _length: 5 , _mantissa: ( 0x0000 , 0x6310 , 0x5e2d , 0x6bc7 , 0x0005 , 0 , 0 , 0 ) ) ,
525
+ /*^21*/ Decimal ( _length: 5 , _mantissa: ( 0x0000 , 0xdea0 , 0xadc5 , 0x35c9 , 0x0036 , 0 , 0 , 0 ) ) ,
526
+ /*^22*/ Decimal ( _length: 5 , _mantissa: ( 0x0000 , 0xb240 , 0xc9ba , 0x19e0 , 0x021e , 0 , 0 , 0 ) ) ,
527
+ /*^23*/ Decimal ( _length: 5 , _mantissa: ( 0x0000 , 0xf680 , 0xe14a , 0x02c7 , 0x152d , 0 , 0 , 0 ) ) ,
528
+ /*^24*/ Decimal ( _length: 5 , _mantissa: ( 0x0000 , 0xa100 , 0xcced , 0x1bce , 0xd3c2 , 0 , 0 , 0 ) ) ,
529
+ /*^25*/ Decimal ( _length: 6 , _mantissa: ( 0x0000 , 0x4a00 , 0x0148 , 0x1614 , 0x4595 , 0x0008 , 0 , 0 ) ) ,
530
+ /*^26*/ Decimal ( _length: 6 , _mantissa: ( 0x0000 , 0xe400 , 0x0cd2 , 0xdcc8 , 0xb7d2 , 0x0052 , 0 , 0 ) ) ,
531
+ /*^27*/ Decimal ( _length: 6 , _mantissa: ( 0x0000 , 0xe800 , 0x803c , 0x9fd0 , 0x2e3c , 0x033b , 0 , 0 ) ) ,
532
+ /*^28*/ Decimal ( _length: 6 , _mantissa: ( 0x0000 , 0x1000 , 0x0261 , 0x3e25 , 0xce5e , 0x204f , 0 , 0 ) ) ,
533
+ /*^29*/ Decimal ( _length: 7 , _mantissa: ( 0x0000 , 0xa000 , 0x17ca , 0x6d72 , 0x0fae , 0x431e , 0x0001 , 0 ) ) ,
534
+ /*^30*/ Decimal ( _length: 7 , _mantissa: ( 0x0000 , 0x4000 , 0xedea , 0x4674 , 0x9cd0 , 0x9f2c , 0x000c , 0 ) ) ,
535
+ /*^31*/ Decimal ( _length: 7 , _mantissa: ( 0x0000 , 0x8000 , 0x4b26 , 0xc091 , 0x2022 , 0x37be , 0x007e , 0 ) ) ,
536
+ /*^32*/ Decimal ( _length: 7 , _mantissa: ( 0x0000 , 0x0000 , 0xef81 , 0x85ac , 0x415b , 0x2d6d , 0x04ee , 0 ) ) ,
537
+ /*^33*/ Decimal ( _length: 7 , _mantissa: ( 0x0000 , 0x0000 , 0x5b0a , 0x38c1 , 0x8d93 , 0xc644 , 0x314d , 0 ) ) ,
538
+ /*^34*/ Decimal ( _length: 8 , _mantissa: ( 0x0000 , 0x0000 , 0x8e64 , 0x378d , 0x87c0 , 0xbead , 0xed09 , 0x0001 ) ) ,
539
+ /*^35*/ Decimal ( _length: 8 , _mantissa: ( 0x0000 , 0x0000 , 0x8fe8 , 0x2b87 , 0x4d82 , 0x72c7 , 0x4261 , 0x0013 ) ) ,
540
+ /*^36*/ Decimal ( _length: 8 , _mantissa: ( 0x0000 , 0x0000 , 0x9f10 , 0xb34b , 0x0715 , 0x7bc9 , 0x97ce , 0x00c0 ) ) ,
541
+ /*^37*/ Decimal ( _length: 8 , _mantissa: ( 0x0000 , 0x0000 , 0x36a0 , 0x00f4 , 0x46d9 , 0xd5da , 0xee10 , 0x0785 ) ) ,
542
+ /*^38*/ Decimal ( _length: 8 , _mantissa: ( 0x0000 , 0x0000 , 0x2240 , 0x098a , 0xc47a , 0x5a86 , 0x4ca8 , 0x4b3b ) )
543
+ /*^39 is on 9 shorts.*/
544
+ ]
545
+
495
546
// The methods in this extension exist to match the protocol requirements of
496
547
// FloatingPoint, even if we can't conform directly.
497
548
//
@@ -718,9 +769,20 @@ extension Decimal {
718
769
}
719
770
720
771
public var ulp : Decimal {
721
- if !self . isFinite { return Decimal . nan }
772
+ guard isFinite else { return . nan }
773
+
774
+ let exponent : Int32
775
+ if isZero {
776
+ exponent = . min
777
+ } else {
778
+ let significand = Decimal ( _length: _length, _mantissa: _mantissa)
779
+ let maxPowerOfTen = _powersOfTen. count
780
+ let powerOfTen = _powersOfTen. firstIndex { $0 > significand } ?? maxPowerOfTen
781
+ exponent = _exponent &- Int32 ( maxPowerOfTen &- powerOfTen)
782
+ }
783
+
722
784
return Decimal (
723
- _exponent: _exponent , _length: 1 , _isNegative: 0 , _isCompact: 1 ,
785
+ _exponent: max ( exponent , - 128 ) , _length: 1 , _isNegative: 0 , _isCompact: 1 ,
724
786
_reserved: 0 , _mantissa: ( 0x0001 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 ) )
725
787
}
726
788
@@ -1216,14 +1278,14 @@ fileprivate func integerMultiplyByPowerOf10<T:VariableLengthNumber>(_ result: in
1216
1278
}
1217
1279
result = left
1218
1280
1219
- let maxpow10 = pow10 . count - 1
1281
+ let maxpow10 = _powersOfTen . count - 1
1220
1282
var error : NSDecimalNumber . CalculationError = . noError
1221
1283
1222
1284
while power > maxpow10 {
1223
1285
var big = T ( )
1224
1286
1225
1287
power -= maxpow10
1226
- let p10 = pow10 [ maxpow10]
1288
+ let p10 = _powersOfTen [ maxpow10]
1227
1289
1228
1290
if !isNegative {
1229
1291
error = integerMultiply ( & big, result, p10)
@@ -1245,7 +1307,7 @@ fileprivate func integerMultiplyByPowerOf10<T:VariableLengthNumber>(_ result: in
1245
1307
var big = T ( )
1246
1308
1247
1309
// Handle the rest of the power (<= maxpow10)
1248
- let p10 = pow10 [ Int ( power) ]
1310
+ let p10 = _powersOfTen [ Int ( power) ]
1249
1311
1250
1312
if !isNegative {
1251
1313
error = integerMultiply ( & big, result, p10)
@@ -1929,15 +1991,6 @@ fileprivate struct WideDecimal : VariableLengthNumber {
1929
1991
extension Decimal {
1930
1992
fileprivate static let maxSize : UInt32 = UInt32 ( NSDecimalMaxSize)
1931
1993
1932
- fileprivate init ( length: UInt32 , mantissa: ( UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 ) ) {
1933
- precondition ( length <= 15 )
1934
- self . _mantissa = mantissa
1935
- self . __exponent = 0
1936
- self . __lengthAndFlags = 0
1937
- self . __reserved = 0
1938
- self . _length = length
1939
- }
1940
-
1941
1994
fileprivate var isCompact : Bool {
1942
1995
get {
1943
1996
return _isCompact != 0
@@ -2196,50 +2249,6 @@ extension Decimal {
2196
2249
}
2197
2250
}
2198
2251
2199
- fileprivate let pow10 = [
2200
- /*^00*/ Decimal ( length: 1 , mantissa: ( 0x0001 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2201
- /*^01*/ Decimal ( length: 1 , mantissa: ( 0x000a , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2202
- /*^02*/ Decimal ( length: 1 , mantissa: ( 0x0064 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2203
- /*^03*/ Decimal ( length: 1 , mantissa: ( 0x03e8 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2204
- /*^04*/ Decimal ( length: 1 , mantissa: ( 0x2710 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2205
- /*^05*/ Decimal ( length: 2 , mantissa: ( 0x86a0 , 0x0001 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2206
- /*^06*/ Decimal ( length: 2 , mantissa: ( 0x4240 , 0x000f , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2207
- /*^07*/ Decimal ( length: 2 , mantissa: ( 0x9680 , 0x0098 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2208
- /*^08*/ Decimal ( length: 2 , mantissa: ( 0xe100 , 0x05f5 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2209
- /*^09*/ Decimal ( length: 2 , mantissa: ( 0xca00 , 0x3b9a , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
2210
- /*^10*/ Decimal ( length: 3 , mantissa: ( 0xe400 , 0x540b , 0x0002 , 0 , 0 , 0 , 0 , 0 ) ) ,
2211
- /*^11*/ Decimal ( length: 3 , mantissa: ( 0xe800 , 0x4876 , 0x0017 , 0 , 0 , 0 , 0 , 0 ) ) ,
2212
- /*^12*/ Decimal ( length: 3 , mantissa: ( 0x1000 , 0xd4a5 , 0x00e8 , 0 , 0 , 0 , 0 , 0 ) ) ,
2213
- /*^13*/ Decimal ( length: 3 , mantissa: ( 0xa000 , 0x4e72 , 0x0918 , 0 , 0 , 0 , 0 , 0 ) ) ,
2214
- /*^14*/ Decimal ( length: 3 , mantissa: ( 0x4000 , 0x107a , 0x5af3 , 0 , 0 , 0 , 0 , 0 ) ) ,
2215
- /*^15*/ Decimal ( length: 4 , mantissa: ( 0x8000 , 0xa4c6 , 0x8d7e , 0x0003 , 0 , 0 , 0 , 0 ) ) ,
2216
- /*^16*/ Decimal ( length: 4 , mantissa: ( 0x0000 , 0x6fc1 , 0x86f2 , 0x0023 , 0 , 0 , 0 , 0 ) ) ,
2217
- /*^17*/ Decimal ( length: 4 , mantissa: ( 0x0000 , 0x5d8a , 0x4578 , 0x0163 , 0 , 0 , 0 , 0 ) ) ,
2218
- /*^18*/ Decimal ( length: 4 , mantissa: ( 0x0000 , 0xa764 , 0xb6b3 , 0x0de0 , 0 , 0 , 0 , 0 ) ) ,
2219
- /*^19*/ Decimal ( length: 4 , mantissa: ( 0x0000 , 0x89e8 , 0x2304 , 0x8ac7 , 0 , 0 , 0 , 0 ) ) ,
2220
- /*^20*/ Decimal ( length: 5 , mantissa: ( 0x0000 , 0x6310 , 0x5e2d , 0x6bc7 , 0x0005 , 0 , 0 , 0 ) ) ,
2221
- /*^21*/ Decimal ( length: 5 , mantissa: ( 0x0000 , 0xdea0 , 0xadc5 , 0x35c9 , 0x0036 , 0 , 0 , 0 ) ) ,
2222
- /*^22*/ Decimal ( length: 5 , mantissa: ( 0x0000 , 0xb240 , 0xc9ba , 0x19e0 , 0x021e , 0 , 0 , 0 ) ) ,
2223
- /*^23*/ Decimal ( length: 5 , mantissa: ( 0x0000 , 0xf680 , 0xe14a , 0x02c7 , 0x152d , 0 , 0 , 0 ) ) ,
2224
- /*^24*/ Decimal ( length: 5 , mantissa: ( 0x0000 , 0xa100 , 0xcced , 0x1bce , 0xd3c2 , 0 , 0 , 0 ) ) ,
2225
- /*^25*/ Decimal ( length: 6 , mantissa: ( 0x0000 , 0x4a00 , 0x0148 , 0x1614 , 0x4595 , 0x0008 , 0 , 0 ) ) ,
2226
- /*^26*/ Decimal ( length: 6 , mantissa: ( 0x0000 , 0xe400 , 0x0cd2 , 0xdcc8 , 0xb7d2 , 0x0052 , 0 , 0 ) ) ,
2227
- /*^27*/ Decimal ( length: 6 , mantissa: ( 0x0000 , 0xe800 , 0x803c , 0x9fd0 , 0x2e3c , 0x033b , 0 , 0 ) ) ,
2228
- /*^28*/ Decimal ( length: 6 , mantissa: ( 0x0000 , 0x1000 , 0x0261 , 0x3e25 , 0xce5e , 0x204f , 0 , 0 ) ) ,
2229
- /*^29*/ Decimal ( length: 7 , mantissa: ( 0x0000 , 0xa000 , 0x17ca , 0x6d72 , 0x0fae , 0x431e , 0x0001 , 0 ) ) ,
2230
- /*^30*/ Decimal ( length: 7 , mantissa: ( 0x0000 , 0x4000 , 0xedea , 0x4674 , 0x9cd0 , 0x9f2c , 0x000c , 0 ) ) ,
2231
- /*^31*/ Decimal ( length: 7 , mantissa: ( 0x0000 , 0x8000 , 0x4b26 , 0xc091 , 0x2022 , 0x37be , 0x007e , 0 ) ) ,
2232
- /*^32*/ Decimal ( length: 7 , mantissa: ( 0x0000 , 0x0000 , 0xef81 , 0x85ac , 0x415b , 0x2d6d , 0x04ee , 0 ) ) ,
2233
- /*^33*/ Decimal ( length: 7 , mantissa: ( 0x0000 , 0x0000 , 0x5b0a , 0x38c1 , 0x8d93 , 0xc644 , 0x314d , 0 ) ) ,
2234
- /*^34*/ Decimal ( length: 8 , mantissa: ( 0x0000 , 0x0000 , 0x8e64 , 0x378d , 0x87c0 , 0xbead , 0xed09 , 0x0001 ) ) ,
2235
- /*^35*/ Decimal ( length: 8 , mantissa: ( 0x0000 , 0x0000 , 0x8fe8 , 0x2b87 , 0x4d82 , 0x72c7 , 0x4261 , 0x0013 ) ) ,
2236
- /*^36*/ Decimal ( length: 8 , mantissa: ( 0x0000 , 0x0000 , 0x9f10 , 0xb34b , 0x0715 , 0x7bc9 , 0x97ce , 0x00c0 ) ) ,
2237
- /*^37*/ Decimal ( length: 8 , mantissa: ( 0x0000 , 0x0000 , 0x36a0 , 0x00f4 , 0x46d9 , 0xd5da , 0xee10 , 0x0785 ) ) ,
2238
- /*^38*/ Decimal ( length: 8 , mantissa: ( 0x0000 , 0x0000 , 0x2240 , 0x098a , 0xc47a , 0x5a86 , 0x4ca8 , 0x4b3b ) )
2239
- /*^39 is on 9 shorts. */
2240
- ]
2241
-
2242
-
2243
2252
// Could be silently inexact for float and double.
2244
2253
extension Scanner {
2245
2254
0 commit comments