JuliaLang/julia — pull request #5065 by ggggggggg (2013-12-08 20:14:44+00:00)
Title: RFC: less overflows when constructing ranges

As noted in #3079 ranges can overflow easily because the length is stored as an Int. However some ranges that are currently capable of being represented still overflow due to the way range is calculated. This changes the math slightly when calculating the length of ranges to avoid integer overflows. It is slightly slower than the original behavior, but allows things like `1:4:typemax(Int)` to return the expected range.

previous behavior: `1:4:typemax(Int) = 1:4:-3`
new behavior: `1:4:typemax(Int) = 1:4:9223372036854775805`

This function takes about 7/6 as long to execute as the old version. I
tested with this code
```
function old_colon{T<:Integer}(start::T, step::T, stop::T)
step != 0 || error("step cannot be zero in colon syntax")
Range(start, step, max(0, div(stop-start+step, step)))
end

function new_colon{T<:Integer}(start::T, step::T, stop::T)
step != 0 || error("step cannot be zero in colon syntax")
len,rem = divrem(stop-start,step)
Range(start, step, max(0, len+div(rem+step,step)))
end

function range_test(f)
for start = -1000:1000, stop = start-1000:10:start+1000, step=-31:2:30
try
r=f(start,step,stop)
catch
error("$f failed on $start:$step:$stop")
end
end
end

@time range_test(old_colon);
@time range_test(new_colon);
```
output after multiple executions
```
julia> @time range_test(old_colon);
elapsed time: 3.064090887 seconds (607020720 bytes allocated)
julia> @time range_test(new_colon);
elapsed time: 3.493075716 seconds (607020720 bytes allocated)
```