diff --git a/Project.toml b/Project.toml index b3acd5f..c16d012 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "IrrationalConstants" uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" authors = ["JuliaMath"] -version = "0.2.1" +version = "0.2.2" [compat] julia = "1" diff --git a/src/IrrationalConstants.jl b/src/IrrationalConstants.jl index 3d9e8ee..691be93 100644 --- a/src/IrrationalConstants.jl +++ b/src/IrrationalConstants.jl @@ -28,5 +28,6 @@ export include("macro.jl") include("stats.jl") +include("trigonometric.jl") end # module diff --git a/src/trigonometric.jl b/src/trigonometric.jl new file mode 100644 index 0000000..7f84548 --- /dev/null +++ b/src/trigonometric.jl @@ -0,0 +1,34 @@ +# Functions return `Float64`, consistent with Base +# https://github.com/JuliaLang/julia/pull/42595 +# Values at poles are defined to be consistent with `cot(0)` and `cot(π)` +# https://github.com/JuliaLang/julia/issues/7123 +# https://github.com/JuliaLang/julia/blob/e3d366f1966595ba737220df49e220610823b331/base/mathconstants.jl#L130 + +# `sin` +Base.sin(::Twoπ) = 0.0 +Base.sin(::Fourπ) = 0.0 +Base.sin(::Halfπ) = 1.0 +Base.sin(::Quartπ) = Float64(invsqrt2) + +# `cos` +Base.cos(::Twoπ) = 1.0 +Base.cos(::Fourπ) = 1.0 +Base.cos(::Halfπ) = 0.0 +Base.cos(::Quartπ) = Float64(invsqrt2) + +# `sincos` +Base.sincos(::Twoπ) = (0.0, 1.0) +Base.sincos(::Fourπ) = (0.0, 1.0) +Base.sincos(::Halfπ) = (1.0, 0.0) +Base.sincos(::Quartπ) = (Float64(invsqrt2), Float64(invsqrt2)) + +# `tan` +Base.tan(::Twoπ) = 0.0 +Base.tan(::Fourπ) = 0.0 +Base.tan(::Halfπ) = 1/0 +Base.tan(::Quartπ) = 1.0 + +# `csc`, `sec`, and `cot` are defined automatically, so we do not define them +# there is one exception where we can improve accuracy: +Base.csc(::Quartπ) = Float64(sqrt2) +Base.sec(::Quartπ) = Float64(sqrt2) diff --git a/test/runtests.jl b/test/runtests.jl index c87faa9..a529a5e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -150,3 +150,34 @@ end @test @inferred(round(loghalf, mode)) == 0.0 end end + +@testset "trigonometric functions" begin + # 2π, 4π + for (n, x) in ((2, twoπ), (4, fourπ)) + @test sin(x) === sinpi(n) === sin(0.0) + @test cos(x) === cospi(n) === cos(0.0) + end + + # halfπ, quartπ + for (r, x) in ((big"0.5", halfπ), (big"0.25", quartπ)) + @test sin(x) === Float64(sinpi(r)) + @test cos(x) === Float64(cospi(r)) + end + + # Check consistency of definitions + for x in (twoπ, fourπ, halfπ, quartπ) + @test sincos(x) === (sin(x), cos(x)) + @test tan(x) === sin(x) / cos(x) + end + + # Check `csc`, `sec`, and `cot` + for x in (twoπ, fourπ, halfπ) + # These are defined automatically via sin, cos, and tan + @test csc(x) === 1 / sin(x) + @test sec(x) === 1 / cos(x) + @test cot(x) === csc(x) / sec(x) + end + @test csc(quartπ) === Float64(csc(big(quartπ))) + @test sec(quartπ) === Float64(sec(big(quartπ))) + @test cot(quartπ) === Float64(cot(big(quartπ))) +end