@@ -38,7 +38,10 @@ export
3838# Functions
3939 scaledual,
4040 wrapping_neg, wrapping_abs, wrapping_add, wrapping_sub, wrapping_mul,
41- saturating_neg, saturating_abs, saturating_add, saturating_sub, saturating_mul
41+ wrapping_fdiv,
42+ saturating_neg, saturating_abs, saturating_add, saturating_sub, saturating_mul,
43+ saturating_fdiv,
44+ checked_fdiv
4245
4346include (" utilities.jl" )
4447
@@ -207,6 +210,10 @@ wrapping_abs(x::X) where {X <: FixedPoint} = X(abs(x.i), 0)
207210wrapping_add (x:: X , y:: X ) where {X <: FixedPoint } = X (x. i + y. i, 0 )
208211wrapping_sub (x:: X , y:: X ) where {X <: FixedPoint } = X (x. i - y. i, 0 )
209212wrapping_mul (x:: X , y:: X ) where {X <: FixedPoint } = (float (x) * float (y)) % X
213+ function wrapping_fdiv (x:: X , y:: X ) where {X <: FixedPoint }
214+ z = floattype (X)(x. i) / floattype (X)(y. i)
215+ isfinite (z) ? z % X : zero (X)
216+ end
210217
211218# saturating arithmetic
212219saturating_neg (x:: X ) where {X <: FixedPoint } = X (~ min (x. i - true , x. i), 0 )
@@ -224,6 +231,9 @@ saturating_sub(x::X, y::X) where {X <: FixedPoint} =
224231saturating_sub (x:: X , y:: X ) where {X <: FixedPoint{<:Unsigned} } = X (x. i - min (x. i, y. i), 0 )
225232
226233saturating_mul (x:: X , y:: X ) where {X <: FixedPoint } = clamp (float (x) * float (y), X)
234+ function saturating_fdiv (x:: X , y:: X ) where {X <: FixedPoint }
235+ clamp (floattype (X)(x. i) / floattype (X)(y. i), X)
236+ end
227237
228238# checked arithmetic
229239checked_neg (x:: X ) where {X <: FixedPoint } = checked_sub (zero (X), x)
@@ -248,6 +258,16 @@ function checked_mul(x::X, y::X) where {X <: FixedPoint}
248258 typemin (X) - eps (X)/ 2 <= z < typemax (X) + eps (X)/ 2 || throw_overflowerror (:* , x, y)
249259 z % X
250260end
261+ function checked_fdiv (x:: X , y:: X ) where {T, X <: FixedPoint{T} }
262+ y === zero (X) && throw (DivideError ())
263+ z = floattype (X)(x. i) / floattype (X)(y. i)
264+ if T <: Unsigned
265+ z < typemax (X) + eps (X)/ 2 || throw_overflowerror (:/ , x, y)
266+ else
267+ typemin (X) - eps (X)/ 2 <= z < typemax (X) + eps (X)/ 2 || throw_overflowerror (:/ , x, y)
268+ end
269+ z % X
270+ end
251271
252272# default arithmetic
253273const DEFAULT_ARITHMETIC = :wrapping
@@ -264,6 +284,7 @@ for (op, name) in ((:+, :add), (:-, :sub), (:*, :mul))
264284 $ op (x:: X , y:: X ) where {X <: FixedPoint } = $ f (x, y)
265285 end
266286end
287+ / (x:: X , y:: X ) where {X <: FixedPoint } = checked_fdiv (x, y) # force checked arithmetic
267288
268289
269290function minmax (x:: X , y:: X ) where {X <: FixedPoint }
0 commit comments