Skip to content

Commit b9451fd

Browse files
authored
Merge pull request #3067 from xwu/decimal-floatingpoint
[SR-6671] Fix `Decimal` implementation of `FloatingPoint` constants
2 parents 671cadb + 87850da commit b9451fd

File tree

5 files changed

+32
-60
lines changed

5 files changed

+32
-60
lines changed

Darwin/Foundation-swiftoverlay-Tests/TestDecimal.swift

+5-3
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,15 @@ class TestDecimal : XCTestCase {
116116
XCTAssertEqual(8, NSDecimalMaxSize)
117117
XCTAssertEqual(32767, NSDecimalNoScale)
118118
let smallest = Decimal(_exponent: 127, _length: 8, _isNegative: 1, _isCompact: 1, _reserved: 0, _mantissa: (UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max))
119-
XCTAssertEqual(smallest, Decimal.leastFiniteMagnitude)
119+
XCTAssertEqual(smallest, -Decimal.greatestFiniteMagnitude)
120120
let biggest = Decimal(_exponent: 127, _length: 8, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max))
121121
XCTAssertEqual(biggest, Decimal.greatestFiniteMagnitude)
122-
let leastNormal = Decimal(_exponent: -127, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
122+
let leastNormal = Decimal(_exponent: -128, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
123123
XCTAssertEqual(leastNormal, Decimal.leastNormalMagnitude)
124-
let leastNonzero = Decimal(_exponent: -127, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
124+
let leastNonzero = Decimal(_exponent: -128, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
125125
XCTAssertEqual(leastNonzero, Decimal.leastNonzeroMagnitude)
126+
let leastFinite = 0 as Decimal
127+
XCTAssertEqual(leastFinite, Decimal.leastFiniteMagnitude)
126128
let pi = Decimal(_exponent: -38, _length: 8, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (0x6623, 0x7d57, 0x16e7, 0xad0d, 0xaf52, 0x4641, 0xdfa7, 0xec58))
127129
XCTAssertEqual(pi, Decimal.pi)
128130
XCTAssertEqual(10, Decimal.radix)

Darwin/Foundation-swiftoverlay/Decimal.swift

+4-18
Original file line numberDiff line numberDiff line change
@@ -330,15 +330,6 @@ extension Decimal : Strideable {
330330
// If it becomes clear that conformance is truly impossible, we can deprecate
331331
// some of the methods (e.g. `isEqual(to:)` in favor of operators).
332332
extension Decimal {
333-
public static let leastFiniteMagnitude = Decimal(
334-
_exponent: 127,
335-
_length: 8,
336-
_isNegative: 1,
337-
_isCompact: 1,
338-
_reserved: 0,
339-
_mantissa: (0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff)
340-
)
341-
342333
public static let greatestFiniteMagnitude = Decimal(
343334
_exponent: 127,
344335
_length: 8,
@@ -349,22 +340,17 @@ extension Decimal {
349340
)
350341

351342
public static let leastNormalMagnitude = Decimal(
352-
_exponent: -127,
343+
_exponent: -128,
353344
_length: 1,
354345
_isNegative: 0,
355346
_isCompact: 1,
356347
_reserved: 0,
357348
_mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000)
358349
)
359350

360-
public static let leastNonzeroMagnitude = Decimal(
361-
_exponent: -127,
362-
_length: 1,
363-
_isNegative: 0,
364-
_isCompact: 1,
365-
_reserved: 0,
366-
_mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000)
367-
)
351+
public static let leastNonzeroMagnitude = leastNormalMagnitude
352+
353+
public static let leastFiniteMagnitude = zero
368354

369355
public static let pi = Decimal(
370356
_exponent: -38,

Sources/Foundation/Decimal.swift

+4-18
Original file line numberDiff line numberDiff line change
@@ -498,15 +498,6 @@ extension Decimal : Strideable {
498498
// If it becomes clear that conformance is truly impossible, we can deprecate
499499
// some of the methods (e.g. `isEqual(to:)` in favor of operators).
500500
extension Decimal {
501-
public static let leastFiniteMagnitude = Decimal(
502-
_exponent: 127,
503-
_length: 8,
504-
_isNegative: 1,
505-
_isCompact: 1,
506-
_reserved: 0,
507-
_mantissa: (0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff)
508-
)
509-
510501
public static let greatestFiniteMagnitude = Decimal(
511502
_exponent: 127,
512503
_length: 8,
@@ -517,22 +508,17 @@ extension Decimal {
517508
)
518509

519510
public static let leastNormalMagnitude = Decimal(
520-
_exponent: -127,
511+
_exponent: -128,
521512
_length: 1,
522513
_isNegative: 0,
523514
_isCompact: 1,
524515
_reserved: 0,
525516
_mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000)
526517
)
527518

528-
public static let leastNonzeroMagnitude = Decimal(
529-
_exponent: -127,
530-
_length: 1,
531-
_isNegative: 0,
532-
_isCompact: 1,
533-
_reserved: 0,
534-
_mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000)
535-
)
519+
public static let leastNonzeroMagnitude = leastNormalMagnitude
520+
521+
public static let leastFiniteMagnitude = zero
536522

537523
public static let pi = Decimal(
538524
_exponent: -38,

Tests/Foundation/Tests/TestDecimal.swift

+15-17
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,15 @@ class TestDecimal: XCTestCase {
137137
XCTAssertEqual(8, NSDecimalMaxSize)
138138
XCTAssertEqual(32767, NSDecimalNoScale)
139139
let smallest = Decimal(_exponent: 127, _length: 8, _isNegative: 1, _isCompact: 1, _reserved: 0, _mantissa: (UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max))
140-
XCTAssertEqual(smallest, Decimal.leastFiniteMagnitude)
140+
XCTAssertEqual(smallest, -Decimal.greatestFiniteMagnitude)
141141
let biggest = Decimal(_exponent: 127, _length: 8, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max))
142142
XCTAssertEqual(biggest, Decimal.greatestFiniteMagnitude)
143-
let leastNormal = Decimal(_exponent: -127, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
143+
let leastNormal = Decimal(_exponent: -128, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
144144
XCTAssertEqual(leastNormal, Decimal.leastNormalMagnitude)
145-
let leastNonzero = Decimal(_exponent: -127, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
145+
let leastNonzero = Decimal(_exponent: -128, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (1, 0, 0, 0, 0, 0, 0, 0))
146146
XCTAssertEqual(leastNonzero, Decimal.leastNonzeroMagnitude)
147+
let leastFinite = 0 as Decimal
148+
XCTAssertEqual(leastFinite, Decimal.leastFiniteMagnitude)
147149
let pi = Decimal(_exponent: -38, _length: 8, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (0x6623, 0x7d57, 0x16e7, 0xad0d, 0xaf52, 0x4641, 0xdfa7, 0xec58))
148150
XCTAssertEqual(pi, Decimal.pi)
149151
XCTAssertEqual(10, Decimal.radix)
@@ -177,13 +179,12 @@ class TestDecimal: XCTestCase {
177179
XCTAssertEqual("-5", Decimal(signOf: Decimal(-3), magnitudeOf: Decimal(-5)).description)
178180
XCTAssertEqual("5", NSDecimalNumber(decimal: Decimal(5)).description)
179181
XCTAssertEqual("-5", NSDecimalNumber(decimal: Decimal(-5)).description)
180-
XCTAssertEqual("-3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Decimal.leastFiniteMagnitude.description)
181182
XCTAssertEqual("3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", Decimal.greatestFiniteMagnitude.description)
182-
XCTAssertEqual("0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", Decimal.leastNormalMagnitude.description)
183-
XCTAssertEqual("0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", Decimal.leastNonzeroMagnitude.description)
183+
XCTAssertEqual("0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", Decimal.leastNormalMagnitude.description)
184+
XCTAssertEqual("0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", Decimal.leastNonzeroMagnitude.description)
185+
XCTAssertEqual("0", Decimal.leastFiniteMagnitude.description)
184186

185187
let fr = Locale(identifier: "fr_FR")
186-
let leastFiniteMagnitude = "-3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
187188
let greatestFiniteMagnitude = "3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
188189

189190
XCTAssertEqual("0", NSDecimalNumber(decimal: Decimal()).description(withLocale: fr))
@@ -194,10 +195,9 @@ class TestDecimal: XCTestCase {
194195
XCTAssertEqual("3,14159265358979323846264338327950288419", NSDecimalNumber(decimal: Decimal.pi).description(withLocale: fr))
195196
XCTAssertEqual("-30000000000", NSDecimalNumber(decimal: Decimal(sign: .minus, exponent: 10, significand: Decimal(3))).description(withLocale: fr))
196197
XCTAssertEqual("123456,789", NSDecimalNumber(decimal: Decimal(string: "123456.789")!).description(withLocale: fr))
197-
XCTAssertEqual(leastFiniteMagnitude, NSDecimalNumber(decimal: Decimal.leastFiniteMagnitude).description(withLocale: fr))
198198
XCTAssertEqual(greatestFiniteMagnitude, NSDecimalNumber(decimal: Decimal.greatestFiniteMagnitude).description(withLocale: fr))
199-
XCTAssertEqual("0,0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", NSDecimalNumber(decimal: Decimal.leastNormalMagnitude).description(withLocale: fr))
200-
XCTAssertEqual("0,0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", NSDecimalNumber(decimal: Decimal.leastNonzeroMagnitude).description(withLocale: fr))
199+
XCTAssertEqual("0,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", NSDecimalNumber(decimal: Decimal.leastNormalMagnitude).description(withLocale: fr))
200+
XCTAssertEqual("0,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", NSDecimalNumber(decimal: Decimal.leastNonzeroMagnitude).description(withLocale: fr))
201201

202202
let en = Locale(identifier: "en_GB")
203203
XCTAssertEqual("0", NSDecimalNumber(decimal: Decimal()).description(withLocale: en))
@@ -208,10 +208,9 @@ class TestDecimal: XCTestCase {
208208
XCTAssertEqual("3.14159265358979323846264338327950288419", NSDecimalNumber(decimal: Decimal.pi).description(withLocale: en))
209209
XCTAssertEqual("-30000000000", NSDecimalNumber(decimal: Decimal(sign: .minus, exponent: 10, significand: Decimal(3))).description(withLocale: en))
210210
XCTAssertEqual("123456.789", NSDecimalNumber(decimal: Decimal(string: "123456.789")!).description(withLocale: en))
211-
XCTAssertEqual(leastFiniteMagnitude, NSDecimalNumber(decimal: Decimal.leastFiniteMagnitude).description(withLocale: en))
212211
XCTAssertEqual(greatestFiniteMagnitude, NSDecimalNumber(decimal: Decimal.greatestFiniteMagnitude).description(withLocale: en))
213-
XCTAssertEqual("0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", NSDecimalNumber(decimal: Decimal.leastNormalMagnitude).description(withLocale: en))
214-
XCTAssertEqual("0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", NSDecimalNumber(decimal: Decimal.leastNonzeroMagnitude).description(withLocale: en))
212+
XCTAssertEqual("0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", NSDecimalNumber(decimal: Decimal.leastNormalMagnitude).description(withLocale: en))
213+
XCTAssertEqual("0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", NSDecimalNumber(decimal: Decimal.leastNonzeroMagnitude).description(withLocale: en))
215214
}
216215

217216
func test_ExplicitConstruction() {
@@ -333,7 +332,6 @@ class TestDecimal: XCTestCase {
333332
XCTAssertEqual(NSDecimalNumber(floatLiteral: 2880.4).subtracting(NSDecimalNumber(floatLiteral: 5538)), NSDecimalNumber(floatLiteral: 2880.4 - 5538))
334333

335334
XCTAssertEqual(Decimal.greatestFiniteMagnitude - Decimal.greatestFiniteMagnitude, Decimal(0))
336-
XCTAssertEqual(Decimal.leastFiniteMagnitude - Decimal(1), Decimal.leastFiniteMagnitude)
337335
let overflowed = Decimal.greatestFiniteMagnitude + Decimal.greatestFiniteMagnitude
338336
XCTAssertTrue(overflowed.isNaN)
339337

@@ -388,7 +386,7 @@ class TestDecimal: XCTestCase {
388386
XCTAssertEqual((1 as Decimal).magnitude, abs(-1 as Decimal))
389387
XCTAssertEqual((-1 as Decimal).magnitude, abs(-1 as Decimal))
390388
XCTAssertEqual((-1 as Decimal).magnitude, abs(1 as Decimal))
391-
XCTAssertEqual(Decimal.leastFiniteMagnitude.magnitude, -Decimal.leastFiniteMagnitude) // A bit of a misnomer.
389+
XCTAssertEqual(Decimal.leastFiniteMagnitude.magnitude, -Decimal.leastFiniteMagnitude)
392390
XCTAssertEqual(Decimal.greatestFiniteMagnitude.magnitude, Decimal.greatestFiniteMagnitude)
393391
XCTAssertTrue(Decimal.nan.magnitude.isNaN)
394392

@@ -568,15 +566,15 @@ class TestDecimal: XCTestCase {
568566
XCTAssertTrue(Int(small.exponent) - Int(large.exponent) < Int(Int8.min))
569567
XCTAssertNotEqual(small, large)
570568

571-
XCTAssertEqual(small.exponent, -127)
569+
XCTAssertEqual(small.exponent, -128)
572570
XCTAssertEqual(large.exponent, 127)
573571
XCTAssertEqual(.lossOfPrecision, NSDecimalNormalize(&small, &large, .plain))
574572
XCTAssertEqual(small.exponent, 127)
575573
XCTAssertEqual(large.exponent, 127)
576574

577575
small = Decimal.leastNonzeroMagnitude
578576
large = Decimal.greatestFiniteMagnitude
579-
XCTAssertEqual(small.exponent, -127)
577+
XCTAssertEqual(small.exponent, -128)
580578
XCTAssertEqual(large.exponent, 127)
581579
XCTAssertEqual(.lossOfPrecision, NSDecimalNormalize(&large, &small, .plain))
582580
XCTAssertEqual(small.exponent, 127)

Tests/Foundation/Tests/TestJSONSerialization.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -1428,10 +1428,10 @@ extension TestJSONSerialization {
14281428
}
14291429

14301430
func test_serialize_Decimal() {
1431-
XCTAssertEqual(try trySerialize([-Decimal.leastFiniteMagnitude]), "[3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
1432-
XCTAssertEqual(try trySerialize([Decimal.leastFiniteMagnitude]), "[-3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
1433-
XCTAssertEqual(try trySerialize([-Decimal.leastNonzeroMagnitude]), "[-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]")
1434-
XCTAssertEqual(try trySerialize([Decimal.leastNonzeroMagnitude]), "[0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]")
1431+
XCTAssertEqual(try trySerialize([-Decimal.leastFiniteMagnitude]), "[0]")
1432+
XCTAssertEqual(try trySerialize([Decimal.leastFiniteMagnitude]), "[0]")
1433+
XCTAssertEqual(try trySerialize([-Decimal.leastNonzeroMagnitude]), "[-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]")
1434+
XCTAssertEqual(try trySerialize([Decimal.leastNonzeroMagnitude]), "[0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001]")
14351435
XCTAssertEqual(try trySerialize([-Decimal.greatestFiniteMagnitude]), "[-3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
14361436
XCTAssertEqual(try trySerialize([Decimal.greatestFiniteMagnitude]), "[3402823669209384634633746074317682114550000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000]")
14371437
XCTAssertEqual(try trySerialize([Decimal(Int8.min), Decimal(Int8(0)), Decimal(Int8.max)]), "[-128,0,127]")

0 commit comments

Comments
 (0)