Swift 中的 Float 到 Int 转换失败
Failable Float to Int conversion in Swift
我正在尝试找到一种可靠的方法将 Float
或 Double
转换为 Swift 中的 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 位架构,我的代码可能必须有所不同。
那么还有别的办法吗?就像我会错过的失败初始化程序或更好、更便携的方法一样?
您可以通过为 Double
创建自己的可失败初始化程序来扩展 Int
:
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
我正在尝试找到一种可靠的方法将 Float
或 Double
转换为 Swift 中的 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 位架构,我的代码可能必须有所不同。
那么还有别的办法吗?就像我会错过的失败初始化程序或更好、更便携的方法一样?
您可以通过为 Double
创建自己的可失败初始化程序来扩展 Int
:
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