@@ -3,17 +3,54 @@ module NaNMath
3
3
using OpenLibm_jll
4
4
const libm = OpenLibm_jll. libopenlibm
5
5
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 )
8
18
@eval begin
9
19
Base. @assume_effects :total ($ f)(x:: Float64 ) = ccall (($ (string (f)),libm), Float64, (Float64,), x)
10
20
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)
14
36
end
15
37
end
16
38
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
17
54
18
55
for f in (:sqrt ,)
19
56
@eval ($ f)(x) = (Base.$ f)(x)
@@ -23,10 +60,8 @@ for f in (:max, :min)
23
60
@eval ($ f)(x, y) = (Base.$ f)(x, y)
24
61
end
25
62
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)
30
65
sqrt (x:: Real ) = sqrt (float (x))
31
66
32
67
# Don't override built-in ^ operator
0 commit comments