Skip to content

Commit 89b26a7

Browse files
committed
[Foundation][SR-3125] Fix Decimal init from (U)Int64
1 parent 937f009 commit 89b26a7

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

stdlib/public/SDK/Foundation/Decimal.swift

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -362,11 +362,35 @@ extension Decimal {
362362
}
363363

364364
public init(_ value: UInt64) {
365-
self.init(Double(value))
365+
self = Decimal()
366+
if value == 0 {
367+
return
368+
}
369+
370+
var compactValue = value
371+
var exponent: Int32 = 0
372+
while compactValue % 10 == 0 {
373+
compactValue = compactValue / 10
374+
exponent = exponent + 1
375+
}
376+
_isCompact = 1
377+
_exponent = exponent
378+
379+
let wordCount = ((UInt64.bitWidth - compactValue.leadingZeroBitCount) + (UInt16.bitWidth - 1)) / UInt16.bitWidth
380+
_length = UInt32(wordCount)
381+
_mantissa.0 = UInt16(truncatingIfNeeded: compactValue >> 0)
382+
_mantissa.1 = UInt16(truncatingIfNeeded: compactValue >> 16)
383+
_mantissa.2 = UInt16(truncatingIfNeeded: compactValue >> 32)
384+
_mantissa.3 = UInt16(truncatingIfNeeded: compactValue >> 48)
366385
}
367386

368387
public init(_ value: Int64) {
369-
self.init(Double(value))
388+
if value < 0 {
389+
self.init(value == Int64.min ? UInt64(Int64.max) + 1 : UInt64(abs(value)))
390+
_isNegative = 1
391+
} else {
392+
self.init(UInt64(value))
393+
}
370394
}
371395

372396
public init(_ value: UInt) {

test/stdlib/TestDecimal.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
1+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
22
// Licensed under Apache License v2.0 with Runtime Library Exception
33
//
44
// See https://swift.org/LICENSE.txt for license information
@@ -118,6 +118,10 @@ class TestDecimal : TestDecimalSuper {
118118
expectFalse(zero.isInfinite)
119119
expectFalse(zero.isNaN)
120120
expectFalse(zero.isSignaling)
121+
122+
let d1 = Decimal(1234567890123456789 as UInt64)
123+
expectEqual(d1._exponent, 0)
124+
expectEqual(d1._length, 4)
121125
}
122126
func test_Constants() {
123127
expectEqual(8, NSDecimalMaxSize)

0 commit comments

Comments
 (0)