Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

check for typemin(T) in denominator of rational #32572

Merged
merged 9 commits into from
Dec 17, 2019
14 changes: 10 additions & 4 deletions base/rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@ struct Rational{T<:Integer} <: Real
den::T

function Rational{T}(num::Integer, den::Integer) where T<:Integer
num == den == zero(T) && __throw_rational_argerror(T)
num2, den2 = signbit(den) ? divgcd(-num, -den) : divgcd(num, den)
new(num2, den2)
num == den == zero(T) && __throw_rational_argerror_zero(T)
num2, den2 = divgcd(num, den)
if T<:Signed && signbit(den2)
den2 = -den2
signbit(den2) && __throw_rational_argerror_typemin(T)
num2 = -num2
end
return new(num2, den2)
end
end
@noinline __throw_rational_argerror(T) = throw(ArgumentError("invalid rational: zero($T)//zero($T)"))
@noinline __throw_rational_argerror_zero(T) = throw(ArgumentError("invalid rational: zero($T)//zero($T)"))
@noinline __throw_rational_argerror_typemin(T) = throw(ArgumentError("invalid rational: denominator can't be typemin($T)"))

Rational(n::T, d::T) where {T<:Integer} = Rational{T}(n,d)
Rational(n::Integer, d::Integer) = Rational(promote(n,d)...)
Expand Down
4 changes: 4 additions & 0 deletions test/rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ using Test
@test_throws ArgumentError rationalize(Int, big(3.0), -1.)
# issue 26823
@test_throws InexactError rationalize(Int, NaN)
# issue 32569
@test_throws ArgumentError 1 // typemin(Int)
@test -2 // typemin(Int) == -1 // (typemin(Int) >> 1)
@test 2 // typemin(Int) == 1 // (typemin(Int) >> 1)

for a = -5:5, b = -5:5
if a == b == 0; continue; end
Expand Down