在 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
那里发生了什么?检查 dOmega 给出了答案。
print("\(demo.dOmega)") // -> 0.010000000000000002
增量值 dOmega 并不像预期的那样精确为 0.01,但具有非常小的近似误差,这对于 Double 来说是可以的。然而,这会导致这样的情况,即预期的数组元素 1001 将具有值 10.000000000000002,该值大于给定的最大值 10.0,因此不会生成此元素 1001。根据跨步函数中的变量是否存在舍入误差,结果是否为预期值。
我的问题是:在任何情况下使用双打的步幅来获得预期结果的正确方法是什么?