Stride() excludes the "through" value in some cases, when using Double

153 views Asked by At

I ran into a strange problem, which I want to understand background of:

func printIntervals(_ colors: Int) {
    let start = 0.4 - (Double(colors) - 1) / 10
    print("start: \(start)")
    for i in stride(from: start, through: 0.4, by: 0.1) { print ("i:\(i)")}
}

printIntervals(1)
printIntervals(2)
printIntervals(3)
printIntervals(4)
printIntervals(5)
printIntervals(6)
printIntervals(7)
printIntervals(8)

Gives me this output:

colors: 1 start: 0.4
i:0.4
colors: 2 start: 0.3
i:0.3
i:0.4
colors: 3 start: 0.2
i:0.2
i:0.3
i:0.4
colors: 4 start: 0.1
i:0.1
i:0.2
i:0.3
colors: 5 start: 0.0
i:0.0
i:0.1
i:0.2
i:0.3
i:0.4
colors: 6 start: -0.1
i:-0.1
i:2.77555756156289e-17
i:0.1
i:0.2
i:0.3
i:0.4
colors: 7 start: -0.2
i:-0.2
i:-0.1
i:5.55111512312578e-17
i:0.1
i:0.2
i:0.3
colors: 8 start: -0.3
i:-0.3
i:-0.2
i:-0.0999999999999999
i:1.11022302462516e-16
i:0.1
i:0.2
i:0.3

As you can see, some function calls will include the 0.4 value an others won't... My quick workaround is to make the stride end at 0.41 instead, so it's definitely a precision issue.

But if the previous value is printed as 0.3 (not 0.300001), why would it skip 0.4 when incrementing by 0.1? And why does it only happen in some cases - but consistently?

0

There are 0 answers