Skip to content

Commit aa4cd70

Browse files
nhz2nsajko
andauthored
Avoid silent overflow in /(x::Rational, y::Complex{Int}) (#53453)
This change catches the overflow in ```julia (Int8(1)//Int8(1)) / (Int8(100) + Int8(100)im) ``` instead of incorrectly returning ```julia 25//8 - 25//8*im ``` This PR removes some of the specific `/` methods that involve complex rationals in `rational.jl`. The default methods in `complex.jl` have better promotion rules and edge case checking. This includes the checks added in #32050, fixing #23134 for rational numbers. The previous dispatch to `//` ignored overflow errors (see #53435), but would return the correct answer if the numerator was zero even if the denominator would overflow. --------- Co-authored-by: Neven Sajko <[email protected]>
1 parent 087a9e5 commit aa4cd70

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

base/rational.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,8 +421,8 @@ function *(x::Bool, y::T)::promote_type(Bool,T) where T<:Rational
421421
return ifelse(x, y, copysign(zero(y), y))
422422
end
423423
*(y::Rational, x::Bool) = x * y
424-
/(x::Rational, y::Union{Rational, Integer, Complex{<:Union{Integer,Rational}}}) = x//y
425-
/(x::Union{Integer, Complex{<:Union{Integer,Rational}}}, y::Rational) = x//y
424+
/(x::Rational, y::Union{Rational, Integer}) = x//y
425+
/(x::Integer, y::Rational) = x//y
426426
inv(x::Rational{T}) where {T} = checked_den(x.den, x.num)
427427

428428
fma(x::Rational, y::Rational, z::Rational) = x*y+z

test/rational.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,21 @@ end
203203
end
204204

205205
@test Rational(rand_int, 3)/Complex(3, 2) == Complex(Rational(rand_int, 13), -Rational(rand_int*2, 39))
206+
@test (1//1) / complex(0, 1) === 0//1 - 1//1*im
207+
@test (0//1) / complex(0, 1) === 0//1 + 0//1*im
208+
@test (0//1) / complex(1, 0) === 0//1 + 0//1*im
209+
@test (0//1) / complex(1, 1) === 0//1 + 0//1*im
210+
@test (1//1) / complex(1, 1) === 1//2 - 1//2*im
211+
@test (0//1) / complex(1//1, 1//1) === 0//1 + 0//1*im
212+
@test (1//1) / complex(1//1, 1//1) === 1//2 - 1//2*im
213+
@test (0//1) / complex(1//0, 0//1) === 0//1 + 0//1*im
214+
@test (1//1) / complex(1//1, 1//0) === 0//1 + 0//1*im
215+
@test_throws DivideError (0//1) / complex(0, 0)
216+
@test_throws DivideError (1//1) / complex(0, 0)
217+
@test_throws DivideError (1//0) / complex(0, 0)
218+
219+
# 1//200 - 1//200*im cannot be represented as Complex{Rational{Int8}}
220+
@test_throws OverflowError (Int8(1)//Int8(1)) / (Int8(100) + Int8(100)im)
206221

207222
@test Complex(rand_int, 0) == Rational(rand_int)
208223
@test Rational(rand_int) == Complex(rand_int, 0)

0 commit comments

Comments
 (0)