Skip to content

Commit b2ce4a2

Browse files
authored
[Foundation] Fix two Decimal members with respect to NaN (#25698)
* Update Decimal.swift Fix `Decimal.magnitude` so that `Decimal.nan.magnitude` is no longer incorrectly `0`. Port changes from swiftlang/swift-corelibs-foundation#1759, crucially correcting an error where `(0 as Decimal).doubleValue` returned `.nan`. * [gardening] Zap indentation error * Add test for `Decimal.nan.magnitude` * Apply reviewer suggestion Clean up `doubleValue`
1 parent 16b6eb0 commit b2ce4a2

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

Diff for: stdlib/public/Darwin/Foundation/Decimal.swift

+24-12
Original file line numberDiff line numberDiff line change
@@ -150,21 +150,32 @@ public func pow(_ x: Decimal, _ y: Int) -> Decimal {
150150
}
151151

152152
extension Decimal : Hashable, Comparable {
153-
internal var doubleValue : Double {
153+
private subscript(index: UInt32) -> UInt16 {
154+
get {
155+
switch index {
156+
case 0: return _mantissa.0
157+
case 1: return _mantissa.1
158+
case 2: return _mantissa.2
159+
case 3: return _mantissa.3
160+
case 4: return _mantissa.4
161+
case 5: return _mantissa.5
162+
case 6: return _mantissa.6
163+
case 7: return _mantissa.7
164+
default: fatalError("Invalid index \(index) for _mantissa")
165+
}
166+
}
167+
}
168+
169+
internal var doubleValue: Double {
170+
if _length == 0 {
171+
return _isNegative == 1 ? Double.nan : 0
172+
}
173+
154174
var d = 0.0
155-
if _length == 0 && _isNegative == 0 {
156-
return Double.nan
175+
for idx in (0..<min(_length, 8)).reversed() {
176+
d = d * 65536 + Double(self[idx])
157177
}
158178

159-
d = d * 65536 + Double(_mantissa.7)
160-
d = d * 65536 + Double(_mantissa.6)
161-
d = d * 65536 + Double(_mantissa.5)
162-
d = d * 65536 + Double(_mantissa.4)
163-
d = d * 65536 + Double(_mantissa.3)
164-
d = d * 65536 + Double(_mantissa.2)
165-
d = d * 65536 + Double(_mantissa.1)
166-
d = d * 65536 + Double(_mantissa.0)
167-
168179
if _exponent < 0 {
169180
for _ in _exponent..<0 {
170181
d /= 10.0
@@ -212,6 +223,7 @@ extension Decimal : ExpressibleByIntegerLiteral {
212223

213224
extension Decimal : SignedNumeric {
214225
public var magnitude: Decimal {
226+
guard _length != 0 else { return self }
215227
return Decimal(
216228
_exponent: self._exponent, _length: self._length,
217229
_isNegative: 0, _isCompact: self._isCompact,

Diff for: test/stdlib/TestDecimal.swift

+1
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ class TestDecimal : TestDecimalSuper {
303303
expectEqual(Decimal(68040), Decimal(386).advanced(by: Decimal(67654)))
304304
expectEqual(Decimal(1.234), abs(Decimal(1.234)))
305305
expectEqual(Decimal(1.234), abs(Decimal(-1.234)))
306+
expectTrue(Decimal.nan.magnitude.isNaN)
306307
var a = Decimal(1234)
307308
var r = a
308309
expectEqual(.noError, NSDecimalMultiplyByPowerOf10(&r, &a, 1, .plain))

0 commit comments

Comments
 (0)