In IEEE 754-2008, floating-point operations such as arithmetic may raise exceptions. This sets a flag in the floating-point environment that is maintained until it is cleared. Many machines can also be configured to trap on exceptions, which in Scheme leads to signalling a condition. (Not all CPUs support trapping exceptions — for example, most ARMv8 CPUs do not.) In the default environment, no exceptions are trapped.
Floating-point exceptions and sets of floating-point exceptions are
represented by small integers, whose interpretation is
machine-dependent — for example, the invalid-operation exception
may be represented differently on PowerPC and AMD x86-64 CPUs.
The number for a floating-point exception is the same as the number
for a set of exceptions containing only that one; the bitwise-AND of
two sets is their intersection, the bitwise-IOR is their union, etc.
flo:names->exceptions convert between machine-dependent integer
representations and machine-independent lists of human-readable
The following exceptions are recognized by MIT/GNU Scheme:
Raised when the result of a floating-point computation is not a floating-point number and therefore must be rounded.
The inexact-result exception is never trappable in MIT/GNU Scheme.
Raised when the result of a floating-point computation is too small in magnitude to be represented by a normal floating-point number, and is therefore rounded to a subnormal or zero.
Raised when the result of a floating-point computation is too large in magnitude to be represented by a floating-point number, and is therefore rounded to infinity.
Raised on division of a nonzero finite real number by a zero real number, or logarithm of zero, or other operation that has an unbounded limit at a point like division by a divisor approaching zero.
Raised when the input to a floating-point computation is nonsensical, such as division of zero by zero, or real logarithm of a negative number. The result of an invalid-operation is a NaN. Also raised when the input to a floating-point operation is a signalling NaN, but not for a quiet NaN.
Raised when an operand in a floating-point operation is subnormal.
(This is not a standard IEEE 754-2008 exception. It is supported by Intel CPUs.)
Returns the set of exceptions that are supported on the current machine.
Returns the specified floating-point exception number.
On machines that do not support a particular exception, the
corresponding procedure simply returns
These procedures convert between a machine-dependent small integer representation of a set of exceptions, and a representation of a set of exceptions by a list of human-readable symbols naming them.
(flo:preserving-environment (lambda () (flo:clear-exceptions! (flo:supported-exceptions)) (flo:/ (identity-procedure 1.) 0.) (flo:exceptions->names (flo:test-exceptions (flo:supported-exceptions))))) ⇒ (divide-by-zero)
Returns the set of exceptions in excepts that are currently raised.
In the default environment, the result is indeterminate, and may be affected by floating-point operations in other threads.
Clears or raises the exceptions in excepts, entering a per-thread environment. Other exceptions are unaffected.
Flo:save-exception-flags returns a machine-dependent
representation of the currently trapped and raised exceptions.
Flo:restore-exception-flags! restores it, entering a per-thread
Flo:test-exception-flags returns the set of exceptions in
excepts that are raised in exceptflags.
Exceptflags is not the same as a set of exceptions.
It is opaque and machine-dependent and should not be used except with
Flo:test-exception-flags is unimplemented.
Returns true if trapping floating-point exceptions is supported on this machine.
Returns the set of exceptions that are trapped in the default
(flo:names->exceptions '()), or simply
since by default, no exceptions are trapped.
Returns the set of exceptions that are currently trapped.
Flo:trap-exceptions! requests that any exceptions in the set
excepts be trapped, in addition to all of the ones that are
Flo:untrap-exceptions! requests that any exceptions in the set
excepts not be trapped.
Flo:set-trapped-exceptions! replaces the set of trapped
exceptions altogether by excepts.
All three procedures enter a per-thread environment.
(define (flo:trap-exceptions! excepts) (flo:set-trapped-exceptions! (fix:or (flo:trapped-exceptions) excepts))) (define (flo:untrap-exceptions! excepts) (flo:set-trapped-exceptions! (fix:andc (flo:trapped-exceptions) excepts))) (define (flo:set-trapped-exceptions! excepts) (flo:trap-exceptions! excepts) (flo:untrap-exceptions! (fix:andc (flo:supported-exceptions) excepts)))
Dynamic-extent analogues of
These call thunk with their respective changes to the set of
trapped exceptions in a per-thread environment, and restore the
environment on return or non-local exit.
Saves the current floating-point environment, clears all raised exceptions, disables all exception traps, and returns a descriptor for the saved floating-point environment.
Flo:defer-exception-traps! is typically used together with
flo:update-environment!, to trap any exceptions that the caller
had wanted trapped only after a long intermediate computation.
This pattern is captured in
Calls thunk, but defers trapping on any exceptions it raises until it returns. Equivalent to:
(flo:preserving-environment (lambda () (let ((environment (flo:defer-exception-traps!))) (begin0 (thunk) (flo:update-environment! environment)))))
Calls thunk with all exceptions untrapped and unraised. Equivalent to:
(flo:preserving-environment (lambda () (flo:defer-exception-traps!) (thunk)))