This is a consequence of SE-0170 NSNumber bridging and Numeric types, implemented in Swift 4:
NSNumbershould mean “Can I safely express the value stored in this opaque box called a NSNumber as the value I want?”.
1.12 is a floating point literal, and inferred as a
NSNumber(value: 1.12) is “boxing” the 64-bit floating point value
1.12. Converting that to a 32-bit
Float does not
preserve this value:
let n = NSNumber(value: 1.12) let x = Float(truncating: n) // Or: let x = n.floatValue let nn = NSNumber(value: x) print(n == nn) // false
On the other hand,
1.0 can be represented exactly as a
let m = NSNumber(value: 1.0) let y = m.floatValue let mm = NSNumber(value: y) print(m == mm) // true
and that is why casting
m as? Float succeeds. Both
n.floatValue Float(truncating: n)
can be used to ”truncate” the number to the closest representable
32-bit floating point value.