Cast Any to Float Always Fails in Swift4.1

Swift: AnyObject cast to Float failed

The 0.6 is a Double literal value. As such, you can't cast it to Float (you need to convert it).

Try this instead:

let f = Float(json["progress"] as! Double)

Or, if you aren't really sure what type of number this AnyObject holds, the safer approach would be:

let f = (json["progress"] as! NSNumber).floatValue

Of course, those as! above will crash hard if the json value is missing or you misjudge the expected type. Use the as? operator instead if you feel otherwise :)


Casting crash course. When casting a known Double value to a Float, the compiler gives us a nice heads up about this:

let d = 0.6
let f = d as? Float

warning: cast from 'Double' to unrelated type 'Float' always fails

Unexpected behavior when casting an NSNumber to Float

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.

Casting problems after updating from Swift 4 to 4.1

Can you try

if let floatDoubleArray = response.result.value as? [[NSNumber]] { 

let floatArr = floatDoubleArray.map{$0.map{$0.floatValue}}

}

Unable to bridge NSNumber to Float Swift 3.3

As you have found, you may need to cast it first to NSNumber.

Something like this:

randomVariable = (jsonDict["jsonKey"] as? NSNumber)?.floatValue ?? 0

Maybe regex replacement would help you update your code.

Pattern: jsonDict\[([^\]]*)\] as\? Float

Replace with: (jsonDict[$1] as? NSNumber)?.floatValue

Implicit Any? to Any cast warning when passing Any? type variable in as Any? type parameter

Dictionary look ups return optional values because the key might not exist. In the case of a non-existent key, the look up returns nil, so the type of the dictionary look up has to be optional.

In your case, your values are of type Any?, so a look up from that dictionary returns a doubly wrapped optional Any??. So you are trying to pass a value of type Any?? to a function that takes Any?.

If you use optional binding to handle and unwrap the dictionary access, everything works:

let testDict : Dictionary<String, Any?> = ["Test": "Hello"];
if let value = testDict["Test"] {
// "Test" key is valid
someFunc(value);
}

Unable to bridge NSNumber to Float Swift 3.3

As you have found, you may need to cast it first to NSNumber.

Something like this:

randomVariable = (jsonDict["jsonKey"] as? NSNumber)?.floatValue ?? 0

Maybe regex replacement would help you update your code.

Pattern: jsonDict\[([^\]]*)\] as\? Float

Replace with: (jsonDict[$1] as? NSNumber)?.floatValue

Casting CGFloat to Float in Swift

You can use the Float() initializer:

let cgFloat: CGFloat = 3.14159
let someFloat = Float(cgFloat)

Convert Float to Int in Swift

You can convert Float to Int in Swift like this:

var myIntValue:Int = Int(myFloatValue)
println "My value is \(myIntValue)"

You can also achieve this result with @paulm's comment:

var myIntValue = Int(myFloatValue)


Related Topics



Leave a reply



Submit