@@ -22,7 +22,7 @@ extension Decimal : CustomStringConvertible {
22
22
if let decimalSeparator = locale? . decimalSeparator {
23
23
decimalString = decimalString. replacing ( decimalSeparator, with: " . " )
24
24
}
25
- guard let value = Decimal . decimal ( from: decimalString. utf8, matchEntireString: false ) else {
25
+ guard let value = Decimal . decimal ( from: decimalString. utf8, matchEntireString: false ) . result else {
26
26
return nil
27
27
}
28
28
self = value
@@ -35,11 +35,8 @@ extension Decimal : CustomStringConvertible {
35
35
36
36
// The methods in this extension exist to match the protocol requirements of
37
37
// FloatingPoint, even if we can't conform directly.
38
- //
39
- // If it becomes clear that conformance is truly impossible, we can deprecate
40
- // some of the methods (e.g. `isEqual(to:)` in favor of operators).
41
38
@available ( macOS 10 . 10 , iOS 8 . 0 , watchOS 2 . 0 , tvOS 9 . 0 , * )
42
- extension Decimal {
39
+ extension Decimal /* : FloatingPoint */ {
43
40
public static let leastFiniteMagnitude = Decimal (
44
41
_exponent: 127 ,
45
42
_length: 8 ,
@@ -310,6 +307,56 @@ extension Decimal {
310
307
311
308
@available ( * , unavailable, message: " Decimal does not yet fully adopt FloatingPoint. " )
312
309
public mutating func formTruncatingRemainder( dividingBy other: Decimal ) { fatalError ( " Decimal does not yet fully adopt FloatingPoint " ) }
310
+
311
+ public var nextUp : Decimal {
312
+ return self + Decimal(
313
+ _exponent: _exponent,
314
+ _length: 1 ,
315
+ _isNegative: 0 ,
316
+ _isCompact: 1 ,
317
+ _reserved: 0 ,
318
+ _mantissa: ( 0x0001 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 )
319
+ )
320
+ }
321
+
322
+ public var nextDown : Decimal {
323
+ return self - Decimal(
324
+ _exponent: _exponent,
325
+ _length: 1 ,
326
+ _isNegative: 0 ,
327
+ _isCompact: 1 ,
328
+ _reserved: 0 ,
329
+ _mantissa: ( 0x0001 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 , 0x0000 )
330
+ )
331
+ }
332
+
333
+ public func isEqual( to other: Decimal ) -> Bool {
334
+ return self == other
335
+ }
336
+
337
+ public func isLess( than other: Decimal ) -> Bool {
338
+ return Decimal . _compare ( lhs: self , rhs: other) == . orderedAscending
339
+ }
340
+
341
+ public func isLessThanOrEqualTo( _ other: Decimal ) -> Bool {
342
+ let order = Decimal . _compare ( lhs: self , rhs: other)
343
+ return order == . orderedAscending || order == . orderedSame
344
+ }
345
+
346
+ public func isTotallyOrdered( belowOrEqualTo other: Decimal ) -> Bool {
347
+ // Note: Decimal does not have -0 or infinities to worry about
348
+ if self . isNaN {
349
+ return false
350
+ }
351
+ if self < other {
352
+ return true
353
+ }
354
+ if other < self {
355
+ return false
356
+ }
357
+ // Fall through to == behavior
358
+ return true
359
+ }
313
360
}
314
361
315
362
@available ( macOS 10 . 10 , iOS 8 . 0 , watchOS 2 . 0 , tvOS 9 . 0 , * )
@@ -388,6 +435,52 @@ extension Decimal: Hashable {
388
435
}
389
436
}
390
437
438
+ @available ( macOS 10 . 10 , iOS 8 . 0 , watchOS 2 . 0 , tvOS 9 . 0 , * )
439
+ extension Decimal : Equatable {
440
+ public static func == ( lhs: Decimal , rhs: Decimal ) -> Bool {
441
+ #if FOUNDATION_FRAMEWORK
442
+ let bitwiseEqual : Bool =
443
+ lhs. _exponent == rhs. _exponent &&
444
+ lhs. _length == rhs. _length &&
445
+ lhs. _isNegative == rhs. _isNegative &&
446
+ lhs. _isCompact == rhs. _isCompact &&
447
+ lhs. _reserved == rhs. _reserved &&
448
+ lhs. _mantissa. 0 == rhs. _mantissa. 0 &&
449
+ lhs. _mantissa. 1 == rhs. _mantissa. 1 &&
450
+ lhs. _mantissa. 2 == rhs. _mantissa. 2 &&
451
+ lhs. _mantissa. 3 == rhs. _mantissa. 3 &&
452
+ lhs. _mantissa. 4 == rhs. _mantissa. 4 &&
453
+ lhs. _mantissa. 5 == rhs. _mantissa. 5 &&
454
+ lhs. _mantissa. 6 == rhs. _mantissa. 6 &&
455
+ lhs. _mantissa. 7 == rhs. _mantissa. 7
456
+ #else
457
+ let bitwiseEqual : Bool =
458
+ lhs. storage. exponent == rhs. storage. exponent &&
459
+ lhs. storage. lengthFlagsAndReserved == rhs. storage. lengthFlagsAndReserved &&
460
+ lhs. storage. reserved == rhs. storage. reserved &&
461
+ lhs. storage. mantissa. 0 == rhs. storage. mantissa. 0 &&
462
+ lhs. storage. mantissa. 1 == rhs. storage. mantissa. 1 &&
463
+ lhs. storage. mantissa. 2 == rhs. storage. mantissa. 2 &&
464
+ lhs. storage. mantissa. 3 == rhs. storage. mantissa. 3 &&
465
+ lhs. storage. mantissa. 4 == rhs. storage. mantissa. 4 &&
466
+ lhs. storage. mantissa. 5 == rhs. storage. mantissa. 5 &&
467
+ lhs. storage. mantissa. 6 == rhs. storage. mantissa. 6 &&
468
+ lhs. storage. mantissa. 7 == rhs. storage. mantissa. 7
469
+ #endif
470
+ if bitwiseEqual {
471
+ return true
472
+ }
473
+ return Decimal . _compare ( lhs: lhs, rhs: rhs) == . orderedSame
474
+ }
475
+ }
476
+
477
+ @available ( macOS 10 . 10 , iOS 8 . 0 , watchOS 2 . 0 , tvOS 9 . 0 , * )
478
+ extension Decimal : Comparable {
479
+ public static func < ( lhs: Decimal , rhs: Decimal ) -> Bool {
480
+ return Decimal . _compare ( lhs: lhs, rhs: rhs) == . orderedAscending
481
+ }
482
+ }
483
+
391
484
@available ( macOS 10 . 10 , iOS 8 . 0 , watchOS 2 . 0 , tvOS 9 . 0 , * )
392
485
extension Decimal : Codable {
393
486
private enum CodingKeys : Int , CodingKey {
@@ -445,10 +538,8 @@ extension Decimal : Codable {
445
538
}
446
539
447
540
// MARK: - SignedNumeric
448
- // SwiftFoundation's `Decimal` does not fully conform to
449
- // SignedNumeric yet because no arithmetics have been implemented
450
541
@available ( macOS 10 . 10 , iOS 8 . 0 , watchOS 2 . 0 , tvOS 9 . 0 , * )
451
- extension Decimal /* : SignedNumeric */ {
542
+ extension Decimal : SignedNumeric {
452
543
public var magnitude : Decimal {
453
544
guard _length != 0 else { return self }
454
545
return Decimal (
@@ -510,10 +601,73 @@ extension Decimal /* : SignedNumeric */ {
510
601
return Decimal ( 0 )
511
602
}
512
603
}
513
- #else
514
- // We need this symbol until Decimal fully conform to SignedNumeric
515
- public static var zero : Decimal {
516
- return Decimal ( 0 )
517
- }
518
604
#endif
605
+
606
+ public static func += ( lhs: inout Decimal , rhs: Decimal ) {
607
+ let result = try ? lhs. _add ( rhs: rhs, roundingMode: . plain)
608
+ if let result = result {
609
+ lhs = result. result
610
+ }
611
+ }
612
+
613
+ public static func -= ( lhs: inout Decimal , rhs: Decimal ) {
614
+ let result = try ? lhs. _subtract ( rhs: rhs, roundingMode: . plain)
615
+ if let result = result {
616
+ lhs = result
617
+ }
618
+ }
619
+
620
+ public static func *= ( lhs: inout Decimal , rhs: Decimal ) {
621
+ let result = try ? lhs. _multiply ( by: rhs, roundingMode: . plain)
622
+ if let result = result {
623
+ lhs = result
624
+ }
625
+ }
626
+
627
+ public static func /= ( lhs: inout Decimal , rhs: Decimal ) {
628
+ let result = try ? lhs. _divide ( by: rhs, roundingMode: . plain)
629
+ if let result = result {
630
+ lhs = result
631
+ }
632
+ }
633
+
634
+ public static func + ( lhs: Decimal , rhs: Decimal ) -> Decimal {
635
+ var answer = lhs
636
+ answer += rhs
637
+ return answer
638
+ }
639
+
640
+ public static func - ( lhs: Decimal , rhs: Decimal ) -> Decimal {
641
+ var answer = lhs
642
+ answer -= rhs
643
+ return answer
644
+ }
645
+
646
+ public static func * ( lhs: Decimal , rhs: Decimal ) -> Decimal {
647
+ var answer = lhs
648
+ answer *= rhs
649
+ return answer
650
+ }
651
+
652
+ public static func / ( lhs: Decimal , rhs: Decimal ) -> Decimal {
653
+ var answer = lhs
654
+ answer /= rhs
655
+ return answer
656
+ }
657
+
658
+ public mutating func negate( ) {
659
+ guard self . _length != 0 else { return }
660
+ self . _isNegative = self . _isNegative == 0 ? 1 : 0
661
+ }
662
+ }
663
+
664
+ @available ( macOS 10 . 10 , iOS 8 . 0 , watchOS 2 . 0 , tvOS 9 . 0 , * )
665
+ extension Decimal : Strideable {
666
+ public func distance( to other: Decimal ) -> Decimal {
667
+ return self - other
668
+ }
669
+
670
+ public func advanced( by n: Decimal ) -> Decimal {
671
+ return self + n
672
+ }
519
673
}
0 commit comments