Skip to content

intersect(::StepRange, ::StepRange) silently overflows producing strange incorrect answers #47577

@LilithHafner

Description

@LilithHafner
julia> a, b = StepRange{Int8, Int8}.((-56:121:-56, 35:62:34))
(-56:121:-56, 35:62:34)

julia> intersect(a,b)
-56:121:65

julia> collect(a), collect(b), collect(intersect(a, b))
(Int8[-56], Int8[], Int8[-56, 65])

julia> invoke(intersect, Tuple{AbstractArray, AbstractArray}, a, b)
Int8[]

Behavior is identical on 1.8 & master.

I believe the bug is here in range.jl

function intersect(r::StepRange, s::StepRange)
    T = promote_type(eltype(r), eltype(s))
    S = promote_type(typeof(step(r)), typeof(step(s)))
    if isempty(r) || isempty(s)
        return StepRange{T,S}(first(r), step(r), first(r)-step(r))
    end

    start1, step1, stop1 = first_step_last_ascending(r)
    start2, step2, stop2 = first_step_last_ascending(s)
    a = lcm(step1, step2)    ###   <-----------   overflow here is more common and errors rather than giving wrong results

    g, x, y = gcdx(step1, step2)

    if !iszero(rem(start1 - start2, g))
        # Unaligned, no overlap possible.
        if  step(r) < zero(step(r))
            return StepRange{T,S}(stop1, -a, stop1+a)
        else
            return StepRange{T,S}(start1, a, start1-a)
        end
    end

    z = div(start1 - start2, g)
    b = start1 - x * z * step1    ###   <---------------------------- overflow at this line is silent
    # Possible points of the intersection of r and s are
    # ..., b-2a, b-a, b, b+a, b+2a, ...
    # Determine where in the sequence to start and stop.
    m = max(start1 + mod(b - start1, a), start2 + mod(b - start2, a))
    n = min(stop1 - mod(stop1 - b, a), stop2 - mod(stop2 - b, a))
    step(r) < zero(step(r)) ? StepRange{T,S}(n, -a, m) : StepRange{T,S}(m, a, n)
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIndicates an unexpected problem or unintended behaviorcorrectness bug ⚠Bugs that are likely to lead to incorrect results in user code without throwingmathsMathematical functionsrangesEverything AbstractRange

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions