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-5228] NSNumber casting to Float returns nil #4084

Open
swift-ci opened this issue Jun 15, 2017 · 8 comments
Open

[SR-5228] NSNumber casting to Float returns nil #4084

swift-ci opened this issue Jun 15, 2017 · 8 comments

Comments

@swift-ci
Copy link
Contributor

Previous ID SR-5228
Radar None
Original Reporter victor.kinvey (JIRA User)
Type Bug
Status Reopened
Resolution
Environment

Swift 4.1 / Xcode 9.3 (9E145)

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

md5: 5dcba46d886f9cd69d44dc9229cac424

duplicates:

  • SR-5179 NSNumber -> Float bridging in Swift 3.2 is not backwards-compatible

Issue Description:

import Foundation

print(NSNumber(value: 27.6) as? Double)
print(NSNumber(value: 27.6) as? Float)

and here is the output

Optional(27.600000000000001)
nil
@swift-ci
Copy link
Contributor Author

swift-ci commented Apr 6, 2018

Comment by Olivier Paillard (JIRA)

I just encountered the same bug with the latest version of Swift/Xcode (Swift 4.1 with Xcode 9.3) released last week.

(all was fine with Swift 4.0 / Xcode 9.2)

@Nef10
Copy link

Nef10 commented Apr 17, 2018

@phausler @natecook1000 any idea on this?

@phausler
Copy link
Member

26.7 does not convert to Float losslessly so it fails the litmus of the cast of being able to be represented “safely”. This is similar to the concept of Int64.max not being able to be represented as Int32

@Nef10
Copy link

Nef10 commented Apr 17, 2018

So this behaviour changed on purpose from Swift 4.0 to Swift 4.1? Is this anywhere noted?

@swift-ci
Copy link
Contributor Author

Comment by Mark Sands (JIRA)

This is really unexpected and has caused a lot of subtle bugs. It would have been nice to more clearly communicate this in release notes. This legacy code works in Xcode 9.3 but silently fails in Xcode 9.4:

let jsonDict: [String: Any] = ["price": 2.18]

let data = try! JSONSerialization.data(withJSONObject: jsonDict, options: [])

let json = try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]

json["price"] as? Float? // 2.18 or nil depending on the version of Swift

@swift-ci
Copy link
Contributor Author

Comment by Mark Sands (JIRA)

(lldb) po type(of: json[“price”])

__NSCFNumber

@swift-ci
Copy link
Contributor Author

Comment by Olivier Paillard (JIRA)

Actually I realized this problem using `JSONSerialization` too.

Surprisingly by using `Codable` protocol for my objects and `JSON[En,De]coder` instead of `JSONSerialization`, it solved my issue (about conversion to `Float`).

I deduce that the casting is not implemented the same way in the `JSONDecoder` black box.

@swift-ci
Copy link
Contributor Author

Comment by Philipp Weber (JIRA)

Also stumbled across this error a few days ago in our app, though in our case it only appears on 32bit devices, in our case the iPod touch 5th gen.

Our code is like this:

//json : [String Any]

quality.skillScore = json["skillScore"] as? CGFloat ?? 0.0

Values in this JSON lie between 0.0 and 1.0.

When a value of, let's say 0.975 is the value for skillScore, the above conditional cast fails on 32bit systems and the default of 0.0 is set for skillScore.

When checking for the type, Swift determines the type of json["skillScore"] to be a Double, which is correct. But since CGFloat's nativeType on 32bit is Float, the cast fails.

This code used to work in Swift 4.0.3, but seems to have regressed in 4.1

I will most likely remedy this by changing the type of quality.skillScore to be a Double and convert to CGFloat when needed for drawing code.

@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
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

3 participants