1

在 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。根据跨步函数中的变量是否存在舍入误差,结果是否为预期值。

我的问题是:在任何情况下使用双打的步幅来获得预期结果的正确方法是什么?

4

1 回答 1

1

您使用了错误的重载stride

有两个重载:

您应该使用第二个,因为它包含参数through,而第一个不包含参数to

print(Array(stride(from: 0, through: 10.0, by: 0.001)).last!) // 10.0

您看到的微小差异只是因为Double.

于 2019-02-16T10:05:15.920 回答