diff --git a/base/complex.jl b/base/complex.jl index 0d985dd49155c..eb5dbb2fbe629 100644 --- a/base/complex.jl +++ b/base/complex.jl @@ -351,19 +351,7 @@ muladd(z::Complex, w::Complex, x::Real) = Complex(muladd(real(z), real(w), -muladd(imag(z), imag(w), -x)), muladd(real(z), imag(w), imag(z) * real(w))) -function /(a::R, z::S) where {R<:Real, S<:Complex} - T = promote_type(R,S) - z_p = T(z) - if z_p isa Complex{<:Rational} - # avoid overflow if a is zero and z isn't zero - if iszero(z_p) - throw(DivideError()) - elseif iszero(a) - return a*inv(oneunit(z_p)) - end - end - a*inv(z_p) -end +/(a::R, z::S) where {R<:Real, S<:Complex} = (T = promote_type(R,S); a*inv(T(z))) /(z::Complex, x::Real) = Complex(real(z)/x, imag(z)/x) function /(a::Complex{T}, b::Complex{T}) where T<:Real diff --git a/base/rational.jl b/base/rational.jl index 6b54a409588d2..3736173cc3626 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -403,6 +403,18 @@ function *(y::Integer, x::Rational) end /(x::Rational, y::Union{Rational, Integer}) = x//y /(x::Integer, y::Rational) = x//y +# Avoid overflow for Rational math if result is zero. +# This method is needed because previously this method didn't check for overflows +# but would return the correct answer if `a` was zero even if 1//z was wrong. +function /(a::Rational, z::Complex{<:Integer}) + z_r = complex(Rational(real(z)), Rational(imag(z))) + if iszero(a) && !iszero(z) + a/oneunit(z_r) + else + a/z_r + end +end + inv(x::Rational) = checked_den(x.den, x.num) fma(x::Rational, y::Rational, z::Rational) = x*y+z diff --git a/test/rational.jl b/test/rational.jl index 548d3b9f0295e..59d21aede7fd6 100644 --- a/test/rational.jl +++ b/test/rational.jl @@ -203,15 +203,19 @@ end end @test Rational(rand_int, 3)/Complex(3, 2) == Complex(Rational(rand_int, 13), -Rational(rand_int*2, 39)) - @test iszero(zero(Rational{Int8}) / complex(Rational{Int8}(100), Rational{Int8}(100))) - @test iszero(zero(Int8) / complex(Rational{Int8}(100), Rational{Int8}(100))) @test iszero(zero(Rational{Int8}) / complex(Int8(100), Int8(100))) + @test (true//true) / complex(false, true) === 0//1 - 1//1*im + @test (false//true) / complex(false, true) === 0//1 + 0//1*im + @test (false//true) / complex(true, false) === 0//1 + 0//1*im @test (false//true) / complex(true, true) === 0//1 + 0//1*im @test (true//true) / complex(true, true) === 1//2 - 1//2*im @test (false//true) / complex(true//true, true//true) === 0//1 + 0//1*im @test (true//true) / complex(true//true, true//true) === 1//2 - 1//2*im @test (false//true) / complex(true//false, false//true) === 0//1 + 0//1*im @test (true//true) / complex(true//true, true//false) === 0//1 + 0//1*im + @test_throws DivideError (0//1) / complex(0, 0) + @test_throws DivideError (1//1) / complex(0, 0) + @test_throws DivideError (1//0) / complex(0, 0) # 1//200 - 1//200*im cannot be represented as Complex{Rational{Int8}} @test_throws OverflowError (Int8(1)//Int8(1)) / (Int8(100) + Int8(100)im)