From e8b3c7ba48fc3e4655231e20af9c708ade5d0e18 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Tue, 8 Aug 2023 21:40:24 -0300 Subject: [PATCH 1/4] Remove weird Rational dispatch and add pi functions to list --- base/math.jl | 2 +- base/special/trig.jl | 8 ++++---- test/math.jl | 6 ++++++ 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/base/math.jl b/base/math.jl index 71bd4949498b5..0f917dce7c99c 100644 --- a/base/math.jl +++ b/base/math.jl @@ -1571,7 +1571,7 @@ sincos(a::Float16) = Float16.(sincos(Float32(a))) for f in (:sin, :cos, :tan, :asin, :atan, :acos, :sinh, :cosh, :tanh, :asinh, :acosh, :atanh, :exp, :exp2, :exp10, :expm1, :log, :log2, :log10, :log1p, - :exponent, :sqrt, :cbrt) + :exponent, :sqrt, :cbrt, :sinpi, :cospi, :sincospi, :tanpi) @eval function ($f)(x::Real) xf = float(x) x === xf && throw(MethodError($f, (x,))) diff --git a/base/special/trig.jl b/base/special/trig.jl index 6463560caa3e5..c9ae219769b27 100644 --- a/base/special/trig.jl +++ b/base/special/trig.jl @@ -789,7 +789,7 @@ Compute ``\\sin(\\pi x)`` more accurately than `sin(pi*x)`, especially for large See also [`sind`](@ref), [`cospi`](@ref), [`sincospi`](@ref). """ -function sinpi(_x::T) where T<:Union{IEEEFloat, Rational} +function sinpi(_x::T) where T<:IEEEFloat x = abs(_x) if !isfinite(x) isnan(x) && return x @@ -820,7 +820,7 @@ end Compute ``\\cos(\\pi x)`` more accurately than `cos(pi*x)`, especially for large `x`. """ -function cospi(x::T) where T<:Union{IEEEFloat, Rational} +function cospi(x::T) where T<:IEEEFloat x = abs(x) if !isfinite(x) isnan(x) && return x @@ -856,7 +856,7 @@ where `x` is in radians), returning a tuple `(sine, cosine)`. See also: [`cispi`](@ref), [`sincosd`](@ref), [`sinpi`](@ref). """ -function sincospi(_x::T) where T<:Union{IEEEFloat, Rational} +function sincospi(_x::T) where T<:IEEEFloat x = abs(_x) if !isfinite(x) isnan(x) && return x, x @@ -895,7 +895,7 @@ Compute ``\\tan(\\pi x)`` more accurately than `tan(pi*x)`, especially for large See also [`tand`](@ref), [`sinpi`](@ref), [`cospi`](@ref), [`sincospi`](@ref). """ -function tanpi(_x::T) where T<:Union{IEEEFloat, Rational} +function tanpi(_x::T) where T<:IEEEFloat # This is modified from sincospi. # Would it be faster or more accurate to make a tanpi_kernel? x = abs(_x) diff --git a/test/math.jl b/test/math.jl index 19d9f7893a496..8e6afba0acfce 100644 --- a/test/math.jl +++ b/test/math.jl @@ -1558,3 +1558,9 @@ for T in (Float16, Float32, Float64) @test Core.Compiler.is_foldable(Base.infer_effects(^, (T,Int))) @test Core.Compiler.is_foldable(Base.infer_effects(^, (T,T))) end + +@testset "BigInt Rationals with special funcs" begin + @test sinpi(big(1//1)) == big(0.0) + @test tanpi(big(1//1)) == big(0.0) + @test cospi(big(1//1)) == big(-1.0) +end From 640c7356c9a920c0b8af4884e72743fef93a96a1 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Tue, 8 Aug 2023 21:48:22 -0300 Subject: [PATCH 2/4] Don't overwrite definitions --- base/math.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/math.jl b/base/math.jl index 0f917dce7c99c..71bd4949498b5 100644 --- a/base/math.jl +++ b/base/math.jl @@ -1571,7 +1571,7 @@ sincos(a::Float16) = Float16.(sincos(Float32(a))) for f in (:sin, :cos, :tan, :asin, :atan, :acos, :sinh, :cosh, :tanh, :asinh, :acosh, :atanh, :exp, :exp2, :exp10, :expm1, :log, :log2, :log10, :log1p, - :exponent, :sqrt, :cbrt, :sinpi, :cospi, :sincospi, :tanpi) + :exponent, :sqrt, :cbrt) @eval function ($f)(x::Real) xf = float(x) x === xf && throw(MethodError($f, (x,))) From 9fcc63faf73eaab08e972ab4cc47076bc01438a0 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Tue, 8 Aug 2023 22:05:29 -0300 Subject: [PATCH 3/4] Change dispatch logic slightly --- base/math.jl | 2 +- base/special/trig.jl | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/base/math.jl b/base/math.jl index 71bd4949498b5..0f917dce7c99c 100644 --- a/base/math.jl +++ b/base/math.jl @@ -1571,7 +1571,7 @@ sincos(a::Float16) = Float16.(sincos(Float32(a))) for f in (:sin, :cos, :tan, :asin, :atan, :acos, :sinh, :cosh, :tanh, :asinh, :acosh, :atanh, :exp, :exp2, :exp10, :expm1, :log, :log2, :log10, :log1p, - :exponent, :sqrt, :cbrt) + :exponent, :sqrt, :cbrt, :sinpi, :cospi, :sincospi, :tanpi) @eval function ($f)(x::Real) xf = float(x) x === xf && throw(MethodError($f, (x,))) diff --git a/base/special/trig.jl b/base/special/trig.jl index c9ae219769b27..7af954df7de01 100644 --- a/base/special/trig.jl +++ b/base/special/trig.jl @@ -932,10 +932,10 @@ cospi(x::Integer) = isodd(x) ? -one(float(x)) : one(float(x)) tanpi(x::Integer) = x >= 0 ? (isodd(x) ? -zero(float(x)) : zero(float(x))) : (isodd(x) ? zero(float(x)) : -zero(float(x))) sincospi(x::Integer) = (sinpi(x), cospi(x)) -sinpi(x::Real) = sin(pi*x) -cospi(x::Real) = cos(pi*x) -sincospi(x::Real) = sincos(pi*x) -tanpi(x::Real) = tan(pi*x) +sinpi(x::AbstractFloat) = sin(pi*x) +cospi(x::AbstractFloat) = cos(pi*x) +sincospi(x::AbstractFloat) = sincos(pi*x) +tanpi(x::AbstractFloat) = tan(pi*x) tanpi(x::Complex) = sinpi(x) / cospi(x) # Is there a better way to do this? function sinpi(z::Complex{T}) where T From c295ecb388d03d769da762216f31e05384bb1e94 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Wed, 9 Aug 2023 17:29:44 -0300 Subject: [PATCH 4/4] Remove unnecessary complexity from the code --- base/special/trig.jl | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/base/special/trig.jl b/base/special/trig.jl index 7af954df7de01..50d3d69585217 100644 --- a/base/special/trig.jl +++ b/base/special/trig.jl @@ -796,9 +796,7 @@ function sinpi(_x::T) where T<:IEEEFloat throw(DomainError(x, "`x` cannot be infinite.")) end # For large x, answers are all 1 or zero. - if T <: AbstractFloat - x >= maxintfloat(T) && return copysign(zero(T), _x) - end + x >= maxintfloat(T) && return copysign(zero(T), _x) # reduce to interval [0, 0.5] n = round(2*x) @@ -827,9 +825,7 @@ function cospi(x::T) where T<:IEEEFloat throw(DomainError(x, "`x` cannot be infinite.")) end # For large x, answers are all 1 or zero. - if T <: AbstractFloat - x >= maxintfloat(T) && return one(T) - end + x >= maxintfloat(T) && return one(T) # reduce to interval [0, 0.5] n = round(2*x) @@ -863,9 +859,7 @@ function sincospi(_x::T) where T<:IEEEFloat throw(DomainError(x, "`x` cannot be infinite.")) end # For large x, answers are all 1 or zero. - if T <: AbstractFloat - x >= maxintfloat(T) && return (copysign(zero(T), _x), one(T)) - end + x >= maxintfloat(T) && return (copysign(zero(T), _x), one(T)) # reduce to interval [0, 0.5] n = round(2*x) @@ -905,9 +899,7 @@ function tanpi(_x::T) where T<:IEEEFloat end # For large x, answers are all zero. # All integer values for floats larger than maxintfloat are even. - if T <: AbstractFloat - x >= maxintfloat(T) && return copysign(zero(T), _x) - end + x >= maxintfloat(T) && return copysign(zero(T), _x) # reduce to interval [0, 0.5] n = round(2*x)