@@ -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_abs, checked_add, checked_sub, 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_abs, wrapping_add, wrapping_sub, wrapping_mul,
41
+ saturating_neg, saturating_abs, saturating_add, saturating_sub, saturating_mul
41
42
42
43
include (" utilities.jl" )
43
44
@@ -202,13 +203,17 @@ float(x::FixedPoint) = convert(floattype(x), x)
202
203
203
204
# wrapping arithmetic
204
205
wrapping_neg (x:: X ) where {X <: FixedPoint } = X (- x. i, 0 )
206
+ wrapping_abs (x:: X ) where {X <: FixedPoint } = X (abs (x. i), 0 )
205
207
wrapping_add (x:: X , y:: X ) where {X <: FixedPoint } = X (x. i + y. i, 0 )
206
208
wrapping_sub (x:: X , y:: X ) where {X <: FixedPoint } = X (x. i - y. i, 0 )
207
209
208
210
# saturating arithmetic
209
211
saturating_neg (x:: X ) where {X <: FixedPoint } = X (~ min (x. i - true , x. i), 0 )
210
212
saturating_neg (x:: X ) where {X <: FixedPoint{<:Unsigned} } = zero (X)
211
213
214
+ saturating_abs (x:: X ) where {X <: FixedPoint } =
215
+ X (ifelse (signbit (abs (x. i)), typemax (x. i), abs (x. i)), 0 )
216
+
212
217
saturating_add (x:: X , y:: X ) where {X <: FixedPoint } =
213
218
X (x. i + ifelse (x. i < 0 , max (y. i, typemin (x. i) - x. i), min (y. i, typemax (x. i) - x. i)), 0 )
214
219
saturating_add (x:: X , y:: X ) where {X <: FixedPoint{<:Unsigned} } = X (x. i + min (~ x. i, y. i), 0 )
@@ -217,8 +222,13 @@ saturating_sub(x::X, y::X) where {X <: FixedPoint} =
217
222
X (x. i - ifelse (x. i < 0 , min (y. i, x. i - typemin (x. i)), max (y. i, x. i - typemax (x. i))), 0 )
218
223
saturating_sub (x:: X , y:: X ) where {X <: FixedPoint{<:Unsigned} } = X (x. i - min (x. i, y. i), 0 )
219
224
225
+
220
226
# checked arithmetic
221
227
checked_neg (x:: X ) where {X <: FixedPoint } = checked_sub (zero (X), x)
228
+ function checked_abs (x:: X ) where {X <: FixedPoint }
229
+ abs (x. i) >= 0 || throw_overflowerror_abs (x)
230
+ X (abs (x. i), 0 )
231
+ end
222
232
function checked_add (x:: X , y:: X ) where {X <: FixedPoint }
223
233
r, f = Base. Checked. add_with_overflow (x. i, y. i)
224
234
z = X (r, 0 ) # store first
235
245
# default arithmetic
236
246
const DEFAULT_ARITHMETIC = :wrapping
237
247
238
- for (op, name) in ((:- , :neg ), )
248
+ for (op, name) in ((:- , :neg ), ( :abs , :abs ) )
239
249
f = Symbol (DEFAULT_ARITHMETIC, :_ , name)
240
250
@eval begin
241
251
$ op (x:: X ) where {X <: FixedPoint } = $ f (x)
@@ -298,7 +308,7 @@ for f in (:(==), :<, :<=, :div, :fld, :fld1)
298
308
$ f (x:: X , y:: X ) where {X <: FixedPoint } = $ f (x. i, y. i)
299
309
end
300
310
end
301
- for f in (:~ , :abs )
311
+ for f in (:~ , )
302
312
@eval begin
303
313
$ f (x:: X ) where {X <: FixedPoint } = X ($ f (x. i), 0 )
304
314
end
458
468
showtype (io, typeof (x))
459
469
throw (OverflowError (String (take! (io))))
460
470
end
471
+ @noinline function throw_overflowerror_abs (@nospecialize (x))
472
+ io = IOBuffer ()
473
+ print (io, " abs(" , x, " ) overflowed for type " )
474
+ showtype (io, typeof (x))
475
+ throw (OverflowError (String (take! (io))))
476
+ end
461
477
462
478
function Random. rand (r:: AbstractRNG , :: SamplerType{X} ) where X <: FixedPoint
463
479
X (rand (r, rawtype (X)), 0 )
0 commit comments