Skip to content

Commit

Permalink
Remove weird Rational dispatch and add pi functions to list (#50850)
Browse files Browse the repository at this point in the history
Should fix  #48735

(cherry picked from commit b763728)
  • Loading branch information
gbaraldi authored and IanButterworth committed Aug 19, 2023
1 parent 03108f2 commit 19fdcce
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 21 deletions.
2 changes: 1 addition & 1 deletion base/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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,)))
Expand Down
32 changes: 12 additions & 20 deletions base/special/trig.jl
Original file line number Diff line number Diff line change
Expand Up @@ -789,16 +789,14 @@ 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
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)
Expand All @@ -820,16 +818,14 @@ 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
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)
Expand All @@ -856,16 +852,14 @@ 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
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)
Expand Down Expand Up @@ -895,7 +889,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)
Expand All @@ -905,9 +899,7 @@ function tanpi(_x::T) where T<:Union{IEEEFloat, Rational}
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)
Expand All @@ -932,10 +924,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
Expand Down
6 changes: 6 additions & 0 deletions test/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 19fdcce

Please sign in to comment.