Update and clarify fp-env documentation.
authorTaylor R Campbell <campbell@mumble.net>
Sat, 24 Aug 2019 07:07:11 +0000 (07:07 +0000)
committerTaylor R Campbell <campbell@mumble.net>
Sat, 24 Aug 2019 07:07:11 +0000 (07:07 +0000)
doc/ref-manual/numbers.texi

index 5c81be9670c2087b6d1a511c5cf75e8360d5d34f..99a788f4604e9a5af364858123d963cc1ae24a1c 100644 (file)
@@ -2430,26 +2430,52 @@ If @var{quiet?} is false, @var{payload} must be nonzero.
 @node Floating-Point Environment, Floating-Point Exceptions, Flonum Operations, Fixnum and Flonum Operations
 @subsection Floating-Point Environment
 
+@cindex floating-point environment
 The @acronym{IEEE 754-2008} computation model includes a persistent
-rounding mode and exception flags.
-In MIT/GNU Scheme, every thread has its own floating-point
-environment, initialized to the default @acronym{IEEE 754-2008}
-environment, with no exceptions trapped, with no exceptions raised,
-and with round-to-nearest/ties-to-even.
+rounding mode, exception flags, and exception-handling modes.
+In MIT/GNU Scheme, the floating-point environment is per-thread.
+However, because saving and restoring the floating-point environment
+is expensive, it is maintained only for those threads that have
+touched the floating-point environment explicitly, either:
+
+@itemize @bullet
+@item
+during a procedure such as @code{flo:with-exceptions-trapped} that
+establishes a change to the floating-point environment for a dynamic
+extent, or
+
+@item
+after @code{flo:set-environment!} to a non-default environment (but
+not after @code{flo:set-environment!} to the default environment), or
+
+@item
+after various other procedures such as @code{flo:clear-exceptions!}
+that explicitly change the floating-point environment.
+@end itemize
+
+@noindent
+@cindex floating-point environment, default
+@cindex default environment, floating-point
+The default environment is as in @acronym{IEEE 754-2008}: no
+exceptions are trapped, and rounding is to nearest with ties broken to
+even.
+The set of exception flags in the default environment is indeterminate
+--- callers must enter a per-thread environment, e.g. by calling
+@code{flo:clear-exceptions!}, before acting on the exception flags.
+Like the default environment, a per-thread environment initially has
+no exceptions trapped and rounds to nearest with ties to even.
 
-@cindex floating-point environment
 A @strong{floating-point environment} descriptor is a
 machine-dependent object representing the @acronym{IEEE 754-2008}
-floating-point exception flags, exception-handling mode (trap or no
-trap), and rounding mode.
+floating-point rounding mode, exception flags, and exception-handling
+mode.
 Users should not inspect a floating-point environment descriptor other
 than to use it with the procedures here; its representation may vary
 from system to system.
 
 @deffn procedure flo:default-environment
-Returns a descriptor for the default floating-point environment, with
-no exceptions trapped, no exceptions raised, and
-round-to-nearest/ties-to-even.
+Returns a descriptor for the default environment, with no exceptions
+trapped and round-to-nearest/ties-to-even.
 @end deffn
 
 @deffn procedure flo:environment
@@ -2469,30 +2495,41 @@ exceptions in a large intermediate computation until the end.
 @end deffn
 
 @deffn procedure flo:preserving-environment thunk
-Saves the current floating-point environment and calls @var{thunk}.
+Saves the current floating-point environment if any and calls
+@var{thunk}.
 On exit from @var{thunk}, including non-local exit, saves
 @var{thunk}'s floating-point environment and restores the original
 floating-point environment as if with @code{flo:set-environment!}.
 On re-entry into @var{thunk}, restores @var{thunk}'s floating-point
 environment.
+
+@strong{Note:} @code{Flo:preserving-environment} @emph{does not} enter
+a per-thread environment.
+If the current thread is in the default environment, the exception
+flags are indeterminate, and remain so inside
+@code{flo:preserving-environment}.
+Callers interested in using the exception flags should start inside
+@code{flo:preserving-environment} by clearing them with
+@code{flo:clear-exceptions!}.
 @end deffn
 
 @node Floating-Point Exceptions, Floating-Point Rounding Mode, Floating-Point Environment, Fixnum and Flonum Operations
 @subsection Floating-Point Exceptions
 
