@@ -40,26 +40,11 @@ function nox(x)
4040 unsafe_store! (flags[], 0 )
4141 return x
4242end
43+
4344# Check exception flags in mask & throw, otherwise returning x;
44- # always clearing exceptions. These are macros so that
45+ # always clearing exceptions. This is a macros so that
4546# the error message is only evaluated if an exception occurs.
46-
47- macro xchk (x, args... )
48- mask= 0x3f
49- if ! isempty (args) && Meta. isexpr (args[end ], :(= )) && args[end ]. args[1 ] == :mask # mask=... keyword at end
50- mask = esc (args[end ]. args[2 ])
51- args = args[1 : end - 1 ]
52- end
53- quote
54- ret = $ (esc (x))
55- f = unsafe_load (flags[])
56- unsafe_store! (flags[], 0 )
57- f & $ mask != 0 && xchk_throw (f, $ (map (esc,args)... ))
58- ret
59- end
60- end
61-
62- macro xchk1 (x, exc, args... )
47+ macro xchk (x, exc, args... )
6348 mask= 0x3f
6449 if ! isempty (args) && Meta. isexpr (args[end ], :(= )) && args[end ]. args[1 ] == :mask # mask=... keyword at end
6550 mask = esc (args[end ]. args[2 ])
@@ -74,18 +59,6 @@ macro xchk1(x, exc, args...)
7459 end
7560end
7661
77- # separate this exception throwing code into a function to avoid
78- # inlining it over and over in the @xchk macro
79- function xchk_throw (f, args... )
80- f & INEXACT != 0 && throw (InexactError (args... ))
81- f & OVERFLOW != 0 && throw (OverflowError (args... ))
82- f & DIVBYZERO != 0 && throw (DivideError ())
83- f & INVALID != 0 && throw (DomainError (args... ))
84- f & UNDERFLOW != 0 && error (" underflow" )
85- f & UNNORMAL != 0 && error (" unnormal" )
86- @assert false # this should be unreachable
87- end
88-
8962# ############################################################################
9063
9164const rounding = Ref {Ptr{Cuint}} ()
@@ -167,7 +140,7 @@ for w in (32,64,128)
167140 if isnan (x) && ! isnanstr (s)
168141 throw (ArgumentError (" invalid number format $s " ))
169142 end
170- return @xchk1 (x, InexactError, :parse , $ BID, s)
143+ return @xchk (x, InexactError, :parse , $ BID, s)
171144 end
172145
173146 $ BID (x:: AbstractString ) = parse ($ BID, x)
@@ -233,7 +206,7 @@ for w in (32,64,128)
233206 n = length (DIGITS) - 1
234207 end
235208 # rounded = round(x * exp10($BID(n)), RoundNearestTiesAway)
236- rounded = @xchk1 (ccall (($ (bidsym (w," round_integral_nearest_away" )), libbid), $ BID, ($ BID,), x * exp10 ($ BID (n))), InexactError, :round , $ BID, x, mask= INVALID | OVERFLOW)
209+ rounded = @xchk (ccall (($ (bidsym (w," round_integral_nearest_away" )), libbid), $ BID, ($ BID,), x * exp10 ($ BID (n))), InexactError, :round , $ BID, x, mask= INVALID | OVERFLOW)
237210 if rounded == 0
238211 DIGITS[1 ] = UInt8 (' 0' )
239212 return Int32 (1 ), Int32 (1 ), signbit (x)
@@ -306,7 +279,7 @@ for w in (32,64,128)
306279
307280 Base. nextfloat (x:: $BID ) = nox (_nextfloat (x))
308281 Base. prevfloat (x:: $BID ) = nox (_prevfloat (x))
309- Base. eps (x:: $BID ) = ifelse (isfinite (x), @xchk (nextfloat (x) - x, " $($ BID) value overflow" , mask= OVERFLOW), $ (_parse (T, " NaN" )))
282+ Base. eps (x:: $BID ) = ifelse (isfinite (x), @xchk (nextfloat (x) - x, OverflowError, " $($ BID) value overflow" , mask= OVERFLOW), $ (_parse (T, " NaN" )))
310283
311284 # the meaning of the exponent is different than for binary FP: it is 10^n, not 2^n:
312285 # Base.exponent(x::$BID) = nox(ccall(($(bidsym(w,"ilogb")), libbid), Cint, ($BID,), x))
@@ -322,11 +295,11 @@ for w in (32,64,128)
322295 end
323296
324297 for f in (:exp ,:log ,:sin ,:cos ,:tan ,:asin ,:acos ,:atan ,:sinh ,:cosh ,:tanh ,:asinh ,:acosh ,:atanh ,:log1p ,:expm1 ,:log10 ,:log2 ,:exp2 ,:exp10 ,:lgamma ,:sqrt ,:cbrt ,:abs )
325- @eval Base.$ f (x:: $BID ) = @xchk (ccall (($ (bidsym (w,f)), libbid), $ BID, ($ BID,), x), " invalid operation ' $( $ f) ' on $( $ BID) " , mask= INVALID)
298+ @eval Base.$ f (x:: $BID ) = @xchk (ccall (($ (bidsym (w,f)), libbid), $ BID, ($ BID,), x), DomainError, x , mask= INVALID)
326299 end
327300
328301 for (f,c) in ((:gamma ," tgamma" ), (:- ," negate" ), (:round ," nearbyint" ))
329- @eval Base.$ f (x:: $BID ) = @xchk (ccall (($ (bidsym (w,c)), libbid), $ BID, ($ BID,), x), " invalid operation ' $( $ c) ' on $( $ BID) " , mask= INVALID)
302+ @eval Base.$ f (x:: $BID ) = @xchk (ccall (($ (bidsym (w,c)), libbid), $ BID, ($ BID,), x), DomainError, x , mask= INVALID)
330303 end
331304
332305 for (f,c) in ((:(== )," quiet_equal" ), (:> ," quiet_greater" ), (:< ," quiet_less" ), (:(>= ), " quiet_greater_equal" ), (:(<= ), " quiet_less_equal" ))
@@ -358,7 +331,7 @@ for w in (32,64,128)
358331 @eval promote_rule (:: Type{$BID} , :: Type{$BID′} ) = $ BID
359332 end
360333 if w != w′
361- @eval Base. convert (:: Type{$BID} , x:: $BID′ ) = @xchk1 (ccall (($ (string (" __bid" ,w′," _to_" ," bid" ,w)), libbid), $ BID, ($ BID′,), x), InexactError, :convert , $ BID, x, mask= INEXACT)
334+ @eval Base. convert (:: Type{$BID} , x:: $BID′ ) = @xchk (ccall (($ (string (" __bid" ,w′," _to_" ," bid" ,w)), libbid), $ BID, ($ BID′,), x), InexactError, :convert , $ BID, x, mask= INEXACT)
362335 end
363336
364337 # promote binary*decimal -> decimal, for consistency with other operations above
@@ -379,12 +352,12 @@ for w in (32,64,128)
379352 for (i′, i′str) in ((" Int$w′ " , " int$w′ " ), (" UInt$w′ " , " uint$w′ " ))
380353 Ti′ = eval (Symbol (i′))
381354 @eval begin
382- Base. trunc (:: Type{$Ti′} , x:: $BID ) = @xchk1 (ccall (($ (bidsym (w," to_" ,i′str," _xint" )), libbid), $ Ti′, ($ BID,), x), InexactError, :trunc , $ BID, x, mask= INVALID | OVERFLOW)
383- Base. floor (:: Type{$Ti′} , x:: $BID ) = @xchk1 (ccall (($ (bidsym (w," to_" ,i′str," _xfloor" )), libbid), $ Ti′, ($ BID,), x), InexactError, :floor , $ BID, x, mask= INVALID | OVERFLOW)
384- Base. ceil (:: Type{$Ti′} , x:: $BID ) = @xchk1 (ccall (($ (bidsym (w," to_" ,i′str," _xceil" )), libbid), $ Ti′, ($ BID,), x), InexactError, :ceil , $ BID, x, mask= INVALID | OVERFLOW)
385- Base. round (:: Type{$Ti′} , x:: $BID ) = @xchk1 (ccall (($ (bidsym (w," to_" ,i′str," _xrnint" )), libbid), $ Ti′, ($ BID,), x), InexactError, :round , $ BID, x, mask= INVALID | OVERFLOW)
386- Base. round (:: Type{$Ti′} , x:: $BID , :: RoundingMode{:NearestTiesAway} ) = @xchk1 (ccall (($ (bidsym (w," to_" ,i′str," _xrninta" )), libbid), $ Ti′, ($ BID,), x), InexactError, :round , $ BID, x, mask= INVALID | OVERFLOW)
387- Base. convert (:: Type{$Ti′} , x:: $BID ) = @xchk1 (ccall (($ (bidsym (w," to_" ,i′str," _xfloor" )), libbid), $ Ti′, ($ BID,), x), InexactError, :convert , $ BID, x)
355+ Base. trunc (:: Type{$Ti′} , x:: $BID ) = @xchk (ccall (($ (bidsym (w," to_" ,i′str," _xint" )), libbid), $ Ti′, ($ BID,), x), InexactError, :trunc , $ BID, x, mask= INVALID | OVERFLOW)
356+ Base. floor (:: Type{$Ti′} , x:: $BID ) = @xchk (ccall (($ (bidsym (w," to_" ,i′str," _xfloor" )), libbid), $ Ti′, ($ BID,), x), InexactError, :floor , $ BID, x, mask= INVALID | OVERFLOW)
357+ Base. ceil (:: Type{$Ti′} , x:: $BID ) = @xchk (ccall (($ (bidsym (w," to_" ,i′str," _xceil" )), libbid), $ Ti′, ($ BID,), x), InexactError, :ceil , $ BID, x, mask= INVALID | OVERFLOW)
358+ Base. round (:: Type{$Ti′} , x:: $BID ) = @xchk (ccall (($ (bidsym (w," to_" ,i′str," _xrnint" )), libbid), $ Ti′, ($ BID,), x), InexactError, :round , $ BID, x, mask= INVALID | OVERFLOW)
359+ Base. round (:: Type{$Ti′} , x:: $BID , :: RoundingMode{:NearestTiesAway} ) = @xchk (ccall (($ (bidsym (w," to_" ,i′str," _xrninta" )), libbid), $ Ti′, ($ BID,), x), InexactError, :round , $ BID, x, mask= INVALID | OVERFLOW)
360+ Base. convert (:: Type{$Ti′} , x:: $BID ) = @xchk (ccall (($ (bidsym (w," to_" ,i′str," _xfloor" )), libbid), $ Ti′, ($ BID,), x), InexactError, :convert , $ BID, x)
388361 Base.$ (Symbol (" $Ti′ " ))(x:: $BID ) = convert ($ Ti′, x)
389362 end
390363 end
0 commit comments