From 9d896dc9f1f105b33aa50ad07bb41d4061e2d439 Mon Sep 17 00:00:00 2001 From: Nathan Zimmerberg <39104088+nhz2@users.noreply.github.com> Date: Tue, 20 Feb 2024 23:07:45 -0500 Subject: [PATCH] Throw OverflowError on `copysign(typemin(Int)//1, 1)` (#53395) The default `copysign(x::Real, y::Real)` in `number.jl` works, so the incorrect method in `rational.jl` isn't needed. Here is a benchmark of the new version. ```julia using BenchmarkTools function foo!(c,a,b) c .= copysign.(a, b) nothing end N = 1000 @btime foo!(c,a,b) setup=(c=zeros(Rational{Int},N); a=rand(Int,N).//rand(Int,N); b=fill(-1,N)) ``` On master: 406.215 ns (0 allocations: 0 bytes) On this PR: 869.327 ns (0 allocations: 0 bytes) --- base/rational.jl | 2 -- test/numbers.jl | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/base/rational.jl b/base/rational.jl index b27baf5973d3b..bd1633bd3dd28 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -315,8 +315,6 @@ denominator(x::Rational) = x.den sign(x::Rational) = oftype(x, sign(x.num)) signbit(x::Rational) = signbit(x.num) -copysign(x::Rational, y::Real) = unsafe_rational(copysign(x.num, y), x.den) -copysign(x::Rational, y::Rational) = unsafe_rational(copysign(x.num, y.num), x.den) abs(x::Rational) = unsafe_rational(checked_abs(x.num), x.den) diff --git a/test/numbers.jl b/test/numbers.jl index 922fa0da3337e..47d7e87753b11 100644 --- a/test/numbers.jl +++ b/test/numbers.jl @@ -679,6 +679,9 @@ end @test copysign(big(-1), 0x02) == 1 @test copysign(big(-1.0), 0x02) == 1.0 @test copysign(-1//2, 0x01) == 1//2 + + # Verify overflow is checked with rational + @test_throws OverflowError copysign(typemin(Int)//1, 1) end @testset "isnan/isinf/isfinite" begin