Skip to content

Commit 05171ee

Browse files
authored
Merge pull request #2925 from spevans/pr_sr_7236
2 parents 3a928c8 + 83d83b9 commit 05171ee

File tree

2 files changed

+81
-1
lines changed

2 files changed

+81
-1
lines changed

Sources/Foundation/Decimal.swift

+3-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@ extension Decimal : Hashable, Comparable {
161161

162162
// The low 64 bits of the integer part. (Used by uint64Value and int64Value.)
163163
private var _unsignedInt64Value: UInt64 {
164-
if _exponent < -20 || _exponent > 20 {
164+
// Quick check if number if has too many zeros before decimal point or too many trailing zeros after decimal point.
165+
// Log10 (2^64) ~ 19, log10 (2^128) ~ 38
166+
if _exponent < -38 || _exponent > 20 {
165167
return 0
166168
}
167169
if _length == 0 || isZero || magnitude < (0 as Decimal) {

Tests/Foundation/Tests/TestDecimal.swift

+78
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,83 @@ class TestDecimal: XCTestCase {
12801280
}
12811281
}
12821282

1283+
func test_intValue() {
1284+
// SR-7236
1285+
XCTAssertEqual(NSDecimalNumber(value: -1).intValue, -1)
1286+
XCTAssertEqual(NSDecimalNumber(value: 0).intValue, 0)
1287+
XCTAssertEqual(NSDecimalNumber(value: 1).intValue, 1)
1288+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal.nan).intValue, 0)
1289+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(1e50)).intValue, 0)
1290+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(1e-50)).intValue, 0)
1291+
1292+
XCTAssertEqual(NSDecimalNumber(value: UInt64.max).uint64Value, UInt64.max)
1293+
XCTAssertEqual(NSDecimalNumber(value: UInt64.max).adding(1).uint64Value, 0)
1294+
XCTAssertEqual(NSDecimalNumber(value: Int64.max).int64Value, Int64.max)
1295+
XCTAssertEqual(NSDecimalNumber(value: Int64.max).adding(1).int64Value, Int64.min)
1296+
XCTAssertEqual(NSDecimalNumber(value: Int64.max).adding(1).uint64Value, UInt64(Int64.max) + 1)
1297+
XCTAssertEqual(NSDecimalNumber(value: Int64.min).int64Value, Int64.min)
1298+
1299+
XCTAssertEqual(NSDecimalNumber(value: 10).dividing(by: 3).intValue, 3)
1300+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Double.pi)).intValue, 3)
1301+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Int.max)).intValue, Int.max)
1302+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Int32.max)).int32Value, Int32.max)
1303+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Int64.max)).int64Value, Int64.max)
1304+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Int.min)).intValue, Int.min)
1305+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Int32.min)).int32Value, Int32.min)
1306+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(Int64.min)).int64Value, Int64.min)
1307+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(UInt.max)).uintValue, UInt.max)
1308+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(UInt32.max)).uint32Value, UInt32.max)
1309+
XCTAssertEqual(NSDecimalNumber(decimal: Decimal(UInt64.max)).uint64Value, UInt64.max)
1310+
1311+
1312+
// SR-2980
1313+
let sr2980Tests = [
1314+
("250.229953885078403", 250),
1315+
("103.8097165991902834008097165991902834", 103),
1316+
("31.541176470588235294", 31),
1317+
("12345.12345678901234", 12345),
1318+
("12345.123456789012345", 12345),
1319+
]
1320+
1321+
for (string, value) in sr2980Tests {
1322+
let decimalValue = NSDecimalNumber(string: string)
1323+
XCTAssertEqual(decimalValue.intValue, value)
1324+
XCTAssertEqual(decimalValue.int8Value, Int8(truncatingIfNeeded: value))
1325+
XCTAssertEqual(decimalValue.int16Value, Int16(value))
1326+
XCTAssertEqual(decimalValue.int32Value, Int32(value))
1327+
XCTAssertEqual(decimalValue.int64Value, Int64(value))
1328+
XCTAssertEqual(decimalValue.uintValue, UInt(value))
1329+
XCTAssertEqual(decimalValue.uint8Value, UInt8(truncatingIfNeeded: value))
1330+
XCTAssertEqual(decimalValue.uint16Value, UInt16(value))
1331+
XCTAssertEqual(decimalValue.uint32Value, UInt32(value))
1332+
XCTAssertEqual(decimalValue.uint64Value, UInt64(value))
1333+
}
1334+
1335+
// Large mantissas, negative exponent
1336+
let maxMantissa = (UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max, UInt16.max)
1337+
1338+
let tests = [
1339+
(-34, 0, "34028.2366920938463463374607431768211455", 34028),
1340+
(-35, 0, "3402.82366920938463463374607431768211455", 3402),
1341+
(-36, 0, "340.282366920938463463374607431768211455", 340),
1342+
(-37, 0, "34.0282366920938463463374607431768211455", 34),
1343+
(-38, 0, "3.40282366920938463463374607431768211455", 3),
1344+
(-39, 0, "0.340282366920938463463374607431768211455", 0),
1345+
(-34, 1, "-34028.2366920938463463374607431768211455", -34028),
1346+
(-35, 1, "-3402.82366920938463463374607431768211455", -3402),
1347+
(-36, 1, "-340.282366920938463463374607431768211455", -340),
1348+
(-37, 1, "-34.0282366920938463463374607431768211455", -34),
1349+
(-38, 1, "-3.40282366920938463463374607431768211455", -3),
1350+
(-39, 1, "-0.340282366920938463463374607431768211455", 0),
1351+
]
1352+
1353+
for (exponent, isNegative, description, intValue) in tests {
1354+
let d = Decimal(_exponent: Int32(exponent), _length: 8, _isNegative: UInt32(isNegative), _isCompact: 1, _reserved: 0, _mantissa: maxMantissa)
1355+
XCTAssertEqual(d.description, description)
1356+
XCTAssertEqual(NSDecimalNumber(decimal:d).intValue, intValue)
1357+
}
1358+
}
1359+
12831360
static var allTests : [(String, (TestDecimal) -> () throws -> Void)] {
12841361
return [
12851362
("test_NSDecimalNumberInit", test_NSDecimalNumberInit),
@@ -1310,6 +1387,7 @@ class TestDecimal: XCTestCase {
13101387
("test_multiplyingByPowerOf10", test_multiplyingByPowerOf10),
13111388
("test_initExactly", test_initExactly),
13121389
("test_NSNumberEquality", test_NSNumberEquality),
1390+
("test_intValue", test_intValue),
13131391
]
13141392
}
13151393
}

0 commit comments

Comments
 (0)