-Floating-point computations such as arithmetic may raise exceptions.
+In @acronym{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, and, if the exception is trapped, signals a
-Scheme condition.
-Most machines support trapping exceptions, but not all --- for
-example, most ARM CPUs do not.
-In the default floating-point environment, no exceptions are trapped
-and no exceptions are raised.
+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.
+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.
@@ -2509,7 +2546,7 @@ 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.
+The inexact-result exception is never trappable in MIT/GNU Scheme.
 
 @item underflow
 @cindex underflow exception
@@ -2526,7 +2563,8 @@ therefore rounded to infinity.
 @item divide-by-zero
 @cindex divide-by-zero exception
 Raised on division of a nonzero finite real number by a zero real
-number, or logarithm of zero.
+number, or logarithm of zero, or other operation that has an unbounded
+limit at a point like division by a divisor approaching zero.
 
 @item invalid-operation
 @cindex invalid-operation exception
@@ -2583,11 +2621,15 @@ of exceptions by a list of human-readable symbols naming them.
 @deffn procedure flo:test-exceptions excepts
 Returns the set of exceptions in @var{excepts} that are currently
 raised.
+
+In the default environment, the result is indeterminate, and may
+be affected by floating-point operations in other threads.
 @end deffn
 
 @deffn procedure flo:clear-exceptions! excepts
 @deffnx procedure flo:raise-exceptions! excepts
-Clears and raises the exceptions in @var{excepts}.
+Clears or raises the exceptions in @var{excepts}, entering a
+per-thread environment.
 Other exceptions are unaffected.
 @end deffn
 
@@ -2596,7 +2638,8 @@ Other exceptions are unaffected.
 @deffnx procedure flo:test-exception-flags exceptflags excepts
 @code{Flo:save-exception-flags} returns a machine-dependent
 representation of the currently trapped and raised exceptions.
-@code{Flo:restore-exception-flags!} restores it.
+@code{Flo:restore-exception-flags!} restores it, entering a per-thread
+environment.
 @code{Flo:test-exception-flags} returns the set of exceptions in
 @var{excepts} that are raised in @var{exceptflags}.
 
@@ -2634,6 +2677,7 @@ currently trapped.
 @var{excepts} not be trapped.
 @code{Flo:set-trapped-exceptions!} replaces the set of trapped
 exceptions altogether by @var{excepts}.
+All three procedures enter a per-thread environment.
 
 @example
 @group
@@ -2659,7 +2703,8 @@ exceptions altogether by @var{excepts}.
 Dynamic-extent analogues of @code{flo:trap-exceptions!},
 @code{flo:untrap-exceptions!}, and @code{flo:set-trapped-exceptions!}.
 These call @var{thunk} with their respective changes to the set of
-trapped exceptions, and restore it on return or non-local exit.
+trapped exceptions in a per-thread environment, and restore the
+environment on return or non-local exit.
 @end deffn
 
 @deffn procedure flo:defer-exception-traps!
@@ -2667,9 +2712,9 @@ Saves the current floating-point environment, clears all raised
 exceptions, disables all exception traps, and returns a descriptor for
 the saved floating-point environment.
 
-This is typically used together with @code{flo:update-environment!},
-to trap any exceptions that the caller had wanted trapped only after a
-long intermediate computation.
+@code{Flo:defer-exception-traps!} is typically used together with
+@code{flo:update-environment!}, to trap any exceptions that the caller
+had wanted trapped only after a long intermediate computation.
 This pattern is captured in @code{flo:deferring-exception-traps}.
 @end deffn
 
@@ -2750,12 +2795,15 @@ Returns a list of the supported rounding modes as symbols.
 
 @deffn procedure flo:rounding-mode
 @deffnx procedure flo:set-rounding-mode! mode
-Gets or sets the current rounding mode as a symbol.
+Gets or sets the current rounding mode as a symbol, entering a
+per-thread environment.
 @end deffn
 
 @deffn procedure flo:with-rounding-mode mode thunk
-Call @var{thunk} with the rounding mode set to @var{mode}.
-On return, the rounding mode is restored to what it was before.
+Call @var{thunk} in a per-thread environment with the rounding mode
+set to @var{mode}.
+On return, the floating-point environment, including rounding mode, is
+restored to what it was before.
 
 Non-local exit from and re-entrance to @var{thunk} behaves as if the
 call is surrounded by @code{flo:preserving-environment}