Next: , Previous: , Up: Fixnum and Flonum Operations   [Contents][Index]

#### 4.7.4 Floating-Point Exceptions

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. The procedures `flo:exceptions->names` and `flo:names->exceptions` convert between machine-dependent integer representations and machine-independent lists of human-readable symbols.

The following exceptions are recognized by MIT/GNU Scheme:

inexact-result

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.

underflow

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.

overflow

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.

divide-by-zero

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.

invalid-operation

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.

subnormal-operand

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.)

procedure: flo:supported-exceptions

Returns the set of exceptions that are supported on the current machine.

procedure: flo:exception:divide-by-zero
procedure: flo:exception:inexact-result
procedure: flo:exception:invalid-operation
procedure: flo:exception:overflow
procedure: flo:exception:subnormal-operand
procedure: flo:exception:underflow

Returns the specified floating-point exception number. On machines that do not support a particular exception, the corresponding procedure simply returns `0`.

procedure: flo:exceptions->names excepts
procedure: flo:names->exceptions list

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)
```
procedure: flo:test-exceptions excepts

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.

procedure: flo:clear-exceptions! excepts
procedure: flo:raise-exceptions! excepts

Clears or raises the exceptions in excepts, entering a per-thread environment. Other exceptions are unaffected.

procedure: flo:save-exception-flags
procedure: flo:restore-exception-flags! exceptflags
procedure: flo:test-exception-flags exceptflags excepts

`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 environment. `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:restore-exception-flags!` and `flo:test-exception-flags`.

Bug: `Flo:test-exception-flags` is unimplemented.

procedure: flo:have-trap-enable/disable?

Returns true if trapping floating-point exceptions is supported on this machine.

procedure: flo:default-trapped-exceptions

Returns the set of exceptions that are trapped in the default floating-point environment. Equivalent to `(flo:names->exceptions '())`, or simply `0`, since by default, no exceptions are trapped.

procedure: flo:trapped-exceptions

Returns the set of exceptions that are currently trapped.

procedure: flo:trap-exceptions! excepts
procedure: flo:untrap-exceptions! excepts
procedure: flo:set-trapped-exceptions! excepts

`Flo:trap-exceptions!` requests that any exceptions in the set excepts be trapped, in addition to all of the ones that are currently trapped. `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)))
```
procedure: flo:with-exceptions-trapped excepts thunk
procedure: flo:with-exceptions-untrapped excepts thunk
procedure: flo:with-trapped-exceptions excepts thunk

Dynamic-extent analogues of `flo:trap-exceptions!`, `flo:untrap-exceptions!`, and `flo:set-trapped-exceptions!`. 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.

procedure: flo:defer-exception-traps!

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 `flo:deferring-exception-traps`.

procedure: flo:deferring-exception-traps thunk

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)))))
```
procedure: flo:ignoring-exception-traps thunk

Calls thunk with all exceptions untrapped and unraised. Equivalent to:

```(flo:preserving-environment
(lambda ()
(flo:defer-exception-traps!)
(thunk)))
```

Next: , Previous: , Up: Fixnum and Flonum Operations   [Contents][Index]