Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-2980] NSDecimalNumber's .intValue produces incorrect results for numbers with many numbers after the decimal place #4315

Open
swift-ci opened this issue Oct 18, 2016 · 10 comments

Comments

@swift-ci
Copy link
Contributor

Previous ID SR-2980
Radar None
Original Reporter pwicks (JIRA User)
Type Bug
Status Reopened
Resolution
Environment
$ swift --version
Apple Swift version 3.0 (swiftlang-800.0.46.2 clang-800.0.38)
Target: x86_64-apple-macosx10.9

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.11.6
BuildVersion:   15G1004

XCode Version: Version 8.0 (8A218a)

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

md5: edd4e608242098a65d37a036b1051abb

duplicates:

  • SR-7236 NSDecimalNumber .intValue reporting 0 on numbers with many decimals

is duplicated by:

  • SR-7236 NSDecimalNumber .intValue reporting 0 on numbers with many decimals
  • SR-9025 Incorrect conversion of NSDecimalNumber to Int

Issue Description:

For NSDecimalNumbers with a lot of numbers after the decimal point, .intValue is always zero. Experimentally, it looks like the crossover point where .intValue becomes incorrect is around 19 places after the decimal point (but I haven't tested this extensively).

.int64Value has the same behavior. .int32Value, .int16Value and .int8Value do not.

Test Case:

var a = NSDecimalNumber(string: "103.8097165991902834008097165991902834")
a: NSDecimalNumber = {
  Foundation.NSNumber = {
    baseNSValue@0 = <extracting data from value failed>

  }
}
  6> a.intValue
$R2: Int = 0
  7> a.doubleValue
$R3: Double = 103.80971659919028
  8> a.int64Value
$R4: Int64 = 0
  9> a.int32Value
$R5: Int32 = 103
 10> a.int16Value
$R6: Int16 = 103
 11> a.int8Value
$R7: Int8 = 103
 12> var b = NSDecimalNumber(string: "1.1111111111111111111111111111111111111")
b: NSDecimalNumber = {
  Foundation.NSNumber = {
    baseNSValue@0 = <extracting data from value failed>

  }
}
 13> b.intValue
$R8: Int = 0
 14> b.int32Value
$R9: Int32 = 1
@swift-ci
Copy link
Contributor Author

Comment by Fabian Emmes (JIRA)

I also noticed this bug, using Swift 3.0.1:

Apple Swift version 3.0.1 (swiftlang-800.0.58.6 clang-800.0.42.1)
Target: x86_64-apple-macosx10.9

And indeed it looks as if it depends on the number of decimal places:

 14> NSDecimalNumber(string: "250.229953885078403").int64Value
$R4: Int64 = 250
 15> NSDecimalNumber(string: "250.22995388507840317").int64Value 
$R5: Int64 = 65
 16> NSDecimalNumber(string: "250.2299538850784031744").int64Value 
$R6: Int64 = 0

@swift-ci
Copy link
Contributor Author

Comment by Andrew Hoos (JIRA)

This seems to be resolved in top of tree master.

@martinr448
Copy link

The problem still exists in Swift 4.2 (Xcode 10):

Welcome to Apple Swift version 4.2 (swiftlang-1000.11.37.1 clang-1000.11.45.1). Type :help for assistance.
  1>  
  2> import Foundation
  3>  
  4> let a = NSDecimalNumber(string: "103.8097165991902834008097165991902834")
a: NSDecimalNumber = 3748538862552120946 x 10^-34
  5> a.int64Value
$R0: Int64 = 0

Another example:

  7> let b = NSDecimalNumber(string: "31.541176470588235294")
b: NSDecimalNumber = 13094432396878683678 x 10^-18
  8> b.int64Value
$R1: Int64 = -5
  9> b.uint64Value 
$R2: UInt64 = 13

@martinr448
Copy link

The wrong results can still be reproduced with Apple Swift version 4.2 (swiftlang-1000.11.37.1 clang-1000.11.45.1) that comes with Xcode 10, therefore I have reopened the issue.

@bealex
Copy link

bealex commented Feb 10, 2020

Got this problem with current Swift 5.1.3 (Xcode 11.3.1)

@pmuller
Copy link
Mannequin

pmuller mannequin commented Mar 4, 2020

To reproduce on Swift 5.1.3:

$ swift -version
Apple Swift version 5.1.3 (swiftlang-1100.0.282.1 clang-1100.0.33.15)
Target: x86_64-apple-darwin19.3.0
$ swift
import Foundation
print((Decimal(string: "12345.12345678901234")! as NSDecimalNumber).intValue) 
12345
print((Decimal(string: "12345.123456789012345")! as NSDecimalNumber).intValue)
-6101

@spevans
Copy link
Collaborator

spevans commented Nov 20, 2020

Linux fix: #2925

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@shahmishal shahmishal transferred this issue from apple/swift May 5, 2022
@pietermuller
Copy link

To reproduce with Swift 5.7 on macOS:

$ swift -version
swift-driver version: 1.62.8 Apple Swift version 5.7 (swiftlang-5.7.0.127.4 clang-1400.0.29.50)
Target: arm64-apple-macosx12.0
$ swift repl
Welcome to Apple Swift version 5.7 (swiftlang-5.7.0.127.4 clang-1400.0.29.50).
Type :help for assistance.
  1> import Foundation 
  2> print((Decimal(string: "12345.12345678901234")! as NSDecimalNumber).intValue) 
12345
  3> print((Decimal(string: "12345.123456789012345")! as NSDecimalNumber).intValue)
-6101

@xjki
Copy link

xjki commented Sep 26, 2023

Reproducable with Swift 5.9 on macOS:

~$ swift repl
Welcome to Apple Swift version 5.9 (swiftlang-5.9.0.128.108 clang-1500.0.40.1).
1> import Foundation
2> print((Decimal(string: "12345.12345678901234")! as NSDecimalNumber).intValue)
12345
3> print((Decimal(string: "12345.123456789012345")! as NSDecimalNumber).intValue)
-6101

@tcamin
Copy link

tcamin commented Sep 29, 2023

❯ swift repl
Welcome to Apple Swift version 5.9 (swiftlang-5.9.0.128.108 clang-1500.0.40.1).
Type :help for assistance.
  1> import Foundation
  2> let decimal = NSDecimalNumber(value: 10.12)
  3. decimal.intValue
$R0: Int = -8
decimal: NSDecimalNumber = 10119999999999997952 x 10^-18

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants