diff --git a/base/rational.jl b/base/rational.jl index fb1824acb6b31..b4e450fd73abc 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -293,8 +293,14 @@ julia> numerator(4) 4 ``` """ -numerator(x::Integer) = x +numerator(x::Union{Integer,Complex{<:Integer}}) = x numerator(x::Rational) = x.num +function numerator(z::Complex{<:Rational}) + den = denominator(z) + reim = (real(z), imag(z)) + result = checked_mul.(numerator.(reim), div.(den, denominator.(reim))) + complex(result...) +end """ denominator(x) @@ -310,8 +316,9 @@ julia> denominator(4) 1 ``` """ -denominator(x::Integer) = one(x) +denominator(x::Union{Integer,Complex{<:Integer}}) = one(x) denominator(x::Rational) = x.den +denominator(z::Complex{<:Rational}) = lcm(denominator(real(z)), denominator(imag(z))) sign(x::Rational) = oftype(x, sign(x.num)) signbit(x::Rational) = signbit(x.num) diff --git a/test/rational.jl b/test/rational.jl index c6f81372de0b9..20a0971068876 100644 --- a/test/rational.jl +++ b/test/rational.jl @@ -801,3 +801,20 @@ end @test rationalize(Int64, nextfloat(0.1) * im; tol=0) == precise_next * im @test rationalize(0.1im; tol=eps(0.1)) == rationalize(0.1im) end + +@testset "complex numerator, denominator" begin + z = complex(3*3, 2*3*5) + @test z === numerator(z) === numerator(z // 2) === numerator(z // 5) + @test complex(3, 2*5) === numerator(z // 3) + @test isone(denominator(z)) + @test 2 === denominator(z // 2) + @test 1 === denominator(z // 3) + @test 5 === denominator(z // 5) + for den ∈ 1:10 + q = z // den + @test q === (numerator(q)//denominator(q)) + end + @testset "do not overflow silently" begin + @test_throws OverflowError numerator(Int8(1)//Int8(31) + Int8(8)im//Int8(3)) + end +end