Skip to content

Commit

Permalink
Promote on Rational binary operations (#36279)
Browse files Browse the repository at this point in the history
  • Loading branch information
Liozou authored Jun 16, 2020
1 parent 772a40f commit 6c760d2
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 9 deletions.
18 changes: 9 additions & 9 deletions base/rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,16 @@ julia> (3 // 5) // (2 // 1)
//(n::Integer, d::Integer) = Rational(n,d)

function //(x::Rational, y::Integer)
xn, yn = divgcd(x.num,y)
xn, yn = divgcd(promote(x.num, y)...)
checked_den(xn, checked_mul(x.den, yn))
end
function //(x::Integer, y::Rational)
xn, yn = divgcd(x,y.num)
xn, yn = divgcd(promote(x, y.num)...)
checked_den(checked_mul(xn, y.den), yn)
end
function //(x::Rational, y::Rational)
xn,yn = divgcd(x.num,y.num)
xd,yd = divgcd(x.den,y.den)
xn,yn = divgcd(promote(x.num, y.num)...)
xd,yd = divgcd(promote(x.den, y.den)...)
checked_den(checked_mul(xn, yd), checked_mul(xd, yn))
end

Expand Down Expand Up @@ -280,7 +280,7 @@ end
for (op,chop) in ((:+,:checked_add), (:-,:checked_sub), (:rem,:rem), (:mod,:mod))
@eval begin
function ($op)(x::Rational, y::Rational)
xd, yd = divgcd(x.den, y.den)
xd, yd = divgcd(promote(x.den, y.den)...)
Rational(($chop)(checked_mul(x.num,yd), checked_mul(y.num,xd)), checked_mul(x.den,yd))
end

Expand All @@ -305,16 +305,16 @@ for (op,chop) in ((:rem,:rem), (:mod,:mod))
end

function *(x::Rational, y::Rational)
xn, yd = divgcd(x.num, y.den)
xd, yn = divgcd(x.den, y.num)
xn, yd = divgcd(promote(x.num, y.den)...)
xd, yn = divgcd(promote(x.den, y.num)...)
unsafe_rational(checked_mul(xn, yn), checked_mul(xd, yd))
end
function *(x::Rational, y::Integer)
xd, yn = divgcd(x.den, y)
xd, yn = divgcd(promote(x.den, y)...)
unsafe_rational(checked_mul(x.num, yn), xd)
end
function *(y::Integer, x::Rational)
yn, xd = divgcd(y, x.den)
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
Expand Down
19 changes: 19 additions & 0 deletions test/rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -575,3 +575,22 @@ end
@test -Int32(1) // typemax(Int32) - Int32(1) == typemin(Int32) // typemax(Int32)
@test 1 // (typemax(Int128) + BigInt(1)) - 2 == (1 + BigInt(2)*typemin(Int128)) // (BigInt(1) + typemax(Int128))
end

@testset "Promotions on binary operations with Rationals (#36277)" begin
inttypes = (Base.BitInteger_types..., BigInt)
for T in inttypes, S in inttypes
U = Rational{promote_type(T, S)}
@test typeof(one(Rational{T}) + one(S)) == typeof(one(S) + one(Rational{T})) == typeof(one(Rational{T}) + one(Rational{S})) == U
@test typeof(one(Rational{T}) - one(S)) == typeof(one(S) - one(Rational{T})) == typeof(one(Rational{T}) - one(Rational{S})) == U
@test typeof(one(Rational{T}) * one(S)) == typeof(one(S) * one(Rational{T})) == typeof(one(Rational{T}) * one(Rational{S})) == U
@test typeof(one(Rational{T}) // one(S)) == typeof(one(S) // one(Rational{T})) == typeof(one(Rational{T}) // one(Rational{S})) == U
end
@test (-40//3) // 0x5 == 0x5 // (-15//8) == -8//3
@test (-4//7) // (0x1//0x3) == (0x4//0x7) // (-1//3) == -12//7
@test -3//2 + 0x1//0x1 == -3//2 + 0x1 == 0x1//0x1 + (-3//2) == 0x1 + (-3//2) == -1//2
@test 0x3//0x5 - 2//3 == 3//5 - 0x2//0x3 == -1//15
@test rem(-12//5, 0x2//0x1) == rem(-12//5, 0x2) == -2//5
@test mod(0x3//0x1, -4//7) == mod(0x3, -4//7) == -3//7
@test -1//5 * 0x3//0x2 == 0x3//0x2 * -1//5 == -3//10
@test -2//3 * 0x1 == 0x1 * -2//3 == -2//3
end

0 comments on commit 6c760d2

Please sign in to comment.