@@ -22,7 +22,7 @@ extension Decimal : CustomStringConvertible {
2222 if let decimalSeparator = locale? . decimalSeparator {
2323 decimalString = decimalString. replacing ( decimalSeparator, with: " . " )
2424 }
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 {
2626 return nil
2727 }
2828 self = value
@@ -35,11 +35,8 @@ extension Decimal : CustomStringConvertible {
3535
3636// The methods in this extension exist to match the protocol requirements of
3737// 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).
4138@available ( macOS 10 . 10 , iOS 8 . 0 , watchOS 2 . 0 , tvOS 9 . 0 , * )
42- extension Decimal {
39+ extension Decimal /* : FloatingPoint */ {
4340 public static let leastFiniteMagnitude = Decimal (
4441 _exponent: 127 ,
4542 _length: 8 ,
@@ -310,6 +307,56 @@ extension Decimal {
310307
311308 @available ( * , unavailable, message: " Decimal does not yet fully adopt FloatingPoint. " )
312309 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+ }
313360}
314361
315362@available ( macOS 10 . 10 , iOS 8 . 0 , watchOS 2 . 0 , tvOS 9 . 0 , * )
@@ -388,6 +435,52 @@ extension Decimal: Hashable {
388435 }
389436}
390437
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+
391484@available ( macOS 10 . 10 , iOS 8 . 0 , watchOS 2 . 0 , tvOS 9 . 0 , * )
392485extension Decimal : Codable {
393486 private enum CodingKeys : Int , CodingKey {
@@ -445,10 +538,8 @@ extension Decimal : Codable {
445538}
446539
447540// MARK: - SignedNumeric
448- // SwiftFoundation's `Decimal` does not fully conform to
449- // SignedNumeric yet because no arithmetics have been implemented
450541@available ( macOS 10 . 10 , iOS 8 . 0 , watchOS 2 . 0 , tvOS 9 . 0 , * )
451- extension Decimal /* : SignedNumeric */ {
542+ extension Decimal : SignedNumeric {
452543 public var magnitude : Decimal {
453544 guard _length != 0 else { return self }
454545 return Decimal (
@@ -510,10 +601,73 @@ extension Decimal /* : SignedNumeric */ {
510601 return Decimal ( 0 )
511602 }
512603 }
513- #else
514- // We need this symbol until Decimal fully conform to SignedNumeric
515- public static var zero : Decimal {
516- return Decimal ( 0 )
517- }
518604#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+ }
519673}
0 commit comments