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..50d3d69585217 100644 --- a/base/special/trig.jl +++ b/base/special/trig.jl @@ -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) @@ -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) @@ -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) @@ -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) @@ -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) @@ -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 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