Unexpected behavior when casting an NSNumber to Float

前端 未结 1 556
一个人的身影
一个人的身影 2020-11-30 15:24

After upgrading to Xcode 9.3 (9E145) my App showed some unexpected behavior. It seems that the issue is with a cast of an NSNumber to a Float. I use the as type

相关标签:
1条回答
  • 2020-11-30 15:43

    This is a consequence of SE-0170 NSNumber bridging and Numeric types, implemented in Swift 4:

    as? for NSNumber should 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 Double, so NSNumber(value: 1.12) is “boxing” the 64-bit floating point value closest to 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 Float:

    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.

    0 讨论(0)
提交回复
热议问题