Julia 为什么不能使用范围数组正确迭代这些值?

Julia 为什么不能使用范围数组正确迭代这些值?,julia,Julia,我遇到了这个问题 julia> Tinit = 0.0 0.0 julia> for ii in 1:10 timeinterval = Tinit:0.05:(Tinit + 0.05) println(Tinit + 0.05) for item in timeinterval println("+++++++++ ", item) end

我遇到了这个问题

julia> Tinit = 0.0
    0.0  

julia> for ii in 1:10
           timeinterval = Tinit:0.05:(Tinit + 0.05)
           println(Tinit + 0.05)
           for item in timeinterval
                   println("+++++++++ ", item)
           end
           Tinit = timeinterval[end]
       end

出于某种奇怪的原因,我无法获得大于
0.15

的值。您在浮点运算中遇到了一个经典问题:

julia> 0.05 + 0.05
0.1

julia> 0.05 + 0.05 + 0.05
0.15000000000000002

julia> 0.05 + 0.05 + 0.05 + 0.05
0.2
所以您的第一个问题是
0.1+0.5==0.150000000000002>0.15
。看见所以你没有得到你希望得到的确切数字。您遇到的第二个问题是,您正在从中构建一个范围:

julia> r = 0.15000000000000002:0.05:0.2
0.15000000000000002:0.05:0.15000000000000002

julia> length(r)
1

julia> r[end]
0.15000000000000002
什么?!?为什么?发生这种情况是因为您的起点比您预期的要大(您的终点也比您预期的要大,但并不显著:
0.2==2.000000000000000 111022302462565404236316680908203125
)。特别要注意的是

julia> (0.2-0.15000000000000002)/0.05
0.9999999999999998
换句话说,您正在构建的范围不够大,无法包含两个点。然而,情况也是如此:

julia> 0.15000000000000002 + 0.05
0.2
可以论证的是,如果您可以添加步骤
n
次数并准确地到达终点,那么范围应该包括该终点,因此这可能被视为一个bug(问题字段:)。但是,我相当肯定,我们可以找到其他情况,在这些情况下,您的算法将积累足够的浮点错误而导致失败

有几种可能的解决方案:

1) 不要做绝对浮点计算而不是迭代计算。例如,可以将范围表示为
(0:0.05:0.05)+Tinit+(ii-1)*0.05

julia> Tinit = 0.0; for ii in 1:10
           println(Tinit + (ii-1)*0.05 + (0:0.05:0.05))
       end
0.0:0.05:0.05
0.05:0.05:0.1
0.1:0.05:0.15
0.15000000000000002:0.05:0.2
0.2:0.05:0.25
0.25:0.05:0.3
0.30000000000000004:0.05:0.35000000000000003
0.35000000000000003:0.05:0.4
0.4:0.05:0.45
0.45:0.05:0.5
正如您所看到的,这并没有完全解决浮点错误问题,但是错误不会在一次迭代到下一次迭代中累积

2) 使用精确的整数算术,除以100或任何除数,将计算降低到最接近的可表示浮点值。由于浮点只能用于表示,而不是核心计算,因此核心计算将是正确的,并且不会累积错误

julia> Tinit = 0.0; for ii in 1:10
           println((Tinit+(ii-1)*5)/100:0.5:(Tinit+ii*5)/100)
       end
0.0:0.5:0.0
0.05:0.5:0.05
0.1:0.5:0.1
0.15:0.5:0.15
0.2:0.5:0.2
0.25:0.5:0.25
0.3:0.5:0.3
0.35:0.5:0.35
0.4:0.5:0.4
0.45:0.5:0.45
如您所见,这实际上完全消除了不精确问题