Julia: Iteration over `typemin(Uint64):typemax(Uint64)` stops immediately and silently.

Created on 18 Jun 2015  路  11Comments  路  Source: JuliaLang/julia

This may be a corner case and unrealistic, but throwing an error like length(typemin(Uint64):typemax(Uint64)) would be nice at least.

julia> for x in typemin(Uint64):typemax(Uint64); println(x); end

julia> versioninfo()
Julia Version 0.4.0-dev+5437
Commit 0bd3554 (2015-06-18 02:27 UTC)
Platform Info:
  System: Darwin (x86_64-apple-darwin14.3.0)
  CPU: Intel(R) Core(TM) i5-4288U CPU @ 2.60GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: libopenblas
  LIBM: libopenlibm
  LLVM: libLLVM-3.3

Most helpful comment

This issue is closed by #27147

All 11 comments

This is because done returns true for the first value due to overflow:

done(r::UnitRange, i) = i==oftype(i,r.stop)+1

also note that indexing doesn't work:

julia> a=typemin(Uint64):typemax(Uint64)
0x0000000000000000:0xffffffffffffffff

julia> a[100]
ERROR: OverflowError()
 in getindex at range.jl:350

I think this is the case for all integer types, signed and unsigned. And a lot of functions are in fact affected by this.

Some mentions before https://github.com/JuliaLang/julia/issues/5585, https://github.com/JuliaLang/julia/issues/3079, https://github.com/JuliaLang/julia/issues/10554#issuecomment-83017906, https://github.com/JuliaLang/julia/issues/5550,

Does changing this to !(i <= oftype(i,r.stop) fix this particular case? Of course, it might fail for some other case 鈥撀爐his range code is a whack-a-mole game with corner cases.

Actually, I guess that could just be i > oftype(i,r.stop).

@mauro3 I think this only applies to Int and larger types. The getindex issue can probably be fixed, but iteration is harder. OTOH, typemax(UInt64)/(4 GHz) is 146 years, so typemin(UInt64):typemax(UInt64) is basically an infinite loop. You might want that behavior (e.g. because you plan to break out of the loop) but in general it's a pretty minor annoyance. I'm not sure there's a solution that doesn't slow down more common cases.

@StefanKarpinski I think that makes iterating over any range that ends with typemax(UInt64) an infinite loop, which would be fine for this case because the loop really isn't going to terminate in any reasonable amount of time, but not for typemax(UInt64)-1:typemax(UInt64). Also, I vaguely remember that if the loop is not guaranteed to terminate, then LLVM won't compute a trip count and won't vectorize it even when it is safe to do so without @simd.

ranges are bananas

@simonster no wonder my test cases didn't terminate!

Would it be an idea to check at range creation that it actually can work?

This definitely feels like deja vu. I thought this was discussed in the last range overhaul.

This was discussed in #5585 (e.g. https://github.com/JuliaLang/julia/issues/5585#issuecomment-33722481) but I don't think we came up with a solution that didn't sacrifice performance.

Even checking at creation has a bit of cost, since we want range creation to be basically free. (And the LLVMPolly people would like it to be even simpler than it is now.) But that seems like the best place to do this. Alternatively we could wait for #18823 and do that check in the single-argument step call.

This issue is closed by #27147

Was this page helpful?
0 / 5 - 0 ratings