@@ -492,6 +492,57 @@ extension Decimal : Strideable {
492492 }
493493}
494494
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+
495546// The methods in this extension exist to match the protocol requirements of
496547// FloatingPoint, even if we can't conform directly.
497548//
@@ -718,9 +769,20 @@ extension Decimal {
718769 }
719770
720771 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+
722784 return Decimal (
723- _exponent: _exponent , _length: 1 , _isNegative: 0 , _isCompact: 1 ,
785+ _exponent: max ( exponent , - 128 ) , _length: 1 , _isNegative: 0 , _isCompact: 1 ,
724786 _reserved: 0 , _mantissa: ( 0x0001 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 ) )
725787 }
726788
@@ -1216,14 +1278,14 @@ fileprivate func integerMultiplyByPowerOf10<T:VariableLengthNumber>(_ result: in
12161278 }
12171279 result = left
12181280
1219- let maxpow10 = pow10 . count - 1
1281+ let maxpow10 = _powersOfTen . count - 1
12201282 var error : NSDecimalNumber . CalculationError = . noError
12211283
12221284 while power > maxpow10 {
12231285 var big = T ( )
12241286
12251287 power -= maxpow10
1226- let p10 = pow10 [ maxpow10]
1288+ let p10 = _powersOfTen [ maxpow10]
12271289
12281290 if !isNegative {
12291291 error = integerMultiply ( & big, result, p10)
@@ -1245,7 +1307,7 @@ fileprivate func integerMultiplyByPowerOf10<T:VariableLengthNumber>(_ result: in
12451307 var big = T ( )
12461308
12471309 // Handle the rest of the power (<= maxpow10)
1248- let p10 = pow10 [ Int ( power) ]
1310+ let p10 = _powersOfTen [ Int ( power) ]
12491311
12501312 if !isNegative {
12511313 error = integerMultiply ( & big, result, p10)
@@ -1929,15 +1991,6 @@ fileprivate struct WideDecimal : VariableLengthNumber {
19291991extension Decimal {
19301992 fileprivate static let maxSize : UInt32 = UInt32 ( NSDecimalMaxSize)
19311993
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-
19411994 fileprivate var isCompact : Bool {
19421995 get {
19431996 return _isCompact != 0
@@ -2196,50 +2249,6 @@ extension Decimal {
21962249 }
21972250}
21982251
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-
22432252// Could be silently inexact for float and double.
22442253extension Scanner {
22452254
0 commit comments