Skip to content

Commit fdcaa06

Browse files
simeonschaubrfourquet
authored andcommitted
check for typemin(T) in denominator of rational (#32572)
1 parent 56d75f7 commit fdcaa06

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

base/rational.jl

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,18 @@ struct Rational{T<:Integer} <: Real
1111
den::T
1212

1313
function Rational{T}(num::Integer, den::Integer) where T<:Integer
14-
num == den == zero(T) && __throw_rational_argerror(T)
15-
num2, den2 = signbit(den) ? divgcd(-num, -den) : divgcd(num, den)
16-
new(num2, den2)
14+
num == den == zero(T) && __throw_rational_argerror_zero(T)
15+
num2, den2 = divgcd(num, den)
16+
if T<:Signed && signbit(den2)
17+
den2 = -den2
18+
signbit(den2) && __throw_rational_argerror_typemin(T)
19+
num2 = -num2
20+
end
21+
return new(num2, den2)
1722
end
1823
end
19-
@noinline __throw_rational_argerror(T) = throw(ArgumentError("invalid rational: zero($T)//zero($T)"))
24+
@noinline __throw_rational_argerror_zero(T) = throw(ArgumentError("invalid rational: zero($T)//zero($T)"))
25+
@noinline __throw_rational_argerror_typemin(T) = throw(ArgumentError("invalid rational: denominator can't be typemin($T)"))
2026

2127
Rational(n::T, d::T) where {T<:Integer} = Rational{T}(n,d)
2228
Rational(n::Integer, d::Integer) = Rational(promote(n,d)...)

test/rational.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ using Test
3232
@test_throws ArgumentError rationalize(Int, big(3.0), -1.)
3333
# issue 26823
3434
@test_throws InexactError rationalize(Int, NaN)
35+
# issue 32569
36+
@test_throws ArgumentError 1 // typemin(Int)
37+
@test -2 // typemin(Int) == -1 // (typemin(Int) >> 1)
38+
@test 2 // typemin(Int) == 1 // (typemin(Int) >> 1)
3539

3640
for a = -5:5, b = -5:5
3741
if a == b == 0; continue; end

0 commit comments

Comments
 (0)