Swift 小浮点值的数学运算
Swift Math Operations on small Float Values
我正在 运行ning 一个 for 循环,如下所示:
for var i: Float = 1.000; i > 0; i -= 0.005 {
println(i)
}
并且我发现在 i
下降超过某个值而不是恰好下降 0.005
之后,它下降的幅度略小于 0.005
,因此当它达到了 201 次迭代,i
不是 0
而是无限接近 0
的东西,因此 for
循环 运行s。输出结果如下:
1.0
0.995
0.99
0.985
...
0.48
0.475001
0.470001
...
0.0100008 // should be 0.01
0.00500081 // should 0.005
8.12113e-07 // should be 0
我的问题是,首先,为什么会发生这种情况,其次,我该怎么做才能使 i
总是减少 0.005
,这样循环就不会 运行 在第 201 次迭代中?
非常感谢,
比格列罗
Swift 浮点数 documentation 状态:
Note
Double has a precision of at least 15 decimal digits, whereas the precision of Float can be as little as 6 decimal digits. The appropriate floating-point type to use depends on the nature and range of values you need to work with in your code. In situations where either type would be appropriate, Double is preferred.
在这种情况下,根据 200 次减法后剩余的数量,看起来每次减法的误差大约为 4.060564999999999e-09
。事实上,将 Float 更改为 Double 会降低精度,使得循环 运行s 直到 i = 0.00499999999999918
而它应该是 0.005
.
这一切都很好,但是我们仍然有构建一个循环的问题,该循环将 运行 直到 i
变为零。如果您减少 i
的数量在整个循环中保持不变,一个稍微不幸的解决方法是:
var x: Double = 1
let reduction = 0.005
for var i = Int(x/reduction); i >= 0; i -= 1, x = Double(i) * reduction {
println(x)
}
在这种情况下,您的错误不会复合,因为我们使用整数来索引我们需要多少减少才能达到当前 x
,因此与循环的长度无关。
我正在 运行ning 一个 for 循环,如下所示:
for var i: Float = 1.000; i > 0; i -= 0.005 {
println(i)
}
并且我发现在 i
下降超过某个值而不是恰好下降 0.005
之后,它下降的幅度略小于 0.005
,因此当它达到了 201 次迭代,i
不是 0
而是无限接近 0
的东西,因此 for
循环 运行s。输出结果如下:
1.0
0.995
0.99
0.985
...
0.48
0.475001
0.470001
...
0.0100008 // should be 0.01
0.00500081 // should 0.005
8.12113e-07 // should be 0
我的问题是,首先,为什么会发生这种情况,其次,我该怎么做才能使 i
总是减少 0.005
,这样循环就不会 运行 在第 201 次迭代中?
非常感谢,
比格列罗
Swift 浮点数 documentation 状态:
Note
Double has a precision of at least 15 decimal digits, whereas the precision of Float can be as little as 6 decimal digits. The appropriate floating-point type to use depends on the nature and range of values you need to work with in your code. In situations where either type would be appropriate, Double is preferred.
在这种情况下,根据 200 次减法后剩余的数量,看起来每次减法的误差大约为 4.060564999999999e-09
。事实上,将 Float 更改为 Double 会降低精度,使得循环 运行s 直到 i = 0.00499999999999918
而它应该是 0.005
.
这一切都很好,但是我们仍然有构建一个循环的问题,该循环将 运行 直到 i
变为零。如果您减少 i
的数量在整个循环中保持不变,一个稍微不幸的解决方法是:
var x: Double = 1
let reduction = 0.005
for var i = Int(x/reduction); i >= 0; i -= 1, x = Double(i) * reduction {
println(x)
}
在这种情况下,您的错误不会复合,因为我们使用整数来索引我们需要多少减少才能达到当前 x
,因此与循环的长度无关。