@@ -3,17 +3,54 @@ module NaNMath
33using OpenLibm_jll
44const 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
1638end
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
1855for 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)
2461end
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)
3065sqrt (x:: Real ) = sqrt (float (x))
3166
3267# Don't override built-in ^ operator
0 commit comments