From 27407e0133277d068adf9526b2c0634ae83c9b18 Mon Sep 17 00:00:00 2001 From: "David P. Sanders" Date: Wed, 24 Jan 2018 15:47:32 -0600 Subject: [PATCH] Fix `sincos` for reals that are not AbstractFloats (#25292) --- base/special/trig.jl | 8 +++++++- test/math.jl | 38 ++++++++++++++++++++++++++++++++++++++ test/show.jl | 4 ++-- 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/base/special/trig.jl b/base/special/trig.jl index 374b38aba61f7..bad3d995b13be 100644 --- a/base/special/trig.jl +++ b/base/special/trig.jl @@ -197,7 +197,13 @@ function sincos(x::T) where T<:Union{Float32, Float64} return -co, si end end -sincos(x::Real) = sincos(float(x)) + +_sincos(x::AbstractFloat) = sincos(x) +_sincos(x) = (sin(x), cos(x)) + +sincos(x) = _sincos(float(x)) + + # There's no need to write specialized kernels, as inlining takes care of remo- # ving superfluous calculations. diff --git a/test/math.jl b/test/math.jl index 1ff7cb17b7ac4..a6f070166f34f 100644 --- a/test/math.jl +++ b/test/math.jl @@ -862,3 +862,41 @@ end @test isnan_type(T, acos(T(NaN))) end end + +# Define simple wrapper of a Float type: +struct FloatWrapper <: Real + x::Float64 +end + +import Base: +, -, *, /, ^, sin, cos, exp, sinh, cosh, convert, isfinite, float, promote_rule + +for op in (:+, :-, :*, :/, :^) + @eval $op(x::FloatWrapper, y::FloatWrapper) = FloatWrapper($op(x.x, y.x)) +end + +for op in (:sin, :cos, :exp, :sinh, :cosh, :-) + @eval $op(x::FloatWrapper) = FloatWrapper($op(x.x)) +end + +for op in (:isfinite,) + @eval $op(x::FloatWrapper) = $op(x.x) +end + +convert(::Type{FloatWrapper}, x::Int) = FloatWrapper(float(x)) +promote_rule(::Type{FloatWrapper}, ::Type{Int}) = FloatWrapper + +float(x::FloatWrapper) = x + +@testset "exp(Complex(a, b)) for a and b of non-standard real type #25292" begin + + x = FloatWrapper(3.1) + y = FloatWrapper(4.1) + + @test sincos(x) == (sin(x), cos(x)) + + z = Complex(x, y) + + @test isa(exp(z), Complex) + @test isa(sin(z), Complex) + @test isa(cos(z), Complex) +end diff --git a/test/show.jl b/test/show.jl index 4511150548cf6..372108287f984 100644 --- a/test/show.jl +++ b/test/show.jl @@ -590,9 +590,9 @@ let repr = sprint(show, "text/html", methods(f16580)) end if isempty(Base.GIT_VERSION_INFO.commit) - @test contains(Base.url(first(methods(sin))),"https://github.com/JuliaLang/julia/tree/v$VERSION/base/missing.jl#L") + @test contains(Base.url(which(sin, (Float64,))), "https://github.com/JuliaLang/julia/tree/v$VERSION/base/special/trig.jl#L") else - @test contains(Base.url(first(methods(sin))),"https://github.com/JuliaLang/julia/tree/$(Base.GIT_VERSION_INFO.commit)/base/missing.jl#L") + @test contains(Base.url(which(sin, (Float64,))), "https://github.com/JuliaLang/julia/tree/$(Base.GIT_VERSION_INFO.commit)/base/special/trig.jl#L") end # print_matrix should be able to handle small and large objects easily, test by