@@ -200,9 +200,19 @@ saturating_sub(x::X, y::X) where {X <: FixedPoint} =
200200saturating_sub (x:: X , y:: X ) where {X <: FixedPoint{<:Unsigned} } = X (x. i - min (x. i, y. i), 0 )
201201
202202# checked arithmetic
203- checked_neg (x:: X ) where {X <: FixedPoint } = X (checked_neg (x. i), 0 )
204- checked_add (x:: X , y:: X ) where {X <: FixedPoint } = X (checked_add (x. i, y. i), 0 )
205- checked_sub (x:: X , y:: X ) where {X <: FixedPoint } = X (checked_sub (x. i, y. i), 0 )
203+ checked_neg (x:: X ) where {X <: FixedPoint } = checked_sub (zero (X), x)
204+ function checked_add (x:: X , y:: X ) where {X <: FixedPoint }
205+ r, f = Base. Checked. add_with_overflow (x. i, y. i)
206+ z = X (r, 0 ) # store first
207+ f && throw_overflowerror (:+ , x, y)
208+ z
209+ end
210+ function checked_sub (x:: X , y:: X ) where {X <: FixedPoint }
211+ r, f = Base. Checked. sub_with_overflow (x. i, y. i)
212+ z = X (r, 0 ) # store first
213+ f && throw_overflowerror (:- , x, y)
214+ z
215+ end
206216
207217# default arithmetic
208218const DEFAULT_ARITHMETIC = :wrapping
@@ -424,6 +434,13 @@ scaledual(::Type{Tdual}, x::AbstractArray{T}) where {Tdual, T <: FixedPoint} =
424434 throw (ArgumentError (String (take! (io))))
425435end
426436
437+ @noinline function throw_overflowerror (op:: Symbol , @nospecialize (x), @nospecialize (y))
438+ io = IOBuffer ()
439+ print (io, x, ' ' , op, ' ' , y, " overflowed for type " )
440+ showtype (io, typeof (x))
441+ throw (OverflowError (String (take! (io))))
442+ end
443+
427444function Random. rand (r:: AbstractRNG , :: SamplerType{X} ) where X <: FixedPoint
428445 X (rand (r, rawtype (X)), 0 )
429446end
0 commit comments