@@ -324,6 +324,57 @@ extension Decimal : Strideable {
324
324
}
325
325
}
326
326
327
+ private extension Decimal {
328
+ // Creates a value with zero exponent.
329
+ // (Used by `_powersOfTenDividingUInt128Max`.)
330
+ init ( _length: UInt32 , _isCompact: UInt32 , _mantissa: ( UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 , UInt16 ) ) {
331
+ self . init ( _exponent: 0 , _length: _length, _isNegative: 0 , _isCompact: _isCompact,
332
+ _reserved: 0 , _mantissa: _mantissa)
333
+ }
334
+ }
335
+
336
+ private let _powersOfTenDividingUInt128Max = [
337
+ /* 10**00 dividing UInt128.max is deliberately omitted. */
338
+ /* 10**01 */ Decimal ( _length: 8 , _isCompact: 1 , _mantissa: ( 0x9999 , 0x9999 , 0x9999 , 0x9999 , 0x9999 , 0x9999 , 0x9999 , 0x1999 ) ) ,
339
+ /* 10**02 */ Decimal ( _length: 8 , _isCompact: 1 , _mantissa: ( 0xf5c2 , 0x5c28 , 0xc28f , 0x28f5 , 0x8f5c , 0xf5c2 , 0x5c28 , 0x028f ) ) ,
340
+ /* 10**03 */ Decimal ( _length: 8 , _isCompact: 1 , _mantissa: ( 0x1893 , 0x5604 , 0x2d0e , 0x9db2 , 0xa7ef , 0x4bc6 , 0x8937 , 0x0041 ) ) ,
341
+ /* 10**04 */ Decimal ( _length: 8 , _isCompact: 1 , _mantissa: ( 0x0275 , 0x089a , 0x9e1b , 0x295e , 0x10cb , 0xbac7 , 0x8db8 , 0x0006 ) ) ,
342
+ /* 10**05 */ Decimal ( _length: 7 , _isCompact: 1 , _mantissa: ( 0x3372 , 0x80dc , 0x0fcf , 0x8423 , 0x1b47 , 0xac47 , 0xa7c5 , 0 ) ) ,
343
+ /* 10**06 */ Decimal ( _length: 7 , _isCompact: 1 , _mantissa: ( 0x3858 , 0xf349 , 0xb4c7 , 0x8d36 , 0xb5ed , 0xf7a0 , 0x10c6 , 0 ) ) ,
344
+ /* 10**07 */ Decimal ( _length: 7 , _isCompact: 1 , _mantissa: ( 0xec08 , 0x6520 , 0x787a , 0xf485 , 0xabca , 0x7f29 , 0x01ad , 0 ) ) ,
345
+ /* 10**08 */ Decimal ( _length: 7 , _isCompact: 1 , _mantissa: ( 0x4acd , 0x7083 , 0xbf3f , 0x1873 , 0xc461 , 0xf31d , 0x002a , 0 ) ) ,
346
+ /* 10**09 */ Decimal ( _length: 7 , _isCompact: 1 , _mantissa: ( 0x5447 , 0x8b40 , 0x2cb9 , 0xb5a5 , 0xfa09 , 0x4b82 , 0x0004 , 0 ) ) ,
347
+ /* 10**10 */ Decimal ( _length: 6 , _isCompact: 1 , _mantissa: ( 0xa207 , 0x5ab9 , 0xeadf , 0x5ef6 , 0x7f67 , 0x6df3 , 0 , 0 ) ) ,
348
+ /* 10**11 */ Decimal ( _length: 6 , _isCompact: 1 , _mantissa: ( 0xf69a , 0xef78 , 0x4aaf , 0xbcb2 , 0xbff0 , 0x0afe , 0 , 0 ) ) ,
349
+ /* 10**12 */ Decimal ( _length: 6 , _isCompact: 1 , _mantissa: ( 0x7f0f , 0x97f2 , 0xa111 , 0x12de , 0x7998 , 0x0119 , 0 , 0 ) ) ,
350
+ /* 10**13 */ Decimal ( _length: 6 , _isCompact: 0 , _mantissa: ( 0x0cb4 , 0xc265 , 0x7681 , 0x6849 , 0x25c2 , 0x001c , 0 , 0 ) ) ,
351
+ /* 10**14 */ Decimal ( _length: 6 , _isCompact: 1 , _mantissa: ( 0x4e12 , 0x603d , 0x2573 , 0x70d4 , 0xd093 , 0x0002 , 0 , 0 ) ) ,
352
+ /* 10**15 */ Decimal ( _length: 5 , _isCompact: 1 , _mantissa: ( 0x87ce , 0x566c , 0x9d58 , 0xbe7b , 0x480e , 0 , 0 , 0 ) ) ,
353
+ /* 10**16 */ Decimal ( _length: 5 , _isCompact: 1 , _mantissa: ( 0xda61 , 0x6f0a , 0xf622 , 0xaca5 , 0x0734 , 0 , 0 , 0 ) ) ,
354
+ /* 10**17 */ Decimal ( _length: 5 , _isCompact: 1 , _mantissa: ( 0x4909 , 0xa4b4 , 0x3236 , 0x77aa , 0x00b8 , 0 , 0 , 0 ) ) ,
355
+ /* 10**18 */ Decimal ( _length: 5 , _isCompact: 1 , _mantissa: ( 0xa0e7 , 0x43ab , 0xd1d2 , 0x725d , 0x0012 , 0 , 0 , 0 ) ) ,
356
+ /* 10**19 */ Decimal ( _length: 5 , _isCompact: 1 , _mantissa: ( 0xc34a , 0x6d2a , 0x94fb , 0xd83c , 0x0001 , 0 , 0 , 0 ) ) ,
357
+ /* 10**20 */ Decimal ( _length: 4 , _isCompact: 1 , _mantissa: ( 0x46ba , 0x2484 , 0x4219 , 0x2f39 , 0 , 0 , 0 , 0 ) ) ,
358
+ /* 10**21 */ Decimal ( _length: 4 , _isCompact: 1 , _mantissa: ( 0xd3df , 0x83a6 , 0xed02 , 0x04b8 , 0 , 0 , 0 , 0 ) ) ,
359
+ /* 10**22 */ Decimal ( _length: 4 , _isCompact: 1 , _mantissa: ( 0x7b96 , 0x405d , 0xe480 , 0x0078 , 0 , 0 , 0 , 0 ) ) ,
360
+ /* 10**23 */ Decimal ( _length: 4 , _isCompact: 1 , _mantissa: ( 0x5928 , 0xa009 , 0x16d9 , 0x000c , 0 , 0 , 0 , 0 ) ) ,
361
+ /* 10**24 */ Decimal ( _length: 4 , _isCompact: 1 , _mantissa: ( 0x88ea , 0x299a , 0x357c , 0x0001 , 0 , 0 , 0 , 0 ) ) ,
362
+ /* 10**25 */ Decimal ( _length: 3 , _isCompact: 1 , _mantissa: ( 0xda7d , 0xd0f5 , 0x1ef2 , 0 , 0 , 0 , 0 , 0 ) ) ,
363
+ /* 10**26 */ Decimal ( _length: 3 , _isCompact: 1 , _mantissa: ( 0x95d9 , 0x4818 , 0x0318 , 0 , 0 , 0 , 0 , 0 ) ) ,
364
+ /* 10**27 */ Decimal ( _length: 3 , _isCompact: 0 , _mantissa: ( 0xdbc8 , 0x3a68 , 0x004f , 0 , 0 , 0 , 0 , 0 ) ) ,
365
+ /* 10**28 */ Decimal ( _length: 3 , _isCompact: 1 , _mantissa: ( 0xaf94 , 0xec3d , 0x0007 , 0 , 0 , 0 , 0 , 0 ) ) ,
366
+ /* 10**29 */ Decimal ( _length: 2 , _isCompact: 1 , _mantissa: ( 0xf7f5 , 0xcad2 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
367
+ /* 10**30 */ Decimal ( _length: 2 , _isCompact: 1 , _mantissa: ( 0x4bfe , 0x1448 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
368
+ /* 10**31 */ Decimal ( _length: 2 , _isCompact: 1 , _mantissa: ( 0x3acc , 0x0207 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
369
+ /* 10**32 */ Decimal ( _length: 2 , _isCompact: 1 , _mantissa: ( 0xec47 , 0x0033 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
370
+ /* 10**33 */ Decimal ( _length: 2 , _isCompact: 1 , _mantissa: ( 0x313a , 0x0005 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
371
+ /* 10**34 */ Decimal ( _length: 1 , _isCompact: 1 , _mantissa: ( 0x84ec , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
372
+ /* 10**35 */ Decimal ( _length: 1 , _isCompact: 1 , _mantissa: ( 0x0d4a , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
373
+ /* 10**36 */ Decimal ( _length: 1 , _isCompact: 0 , _mantissa: ( 0x0154 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
374
+ /* 10**37 */ Decimal ( _length: 1 , _isCompact: 1 , _mantissa: ( 0x0022 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) ) ,
375
+ /* 10**38 */ Decimal ( _length: 1 , _isCompact: 1 , _mantissa: ( 0x0003 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) )
376
+ ]
377
+
327
378
// The methods in this extension exist to match the protocol requirements of
328
379
// FloatingPoint, even if we can't conform directly.
329
380
//
@@ -551,22 +602,47 @@ extension Decimal {
551
602
}
552
603
553
604
public var ulp : Decimal {
554
- if !self . isFinite { return Decimal . nan }
605
+ guard isFinite else { return . nan }
606
+
607
+ let exponent : Int32
608
+ if isZero {
609
+ exponent = . min
610
+ } else {
611
+ let significand_ = significand
612
+ let shift =
613
+ _powersOfTenDividingUInt128Max. firstIndex { significand_ > $0 }
614
+ ?? _powersOfTenDividingUInt128Max. count
615
+ exponent = _exponent &- Int32 ( shift)
616
+ }
617
+
555
618
return Decimal (
556
- _exponent: _exponent , _length: 1 , _isNegative: 0 , _isCompact: 1 ,
619
+ _exponent: max ( exponent , - 128 ) , _length: 1 , _isNegative: 0 , _isCompact: 1 ,
557
620
_reserved: 0 , _mantissa: ( 0x0001 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 ) )
558
621
}
559
622
560
623
public var nextUp : Decimal {
561
- return self + Decimal(
562
- _exponent: _exponent, _length: 1 , _isNegative: 0 , _isCompact: 1 ,
563
- _reserved: 0 , _mantissa: ( 0x0001 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 ) )
624
+ if _isNegative == 1 {
625
+ if _exponent > - 128
626
+ && ( _mantissa. 0 , _mantissa. 1 , _mantissa. 2 , _mantissa. 3 ) == ( 0x999a , 0x9999 , 0x9999 , 0x9999 )
627
+ && ( _mantissa. 4 , _mantissa. 5 , _mantissa. 6 , _mantissa. 7 ) == ( 0x9999 , 0x9999 , 0x9999 , 0x1999 ) {
628
+ return Decimal (
629
+ _exponent: _exponent &- 1 , _length: 8 , _isNegative: 1 , _isCompact: 1 ,
630
+ _reserved: 0 , _mantissa: ( 0xffff , 0xffff , 0xffff , 0xffff , 0xffff , 0xffff , 0xffff , 0xffff ) )
631
+ }
632
+ } else {
633
+ if _exponent < 127
634
+ && ( _mantissa. 0 , _mantissa. 1 , _mantissa. 2 , _mantissa. 3 ) == ( 0xffff , 0xffff , 0xffff , 0xffff )
635
+ && ( _mantissa. 4 , _mantissa. 5 , _mantissa. 6 , _mantissa. 7 ) == ( 0xffff , 0xffff , 0xffff , 0xffff ) {
636
+ return Decimal (
637
+ _exponent: _exponent &+ 1 , _length: 8 , _isNegative: 0 , _isCompact: 1 ,
638
+ _reserved: 0 , _mantissa: ( 0x999a , 0x9999 , 0x9999 , 0x9999 , 0x9999 , 0x9999 , 0x9999 , 0x1999 ) )
639
+ }
640
+ }
641
+ return self + ulp
564
642
}
565
643
566
644
public var nextDown : Decimal {
567
- return self - Decimal(
568
- _exponent: _exponent, _length: 1 , _isNegative: 0 , _isCompact: 1 ,
569
- _reserved: 0 , _mantissa: ( 0x0001 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 ) )
645
+ return - ( - self ) . nextUp
570
646
}
571
647
572
648
/// The IEEE 754 "class" of this type.
0 commit comments