@@ -12,7 +12,8 @@ import Base: ==, <, <=, -, +, *, /, ~, isapprox,
12
12
import Statistics # for _mean_promote
13
13
import Random: Random, AbstractRNG, SamplerType, rand!
14
14
15
- import Base. Checked: checked_neg, checked_add, checked_sub, checked_mul, checked_div
15
+ import Base. Checked: checked_neg, checked_add, checked_sub, checked_abs, checked_mul,
16
+ checked_div
16
17
17
18
using Base: @pure
18
19
36
37
# Q and N typealiases are exported in separate source files
37
38
# Functions
38
39
scaledual,
39
- wrapping_neg, wrapping_add, wrapping_sub, wrapping_mul,
40
- saturating_neg, saturating_add, saturating_sub, saturating_mul
40
+ wrapping_neg, wrapping_add, wrapping_sub, wrapping_abs, wrapping_mul,
41
+ saturating_neg, saturating_add, saturating_sub, saturating_abs, saturating_mul
41
42
42
43
include (" utilities.jl" )
43
44
@@ -189,6 +190,7 @@ float(x::FixedPoint) = convert(floattype(x), x)
189
190
wrapping_neg (x:: X ) where {X <: FixedPoint } = X (- x. i, 0 )
190
191
wrapping_add (x:: X , y:: X ) where {X <: FixedPoint } = X (x. i + y. i, 0 )
191
192
wrapping_sub (x:: X , y:: X ) where {X <: FixedPoint } = X (x. i - y. i, 0 )
193
+ wrapping_abs (x:: X ) where {X <: FixedPoint } = X (abs (x. i), 0 )
192
194
193
195
# saturating arithmetic
194
196
saturating_neg (x:: X ) where {X <: FixedPoint } = X (~ min (x. i - true , x. i), 0 )
@@ -202,6 +204,9 @@ saturating_sub(x::X, y::X) where {X <: FixedPoint} =
202
204
X (x. i - ifelse (x. i < 0 , min (y. i, x. i - typemin (x. i)), max (y. i, x. i - typemax (x. i))), 0 )
203
205
saturating_sub (x:: X , y:: X ) where {X <: FixedPoint{<:Unsigned} } = X (x. i - min (x. i, y. i), 0 )
204
206
207
+ saturating_abs (x:: X ) where {X <: FixedPoint } =
208
+ X (ifelse (signbit (abs (x. i)), typemax (x. i), abs (x. i)), 0 )
209
+
205
210
# checked arithmetic
206
211
checked_neg (x:: X ) where {X <: FixedPoint } = checked_sub (zero (X), x)
207
212
function checked_add (x:: X , y:: X ) where {X <: FixedPoint }
@@ -216,11 +221,15 @@ function checked_sub(x::X, y::X) where {X <: FixedPoint}
216
221
f && throw_overflowerror (:- , x, y)
217
222
z
218
223
end
224
+ function checked_abs (x:: X ) where {X <: FixedPoint }
225
+ abs (x. i) >= 0 || throw_overflowerror_abs (x)
226
+ X (abs (x. i), 0 )
227
+ end
219
228
220
229
# default arithmetic
221
230
const DEFAULT_ARITHMETIC = :wrapping
222
231
223
- for (op, name) in ((:- , :neg ), )
232
+ for (op, name) in ((:- , :neg ), ( :abs , :abs ) )
224
233
f = Symbol (DEFAULT_ARITHMETIC, :_ , name)
225
234
@eval begin
226
235
$ op (x:: X ) where {X <: FixedPoint } = $ f (x)
@@ -283,7 +292,7 @@ for f in (:(==), :<, :<=, :div, :fld, :fld1)
283
292
$ f (x:: X , y:: X ) where {X <: FixedPoint } = $ f (x. i, y. i)
284
293
end
285
294
end
286
- for f in (:~ , :abs )
295
+ for f in (:~ , )
287
296
@eval begin
288
297
$ f (x:: X ) where {X <: FixedPoint } = X ($ f (x. i), 0 )
289
298
end
443
452
showtype (io, typeof (x))
444
453
throw (OverflowError (String (take! (io))))
445
454
end
455
+ @noinline function throw_overflowerror_abs (@nospecialize (x))
456
+ io = IOBuffer ()
457
+ print (io, " abs(" , x, " ) overflowed for type " )
458
+ showtype (io, typeof (x))
459
+ throw (OverflowError (String (take! (io))))
460
+ end
446
461
447
462
function Random. rand (r:: AbstractRNG , :: SamplerType{X} ) where X <: FixedPoint
448
463
X (rand (r, rawtype (X)), 0 )
0 commit comments