Skip to content
1 change: 1 addition & 0 deletions base/special/trig.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1112,6 +1112,7 @@ function _cosc(x::Number)
# generic Taylor series: π ∑ (-1)^n (πx)^{2n-1}/a(n) where
# a(n) = (1+2n)*(2n-1)! (= OEIS A174549)
s = (term = -(π*x))/3
iszero(s) && return s # preserve floating-point signed zero
π²x² = term^2
ε = eps(fastabs(term)) # error threshold to stop sum
n = 1
Expand Down
33 changes: 33 additions & 0 deletions test/math.jl
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,39 @@ end
@test ismissing(scdm[2])
end

@testset "behavior at signed zero of monotonic floating-point functions mapping zero to zero" begin
function rounder(rm::RoundingMode)
function closure(::Type{T}, x::AbstractFloat) where {T <: AbstractFloat}
round(T, x, rm)
end
end
rounding_modes = (
RoundNearest, RoundNearestTiesAway, RoundNearestTiesUp, RoundToZero, RoundFromZero, RoundUp, RoundDown,
)
rounders = map(rounder, rounding_modes)
@testset "typ: $typ" for typ in (Float16, Float32, Float64, BigFloat)
(n0, n1) = typ.(0:1)
rounders_typ = Base.Fix1.(rounders, typ)
@testset "f: $f" for f in (
# all strictly increasing
identity, deg2rad, rad2deg, cbrt, log1p, expm1, sinh, tanh, asinh, atanh,
sin, sind, sinpi, tan, tand, tanpi, asin, asind, atan, atand, Base.Fix2(atan, n1), Base.Fix2(atand, n1),
Base.Fix1(round, typ), Base.Fix1(trunc, typ), +, ∘(-, -), ∘(-, cosc),
rounders_typ...,
Base.Fix1(*, n1), Base.Fix2(*, n1), Base.Fix2(/, n1),
)
@testset "s: $s" for s in (-1, 1)
z = s * n0
z::typ
@test z == f(z)::typ
@test signbit(z) === signbit(f(z))
isbitstype(typ) &&
@test z === @inferred f(z)
end
end
end
end

@testset "Integer and Inf args for sinpi/cospi/tanpi/sinc/cosc" begin
for (sinpi, cospi) in ((sinpi, cospi), (x->sincospi(x)[1], x->sincospi(x)[2]))
@test sinpi(1) === 0.0
Expand Down