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

Avoid silent overflow in /(x::Rational, y::Complex{Int}) #53453

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
6 changes: 3 additions & 3 deletions base/rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -408,9 +408,9 @@ function *(y::Integer, x::Rational)
yn, xd = divgcd(promote(y, x.den)...)
unsafe_rational(checked_mul(yn, x.num), xd)
end
/(x::Rational, y::Union{Rational, Integer, Complex{<:Union{Integer,Rational}}}) = x//y
/(x::Union{Integer, Complex{<:Union{Integer,Rational}}}, y::Rational) = x//y
inv(x::Rational{T}) where {T} = checked_den(x.den, x.num)
/(x::Rational, y::Union{Rational, Integer}) = x//y
/(x::Integer, y::Rational) = x//y
inv(x::Rational) = checked_den(x.den, x.num)
nhz2 marked this conversation as resolved.
Show resolved Hide resolved

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

Expand Down
15 changes: 15 additions & 0 deletions test/rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,21 @@ end
end

@test Rational(rand_int, 3)/Complex(3, 2) == Complex(Rational(rand_int, 13), -Rational(rand_int*2, 39))
@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)
Copy link
Contributor

@nsajko nsajko Oct 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong. The correct result is positive infinity, just like here:

julia> (1 // 1) / 0
1//0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With complex numbers, there are many possible infinities, I'm not sure what infinity is correct.

julia> 1.0/(0.0im)
NaN + NaN*im

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, sorry.

@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)

@test Complex(rand_int, 0) == Rational(rand_int)
@test Rational(rand_int) == Complex(rand_int, 0)
Expand Down