Skip to content

[SR-3887] Decimal(n) fails to initialise properly for many integers within range. #4110

@swift-ci

Description

@swift-ci
Previous ID SR-3887
Radar None
Original Reporter j-h-a (JIRA User)
Type Bug
Status Resolved
Resolution Done

Attachment: Download

Environment

Apple Swift version 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1).

Additional Detail from JIRA
Votes 0
Component/s Foundation
Labels Bug
Assignee None
Priority Medium

md5: 3592da22040f9427c02f2ef22b03d3ed

Issue Description:

For many numbers easily representable by Decimal, the initialiser fails.

Example 1:

let a1 = Decimal(18446742) // 18446742.000000002048 (wrong)
let a2 = Decimal(18446741) + Decimal(1) // 18446742 (correct)

Example 2:

let b1 = Decimal(1000000007) // 1000000007.0000001024 (wrong)
let b2 = Decimal(1000000006) + Decimal(1) // 1000000007 (correct)

The following code calculates how many integers get initialised incorrectly in a few different ranges, all within the range of Int32:

let startValues = [
            0,
   59_386_023,
  264_109_865,
  364_109_865,
1_642_385_017,
]
let len = 10_000_000

for start in startValues {
    var fails = 0
    for i in start ..< (start + len) {
        let a = Decimal(i)
        if a.description.range(of: ".") != nil {
            fails += 1
        }
    }
    let percentFailed = 100.0 * Double(fails) / Double(len)
    print("Starting at \(start): Found \(fails) fails in \(len) (\(percentFailed)%)")
}

And the output is:

Starting at 0: Found 1106804 fails in 10000000 (11.06804%)
Starting at 59386023: Found 0 fails in 10000000 (0.0%)
Starting at 264109865: Found 0 fails in 10000000 (0.0%)
Starting at 364109865: Found 1293746 fails in 10000000 (12.93746%)
Starting at 1642385017: Found 6875000 fails in 10000000 (68.75%)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions