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 set of exceptions that can be trapped on the current machine. This is usually the same as the supported exceptions, except for inexact-result, which is never trappable in MIT/GNU Scheme.
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)))