在Swift 4中使用stride有时会导致错误的结果,这段代码说明了这一点:
import UIKit
import PlaygroundSupport
struct Demo {
let omegaMax = 10.0
let omegaC = 1.0
var omegaSignal:Double {get {return 0.1 * omegaC}}
var dOmega:Double {get {return 0.1 * omegaSignal}}
var omegaArray:[Double] {get {return Array(stride(from: 0.0, through: omegaMax, by: dOmega))}}
变量dOmega的值预计为0.001。
数组的大小预计为1001个元素,
其中最后一个元素的值应为10.0
但是,正如您在下面的代码部分中看到的,这些假设是不正确的:
let demo = Demo()
let nbrOfElements = demo.omegaArray.count
let lastElement = demo.omegaArray[nbrOfElements-1]
print("\(nbrOfElements)") // -> 1000
print("\(lastElement)") // -> 9.990000000000002
怎么回事?检查多梅加给出了答案。
print("\(demo.dOmega)") // -> 0.010000000000000002
增量值DOMEGA不完全如预期的0.01,但具有非常小的近似误差,对于双精度来说是可以的。然而,这导致了这样的情况,即期望的数组元素1001将具有值10.000000000000002,其大于给定的最大值10,因此不生成该元素1001。
根据stride函数中的变量是否有舍入错误,结果是预期的结果。
我的问题是:在任何情况下,什么是正确的方法来使用跨步和双打来获得预期的结果?
最佳答案
您使用了错误的stride
过载!
有两个重载:stride(from:to:by:)
stride(from:through:by:)
您应该使用第二个参数,因为它包含参数through
,而第一个参数不包含参数to
。
print(Array(stride(from: 0, through: 10.0, by: 0.001)).last!) // 10.0
你所看到的小差别仅仅是因为imprecise nature of
Double
。关于swift - swift 与 double 大步前进并不可靠,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54721856/