deadbeef - 6 months ago 32

Swift Question

I'm trying to find a reliable way to convert a

`Float`

`Double`

`Int`

Let's take the following example:

`let double = 9223372036854775807.0 // This is 2^63 - 1 (aka Int.max on 64 bits architecture)`

print("Int.max is : \(Int.max)")

print(String(format: "double value is : %f", double))

print(String(format: "Double(Int.max) is : %f", Double(Int.max)))

let int: Int

if (double >= Double(Int.max)) {

print("Warning : double is too big for int !")

int = Int.max

} else {

int = Int(double)

}

Which prints:

`Int.max is : 9223372036854775807`

double value is : 9223372036854775808.000000

Double(Int.max) is : 9223372036854775808.000000

Warning : double is too big for int !

This approach is very cumbersome. Besides, you probably noticed that I test for

`double >= Double(Int.max)`

`double > Double(Int.max)`

`Double(Int.max)`

`Int.max + 1`

So is there another way? Like a failable initializer that I would have missed or a better, portable way to do this?

Answer

You can extend `Int`

by creating your own failable initializer for `Double`

:

```
extension Int {
init?(double: Double) {
if double >= Double(Int.max) || double < Double(Int.min) || double.isNaN || double.isInfinite {
return nil
} else {
self = Int(double)
}
}
}
if let i = Int(double: 17) {
print(i)
} else {
print("nil")
}
// It also handles NaN and Infinite
let nan = sqrt(-1.0)
let inf = 1e1000
Int(double: nan) // nil
Int(double: inf) // nil
```