objective-cswiftnsnumberbridging

Swift Unable to bridge NSNumber to Float


So I have a NSArrays loaded with for pitch and yaw values saved on a Shot object.

@interface Shot : NSObject
@property (strong, nonatomic) NSArray *pitch;
@property (strong, nonatomic) NSArray *yaw;

I am trying to do some number crunching in swift and running into a very weird problem:

let pitch = Array(shot.recoil_pitch[0..<10]) as! [Float]
let yaw = Array(shot.recoil_yaw[0..<10]) as! [Float]

For some reason that I can't figure out, the first line runs fine. The second line, however, throws a Fatal error: Unable to bridge NSNumber to Float.

When I inspect shot.recoil_pitch[0..<10] in the debugger I get:

- 0 : 0
- 1 : -0.1355667114257812
- 2 : -2.584976196289062
- 3 : -2.238974571228027
- 4 : -1.606719017028809
- 5 : -1.54025936126709
- 6 : -1.570234298706055
- 7 : -1.544057846069336
- 8 : -1.323789596557617
- 9 : -1.073002815246582

and when I inspect the shot.recoil_yaw[0..<10] I get:

- 0 : 0
- 1 : 0.017406463623046875
- 2 : -0.07871246337890625
- 3 : 0.004611968994140625
- 4 : 0.0446014404296875
- 5 : -0.0008544921875
- 6 : 0.010448455810546875
- 7 : 0.01015472412109375
- 8 : -0.002346038818359375
- 9 : -0.0569610595703125

Any ideas on why I might be getting this error?


Solution

  • I am able to reproduce this problem with this simple example:

    var arr = [NSNumber(value: 1.3 as Float), NSNumber(value: 2.7)]
    
    // This works
    let x = arr.map { $0.floatValue }
    print(x)
    
    [1.3, 2.7]
    
    // This fails with error 'Fatal error: Unable to bridge NSNumber to Float'
    let y = arr as! [Float]
    print(y)
    

    As explained in the duplicate's answer, you can't cast an NSNumber to Float if the cast doesn't preserve the exact value. Double(2.7) loses precision when converted to Float, so the cast fails. Had I chosen 2.5 instead of 2.7 for the Double, the cast would have worked.

    Accessing the value with .floatValue works because it uses the property of NSNumber to produce the Float value.