Skip to content

Commit 2f4e70b

Browse files
xwuparkera
authored andcommitted
[Foundation][SR-3125] Fix Decimal init from (U)Int64 (#18486)
* [Foundation][SR-3125] Fix Decimal init from (U)Int64 * Minor edits mostly to appease the ToT compiler
1 parent 361f8dd commit 2f4e70b

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

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

+25-3
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,33 @@ 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 /= 10
374+
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+
self.init(value.magnitude)
389+
if value < 0 {
390+
_isNegative = 1
391+
}
370392
}
371393

372394
public init(_ value: UInt) {

Diff for: test/stdlib/TestDecimal.swift

+5-1
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
@@ -119,6 +119,10 @@ class TestDecimal : TestDecimalSuper {
119119
expectFalse(zero.isInfinite)
120120
expectFalse(zero.isNaN)
121121
expectFalse(zero.isSignaling)
122+
123+
let d1 = Decimal(1234567890123456789 as UInt64)
124+
expectEqual(d1._exponent, 0)
125+
expectEqual(d1._length, 4)
122126
}
123127
func test_Constants() {
124128
expectEqual(8, NSDecimalMaxSize)

0 commit comments

Comments
 (0)