【问题标题】:Conversion from Float to CGFloat in Swift在 Swift 中从 Float 转换为 CGFloat
【发布时间】:2018-10-12 06:57:24
【问题描述】:
我正在转换Float => CGFloat,它给了我以下结果。为什么它在转换后显示为“0.349999994039536”但与Double => CGFloat 一起工作正常?
let float: Float = 0.35
let cgFloat = CGFloat(float)
print(cgFloat)
// 0.349999994039536
let double: Double = 0.35
let cgFloat = CGFloat(double)
print(cgFloat)
// 0.35
【问题讨论】:
-
-
@Moritz:浮点运算不精确这一事实并不能单独解释为什么打印从 float 转换而来的 CGFloat 在打印从 double 转换而来的 CGFloat 时显示不准确才不是。完整的答案涉及所涉及的不同精度以及用于将浮点数转换为十进制数的算法。请不要随意关闭浮点问题作为that question 的重复项。
标签:
swift
floating-point
type-conversion
cgfloat
【解决方案1】:
将“.35”转换为float和将“.35”转换为double都会产生一个不同于0.35的值,因为浮点格式使用二进制基数,所以精确的数学值必须是使用 2 的幂(在这种情况下为 2 的负幂)近似。
因为float 格式使用较少的位,其结果不太精确,在这种情况下也不太准确。 float 的值为 0.3499999940395355224609375,double 的值为 0.34999999999999997779553950749686919152736663818359375。
我并不完全熟悉 Swift,但我怀疑它将 CGFloat 转换为十进制(使用默认选项)的算法类似于:
- 产生固定的十进制位数,将
CGFloat 的实际值正确舍入到位数,然后抑制任何尾随零。例如,如果精确的数学值是 0.34999999999999997...,并且格式使用 15 位有效数字,则中间结果为“0.350000000000000”,然后将其缩短为“0.35”。
float 和 double 的操作方式是:
- 当转换为
double 时,.35 变为 0.34999999999999997779553950749686919152736663818359375。使用上述方法打印时,结果为“0.35”。
- 当转换为
float 时,.35 变为 0.3499999940395355224609375。使用上述方法打印时,结果为“0.349999994039536”。
因此,float 和 double 值都不同于 .35,但打印格式没有使用足够的数字来显示 double 值的偏差,但它确实使用了足够的数字来显示float 值的偏差。