Skip to content

Commit 3cea757

Browse files
committed
use Base function rather than Libm ones since they're faster
1 parent ca02438 commit 3cea757

File tree

1 file changed

+44
-9
lines changed

1 file changed

+44
-9
lines changed

src/NaNMath.jl

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,54 @@ module NaNMath
33
using OpenLibm_jll
44
const libm = OpenLibm_jll.libopenlibm
55

6-
for f in (:sin, :cos, :tan, :asin, :acos, :acosh, :atanh, :log, :log2, :log10,
7-
:lgamma, :log1p)
6+
for f in (:sin, :cos, :tan, :asin, :acos, :acosh, :atanh,
7+
:log, :log2, :log10, :log1p, :lgamma)
8+
@eval begin
9+
function ($f)(x::Real)
10+
fx = float(x)
11+
x === xf && throw(MethodError($f, (x,)))
12+
($f)(fx)
13+
end
14+
end
15+
end
16+
17+
for f in (:lgamma)
818
@eval begin
919
Base.@assume_effects :total ($f)(x::Float64) = ccall(($(string(f)),libm), Float64, (Float64,), x)
1020
Base.@assume_effects :total ($f)(x::Float32) = ccall(($(string(f,"f")),libm), Float32, (Float32,), x)
11-
($f)(x::Real) = ($f)(float(x))
12-
if $f !== :lgamma
13-
($f)(x) = (Base.$f)(x)
21+
end
22+
end
23+
24+
for f in (:sin, :cos, :tan)
25+
@eval begin
26+
function ($f)(x::T) where T<:Union{Float16, Float32, Float64}
27+
isinf(x) ? T(NaN) : (Base.$f)(x)
28+
end
29+
end
30+
end
31+
32+
for f in (:asin, :acos, :atanh)
33+
@eval begin
34+
function ($f)(x::T) where T<:Union{Float16, Float32, Float64}
35+
abs(x) > T(1) ? T(NaN) : (Base.$f)(x)
1436
end
1537
end
1638
end
39+
function acosh(x::T) where T<:Union{Float16, Float32, Float64}
40+
x < T(1) ? T(NaN) : acosh(x)
41+
end
42+
43+
for f in (:log, :log2, :log10)
44+
@eval begin
45+
function ($f)(x::T) where T<:Union{Float16, Float32, Float64}
46+
x < 0 ? T(NaN) : (Base.$f)(x)
47+
end
48+
end
49+
end
50+
51+
function log1p(x::T) where T<:Union{Float16, Float32, Float64}
52+
x < T(-1) ? T(NaN) : Base.log1p(x)
53+
end
1754

1855
for f in (:sqrt,)
1956
@eval ($f)(x) = (Base.$f)(x)
@@ -23,10 +60,8 @@ for f in (:max, :min)
2360
@eval ($f)(x, y) = (Base.$f)(x, y)
2461
end
2562

26-
# Would be more efficient to remove the domain check in Base.sqrt(),
27-
# but this doesn't seem easy to do.
28-
Base.@assume_effects :nothrow sqrt(x::T) where {T<:Union{Float16, Float32, Float64}} = x < 0.0 ? T(NaN) : Base.sqrt(x)
29-
sqrt(x::T) where {T<:AbstractFloat} = x < 0.0 ? T(NaN) : Base.sqrt(x)
63+
sqrt(x::T) where {T<:Union{Float16, Float32, Float64}} = x < T(0) ? T(NaN) : Base.Intrinsics.sqrt_llvm(x)
64+
sqrt(x::T) where {T<:AbstractFloat} = x < T(0) ? T(NaN) : Base.sqrt(x)
3065
sqrt(x::Real) = sqrt(float(x))
3166

3267
# Don't override built-in ^ operator

0 commit comments

Comments
 (0)