Стрижи шагают с двойниками ненадежно - PullRequest
0 голосов
/ 16 февраля 2019

Использование шага со Swift 4 иногда приводит к неверным результатам, что демонстрируется этим фрагментом кода:

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 Array будет иметь значение 10.000000000000002, которое больше заданного максимального значения 10.0, и поэтому этот элемент 1001 не генерируется.В зависимости от того, имеют ли переменные в функции шага ошибки округления или нет, результат будет ожидаемым или нет.

Мой вопрос: как правильно использовать шаг с двойными значениями, чтобы в любом случае получить ожидаемый результат?результат?

1 Ответ

0 голосов
/ 16 февраля 2019

Вы используете неправильную перегрузку stride!

Существует две перегрузки:

Вы должны были использовать второй, потому что он включает параметр through, тогда как первый не включает параметр to.

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

Небольшая разница, которую вы видите, заключается только в неточной природе Double.

...