为什么 Float 会截断 10 位数字?

问题描述 投票:0回答:1

我知道浮点精度存在一些问题,但我不明白这个:

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
swift floating-point
1个回答
0
投票

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
© www.soinside.com 2019 - 2024. All rights reserved.