我正在尝试找到一种在Swift中将Float
或Double
转换为Int
的可靠方法。当出现溢出时,我遇到了问题。
我们来看下面的例子:
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)
}
打印哪些:
Int.max is : 9223372036854775807
double value is : 9223372036854775808.000000
Double(Int.max) is : 9223372036854775808.000000
Warning : double is too big for int !
这种方法非常麻烦。此外,您可能已经注意到我测试了double >= Double(Int.max)
而不是double > Double(Int.max)
。那是因为Double(Int.max)
实际上等于Int.max + 1
因为四舍五入。对于32位架构,我的代码可能必须不同。
还有另外一种方法吗?就像我可能错过的可用初始化程序或更好,可移植的方法来做到这一点?
答案 0 :(得分:2)
您可以通过为Int
创建自己的可用初始化程序来扩展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