Numeric Overflows
Most numeric types like i64
have a limited range of possible
values they can hold. Some numeric operations such as addition or multiplication
can lead to an overflow. Fuzion's basic types provide a choice of means to deal
with overflows. These will be presented here.
Runtime Checks via Preconditions
The standard operations perform runtime checks to detect overflows at runtime:
If runtime checks are enabled, an error is produced and the application is stopped.
Alternatively, runtime checks can be disabled:
This results in wrap-around numeric behaviour, which in most cases leads to wrong results.
Explicit handling of Overflows
Alternatively, a set of operations +?
, -?
and *?
produce an optional result in case of an overflow:
A match
-statement can be used to distinguish the successful case
from the overflow.
A disadvantage of this approach is that one needs to check for an overflow after every operation that might overflow, otherwise we might see overflows in intermediate values:
Saturating Semantics
In some cases, it might be sufficient to record a large (or small) number in
case of a numeric overflow (or underflow). An example is counting some entity
while it does not matter to distinguish very large amounts. A set of saturating
operations +^
, -^
and *^
does this: After
an overflow (or underflow), the largest (or smallest) representable value is
produced:
Note that, unlike the operations +?
, -?
and *?
that return an option, the saturating operations return a
normal numeric value that can be used in further arithmetic:
The fact that an intermediate operation resulted in an overflow may no longer be obvious after additional operations.
Wrap-Around Semantics
In some applications, it might be desirable to have wrap-around semantics,
i.e., the value represented is always the lowest bits that fit in the respective
type. This is possible using a new set of operations +°
, -°
and *°
: