我知道浮点精度存在一些问题,但我不明白这个:
将
9138497.986
存储为 Float()
时,它似乎 被截断为“9138497”。有人能解释一下为什么吗?
强制打印 3 个小数位给出“9138497.000”
示例:
Float.greatestFiniteMagnitude
// 3.402823e+38
let f1 = Float(9138497.986)
String(format: "%.3f", f1)
// "9138498.000 <-- Why is this happening?
// divide by 10 to show decimals
let f2 = Float(9138497.986 / 10.0)
String(format: "%.3f", f2)
// 913849.812
// `Double` is fine
let d1 = Double(9138497.986)
String(format: "%.3f", d1)
// "9138497.986
// I found this when using `SCNVector3()`, which uses `Float` internally
import SceneKit
let v = SCNVector3(216877.354, 9138497.986, 2878.604)
v
// x: 216877.4, y: 9138498, z: 2878.604
A
Float
是一个 32 位浮点数。它的指数为 8 位,有效位为 23 位。这将为您提供 24 位二进制位的精度(包括隐含的前导 1)。这相当于略多于七位小数,而您的数字在浮点之前有七位小数。简而言之,完整的精度无法容纳在 Float
中
这里有一些代码证实了这一点:
let f1 = Float(9138497.986)
print(f1.nextUp) // The next bigger representable Float
print(f1.nextDown) // The next smaller representable Float
print(f1.ulp) // The gap between Floats at this magnitude
打印出来
9138499.0
9138497.0
1.0