by Peter McGoron
This SRFI is currently in draft status. Here is an explanation of each status that a SRFI can hold. To provide input on this SRFI, please send email to srfi-276@nospamsrfi.schemers.org. To subscribe to the list, follow these instructions. You can access previous messages via the mailing list archive.
This SRFI is an updated version of SRFI 144 that allows an implementation to support multiple flonum representations. Each flonum has its own separate library. Each library also has the ability to inspect properties of the flonum operations, such as rounding mode and deviations from IEEE 754 arithmetic. New flonum operations are also available, such as serialization and operations corresponding to IEEE 754-2019 and C23.
(flexpt 1.0 +nan.0)
⇒ 1.0 if the NaN is a quiet NaN. The quiet NaN is the one usually
returned from floating point operations. This conflicts with the
usual view of Scheme inexact numbers, where 1.0 is an
approximation of 1.0. How do we handle this?
This section is non-normative.
Standard Scheme doesn’t give specifics about the precision and range
of inexact numbers.
From the R4RS onward,
implementations could use s, f, d,
and l to denote inexact constants of different precisions.
The R6RS and
SRFI 144 included
“flonum” operations. However, these specifications do not specify what
the format of the flonum is. The flonum might not be an IEEE format
number and operations may differ from implementation to implementation.
This SRFI proposes a variant of SRFI 144 that is organized into
representation-specific libraries. The functions exported from
a specific library operate on a precisely defined number format. For
example, if one wanted to operate on binary64 floating point numbers,
one can import (srfi 276 binary64).
This SRFI also updates SRFI 144 to include the recommended procedures described in IEEE 754-2019, which are further included in C23. An implementation of this library can implement the new procedures as an FFI to C23: the definitions between this SRFI and C23 are harmonized.
One reason to use type-specific procedures is speed: the function
sqrt from (srfi 276 binary32) can be compiled
to a single FSQRT instruction on a RISC-V processor. One could also
compile multiple square roots to a single vectorized SQRTPS
instruction on an x86_64 processor with SSE2.
Another reason to use type-specific procedures is portability. Given the same rounding mode, format, and IEEE 754 conformance flag below, operations like +, -, and √ will always return the same value given the same inputs.
Most programmers do not have the speed and portability of floating point operations as their top priorities. They want their floating point calculations to work well above blazing speeds or bit-for-bit reproducibility across architectures. Basically, floating-point should do “what they want.” A type-flexible system is more likely to do what the non-numerically inclined programmer wants: see Kahan 1997 p. 29 and Kahan and Darcy 1998 pp. 60ff.
Scheme’s module system, lack of special arithmetic syntax, and latent
typing allow us to separate strict correctness and “do what I want.”
Programmers who wish
for their programs to do “what they want” should use Scheme’s generic
arithmetic. An implementation is free to do things like widen operands
or optimize expressions (for example, using the SSE2 instruction
RSQRTPS for (/ 1 (sqrt x))) without worrying
about strict reproducibility or the absolute fastest speed.
This SRFI defines procedures that mirror functions in C23’s math library, which are in turn based off of IEEE 754-2019’s recommended functions. These functions are expected to be widely available with stable implementations.
There are many, many special functions that exist, such as the functions in TR24747 and SciPy. They are not included in this SRFI, as they are very specialized and there might not be enough experience with them to standardize an interface and domain. Hopefully with this library as a standard component of Scheme implementations, the entire range of special functions can be implemented in pure Scheme.
All references to IEEE 754 refer to its 2019 revision.
A representation is a type of inexact number that has fixed properties, like exponent range and mantissa width. Examples include binary32, binary64, and posit32 (Gustafson 2022).
An operation is correctly rounded if the returned value is the same as if the operation were calculated to infinite precision, and then rounded to fit in the resulting representation according to the current rounding mode.
Signaling NaN and quiet NaN are defined in the IEEE 754: implementations and representations should differentiate between the two. If an implementation or representation does not differentiate between the two, then all NaNs must be considered quiet. Thus, if an implementation has only quiet NaNs, then statements about the behavior of procedures on signaling NaNs do not apply.
A floating-point exception is a flag in an environment that is raised if a floating point operation does something exceptional, such as overflow. They are not the same as Scheme exceptions. Some operations raise a floating-point exception on certain arguments. Implementations that support the floating point exception library should raise floating-point exceptions when generic arithmetic is done in such a way that would raise the exception when using the floating point library.
If an implementation does not support the floating point environment library, then it does not need to implement the exception behavior as described in the library section. Additionally, an implementation may support other exception handling modes, such as raising a Scheme exception when a floating-point exception is raised. However, every implementation must support a non-stop mode, where all operations return values when given the correct argument types.
When an operation is implementation defined, then the implementation should document what choice or procedure they use for that behavior. For example, the implementation should document the default rounding mode.
The examples in the SRFI use an extension to the syntax of Scheme datums that explicitly states the representation of a flonum. This extension might be useful on implementations with wildly varying representations flonum, such as decimal floats or posit numbers.
The following modification to the grammar implements this representation:
⟨real R⟩ → … | ⟨real numeral R⟩
| ⟨represented flonum R⟩
⟨real numeral R⟩ → ⟨sign⟩ ⟨ureal R⟩ | ⟨infnan⟩
⟨represented flonum R⟩ → #fl( ⟨representation name⟩ ⟨real numeral R⟩ )
⟨representation name⟩ → binary16 | binary32 | …
For example, #fl(binary256 1e400) reads as a finite number,
while #fl(binary64 1e400) reads the same as #fl(binary64 +inf.0).
The syntax allows for complex numbers to be written with mixed precision: for example,
#fl(binary32 1.0)+#fl(binary64 2.0)i.
Implementing this reader syntax is not a requirement for supporting this SRFI. The sample implementation does not have an implementation of this syntax.
The argument names have the same meanings as the R7RS; it is an error if the wrong arguments are passed to a procedure. It is an error if:
flinteger?)
rounding-mode?)
little, big, or an endianness
supplied by the macro in (rnrs bytevectors)flexception-name?)flenvironment?)Square brackets [] are used to denote a group of arguments that are optional, but all arguments must be present or absent. If one pair of square brackets is nested in another pair, then the nested pair is optional even when the other arguments are supplied.
When endianness is not supplied in a procedure, it is the native endianness, which is an implementation-specified valid value.
The implementation must export the following libraries:
(srfi 276)The following library names, if available, must implement the library described in the sections below.
(srfi 276 binary16)(srfi 276 binary32)(srfi 276 binary64)(srfi 276 binary128)(srfi 276 binary256)The following library names are reserved (where ⟨n⟩ is a base-10 numeral). They are reserved because some of the functions in the flonum library may not be appropriate for these format numbers. A future SRFI or Report will define operations on these representations.
(srfi 276 decimal⟨n⟩)(srfi 276 complex-⟨format⟩⟨n⟩) where ⟨format⟩ is either binary or decimal(srfi 276 binary⟨n⟩) for ⟨n⟩ not previously definedThe following libraries are optional, but if present, must export identifiers that act as described:
(srfi 276 rounding-mode)(srfi 276 with-rounding-mode)(srfi 276 set-rounding-mode)(srfi 276 exceptions)(srfi 276 environment)
An implementation may provide libraries with different
names than the ones above. Such a library should
implement all of the procedures described below. For example,
an implementation could provide (srfi 276 posit32) for
operations on posits, with a similar API to the one below. However,
posits do not have infinite values, so flinfinite? would
not be exported.
The floating-point libraries are an extension of SRFI 144. Unlike SRFI 144, this library can be used for representations of any radix, in particular 2 and 10. However, this library does not define quantization or reencoding procedures for decimal numbers. This library assumes that the floating point format is similar to the IEEE formats.
Rationale:
For compatability with previous code and familiarity, the procedures
retain their fl prefixes, even though there may be
multiple procedures in different libraries with the same name. This
is because most implementations only have one floating point type.
Previous versions of this SRFI removed the fl prefix
and instead prefixed everything with :. This has been
reverted because it optimized for the uncommon case, and not to
mention was somewhat unsightly.
Throughout all code examples, when the floating point representation
is important, the identifiers will be prefixed with
f64: for binary64 numbers, and f32: for
binary32 numbers. All other prefixes will be defined by import
statements in the example code.
This SRFI does not require that implementations support all the NaN operations and values that IEEE 754-2019 supports. Implementations that do support the full range of NaN values should implement SRFI 208, which is designed to support multiple inexact real formats.
By default, all operations that return flonums will return a quiet NaN if they are given a quiet NaN in any input. Any exceptions are noted. Implementations should propagate NaNs if they have one or more NaN inputs.
By default, giving a signaling NaN to a procedure will cause the invalidOperation floating point exception to be raised and will cause a NaN to be returned.
It is unspecified what the sign of a NaN is. Implementations should
make +nan.0 have a positive sign, and -nan.0
have a negative sign, and have that sign be reflected in the machine
representation of the NaN.
The numeric constants of SRFI 144 are exported for the number type of this library. The following are renamed:
| Old | New |
|---|---|
fl-e-2 | fl-e^2 |
fl-e-pi/4 | fl-e^pi/4 |
fl-pi-squared | fl-pi^2 |
fl-e-euler | fl-e^euler |
The identifiers
fl-e,
fl-1/e,
fl-log2-e,
fl-log10-e,
fl-log-2,
fl-1/log-2,
fl-log-3,
fl-log-pi,
fl-log-10,
fl-1/log-10,
fl-pi,
fl-1/pi,
fl-2pi,
fl-pi/2,
fl-pi/4,
fl-2/sqrt-pi,
fl-degree,
fl-2/pi,
fl-sqrt-2,
fl-sqrt-3,
fl-sqrt-5,
fl-sqrt-10,
fl-1/sqrt-2,
fl-cbrt-2,
fl-cbrt-3,
fl-4thrt-2,
fl-phi,
fl-log-phi,
fl-1/log-phi,
fl-euler,
fl-sin-1,
fl-cos-1,
fl-gamma-1/2,
fl-gamma-1/3, and
fl-gamma-2/3
are defined by the same formulas as their corresponding SRFI 144
identifiers.
fl-radix
Radix of the floating point representation. For binary representations such as binary64, this is 2. The variable b is set to this value throughout this SRFI.
fl-precision
Length of the significand of the floating point representation.
fl-maximum-exponent
The maximum exponent a normalized floating point number, represented as (-1)s(s0.s1…)×2e can have, represented as an exact integer. For binary64 numbers, this is 1023.
fl-minimum-normalized-exponent
The minimum exponent a normalized floating point number,
represented as (-1)s(s0.s1…)×2e
can have, represented as an exact integer. For IEEE 754 representations, this is
(- 1 fl-maximum-exponent).
fl-minimum-exponent
The minimum exponent of any non-zero floating point number.
fl-greatest
The largest normalized floating point number.
fl-least
The smallest positive floating point number. This number may not be normalized.
fl-least-normal
The smallest positive normal floating point number.
fl-epsilon
The difference between 1.0 and the least normalized value greater than
1.0 that is representable in this type. This is defined as
(fl- (fladjacent 1.0 +inf.0) 1.0).
fl-byte-width
Size of the flonum in bytes as an exact integer. For the binary64 representation, this is 8.
(flonum z)
Convert a number into a flonum.
If z is not real, then a NaN is returned.
If z is exact, then it is converted to inexact before the following rules are applied.
If z is a signed zero, return a zero flonum with the sign of z.
If z is a finite number, and there is a flonum that is
equal to it in the sense of =, return that flonum.
If z is a finite number that is between two flonums, return the closest flonum, rounding in an implementation defined manner.
If z is a finite number that is greater than all flonums, or less than all flonums, either the closest flonum or the appropriately signed infinity is returned.
If z is an infinite number, then return an infinite flonum with the appropriate sign.
If z is a NaN, return a NaN.
(fladjacent fl1 fl2)
If fl1 = fl2, returns fl2.
Otherwise return the next representable flonum from fl1 in the direction of fl2.
(f64:fladjacent 1.0 +inf.0) ⇒ #fl(binary64 1.0000000000000002)
(flcopysign fl1 fl2)
Return a number with the magnitude of fl1 and the sign of fl2.
Even when fl1 is a signaling NaN, this procedure does not signal invalidOperation.
(flcopysign +inf.0 -1.0) ⇒ -inf.0(flcopysign +0.0 -1.0) ⇒ -0.0
(make-flonum fl n)
Return fl×bn correctly rounded.
The allowed values of n are implementation-dependent and
may depend on fl. However, this procedure must round-trip
with flnormalized-fraction-exponent.
This procedure raises no floating-point exceptions when given NaNs.
ldexp, where it always scaled by a power of 2.
This has been changed to the behavior of scalbn,
because it is more general. When the radix is 2, this procedure
and make-flonum in SRFI 144 are equivalent.
(flinteger-fraction fl)
Returns two values, the integral part of fl as a flonum and the fractional part of fl as a flonum.
If fl is zero, the procedure returns fl for both values.
If fl is infinity, the integral part is fl, and
the fractional part is (flcopysign 0.0 fl).
If fl is a NaN, then a NaN is returned for both values.
(flexponent fl)
Returns the exponent of fl as a flonum. If fl is subnormal, it is treated as though it were normalized.
If fl is zero, then negative infinity is returned and a divide-by-zero floating point exception is signalled.
If fl is infinity, return fl.
(flnormalized-fraction-exponent fl)
Returns two values, a correctly signed fraction y whose absolute value is in [1/b,1), and an exact integer exponent e such that fl = y×bn.
If fl is zero, returns fl and exact zero.
If fl is infinite, returns fl and an unspecified integer.
If fl is NaN, returns a NaN and an unspecified integer.
flnormalized-fraction-exponent in SRFI 144 and
frexp in C.
(flinteger-exponent fl)
fl-integer-exponent-zero
fl-integer-exponent-nan
Returns the same as flexponent
as an exact integer.
When fl is zero, returns fl-integer-exponent-zero,
which is a negative exact integer less than the smallest exponent
returned by a finite value.
When fl is NaN, returns fl-integer-exponent-nan,
which is an exact integer whose magnitude is larger than the magnitude
of any exponent returned by a finite value.
When fl is infinite, returns an unspecified integer larger than the magnitude of any exponent returned by a finite value.
(flsign-negative? fl)
Returns true if the sign of fl is negative, and false otherwise.
flsignbit returned 1
for a negative sign and 0 otherwise.
Unless otherwise specified, none of these procedures raise exceptions when given signaling NaNs.
(flonum? obj)
Returns #t if obj is a flonum and
#f otherwise.
These procedures return #t if their arguments are
(respectively): equal, monotonically increasing, monotonically
decreasing, monotonically nondecreasing, or monotonically nonincreasing;
they return #f otherwise. These predicates must be
transitive.
When passed zero or one arguments, they always return true, even when that number is NaN.
When passed two or more arguments where one of them is a signaling NaN, the procedures raise the invalidOperation floating-point exception.
When all operations except fl=? are passed a quiet NaN,
the procedures raise the invalidOperation floating-point exception.
If NaN is passed as an argument to these procedures (when the number of arguments is greater than 1), the procedure returns false. A NaN is not equal to itself.
Positive infinity compares greater than any finite number. Negative infinity compares less than any finite number.
This predicate returns #t when the two values are not equal.
When passed a signaling NaN, this procedure raises the invalidOperation
floating-point exception. When given NaN values, this procedure returns
#f.
Rationale:
Since NaNs are unordered, (not (fl=? fl1 fl2))
is not the same as
(fl!=? fl1 fl2).
(fltotal=? fl …)(fltotal<? fl …)(fltotal>? fl …)(fltotal<=? fl …)(fltotal>=? fl …)Imposes a total ordering on flonums consistent with IEEE 754. The following describes the order:
(fl<? fl1 fl2)
returns #t, then
(fltotal<? fl1 fl2) returns
#t.
(fltotal<? -0.0 +0.0) returns #t.
(fltotal<? +0.0 -0.0) returns #f.
eqv?,
then (fltotal=? fl1 fl2)
returns #t.
(fltotal<? nan fl)
evaluates to #t.
(fltotal<? nan fl)
evaluates to #f.
eqv? NaNs,
then it is unspecified which one occurs after the other in the
ordering.
Although the ordering is underspecified, any implementation must make
choices consistent with the fact that fltotal<? is a
total ordering that respects trichotomy. Implementations should order NaNs according
to their sign and if they are signalling/quiet, as described in
IEEE 754, and should order NaNs with the same sign and
signalling/quiet status by the total ordering of their unsigned integer
payloads.
There is no requirement that the order be total when one of the arguments is a non-canonical flonum.
Rationale: A total ordering on flonums is useful for when the flonums are stored in a set structure.
When the numbers are in a IEEE 754 binary floating point representation, then for non-NaN flonums fl1 and fl2 that are not both zero, the regular and total orderings coincide. The definition is written so that the ordering is forwards compatible with IEEE 754 decimal floats, which have numerically equal yet bitwise-unequal numbers, and also non-canonical encodings. The total ordering of decimal floats is more complicated.
(flunordered? fl1 fl2)
This procedure returns #t if one of its arguments is
a NaN, and #f otherwise.
(flinteger? fl)
Returns #t when the argument is an integer flonum, and
#f otherwise.
(flzero? fl)
Returns #t when the argument is a zero, and
#f otherwise.
(flpositive? fl)
Returns #t when the argument is greater than 0, and
#f otherwise.
(flnegative? fl)
Returns #t when the argument is less than 0, and
#f otherwise.
(flnegative? -0.0) ⇒ #f
(flodd? ifl)
Returns #t when the argument is odd, and
#f otherwise.
(fleven? ifl)
Returns #t when the argument is even, and
#f otherwise.
(flfinite? fl)
Returns #t if fl has a finite value: that is,
if it is not infinite or NaN,
and #f otherwise.
(flinfinite? fl)
Returns #t if fl is infinite,
and #f otherwise.
(flnan? fl)
Returns #t if fl is a NaN,
and #f otherwise.
(flnormal? fl)
Returns #t if fl is a normalized number: that
is, it is not subnormal, zero, infinite, or NaN, and #f
otherwise.
Note:
This procedure was renamed from flnormalized?
in SRFI 144.
(flsubnormal? fl)
Note:
This procedure was renamed from fldenormalized?
in SRFI 144.
Returns #t if fl is a subnormal number, and
#f otherwise.
(flmax fl …)(flmax-abs fl …)(flmax-filter-nans fl …)(flmax-abs-filter-nans fl …)(flmin fl …)(flmin-abs fl …)(flmin-filter-nans fl …)
(flmin-abs-filter-nans fl …)
Returns the maximum/minimum value of the argument of the list of arguments. For the purposes of this procedure, negative zero is less than positive zero.
For the maximum procedures, if no value is given, they return negative infinity. For the minimum procedures, if no value is given, they return positive infinity.
If flmax or flmin have a NaN in any of its
arguments, then a NaN is returned.
If either flmax-filter-nans or flmin-filter-nans
have a NaN in its arguments, it is ignored unless all inputs are NaNs,
in which case a NaN is returned.
The procedures with abs in the name compare two non-NaN
arguments by absolute value. If the two arguments are equal in magnitude,
they are then compared by the procedure without abs in
the name.
flmax/flmin procedures correspond
to the R6RS’s
flmax/flmin, while the
flmax-filter-nans/flmin-filter-nansprocedure
corresponds to the flmax/flmin procedure in
SRFI 144.
Return the sum of the arguments. If no arguments are given, positive zero is returned. If one argument is given, that argument is returned. The following special cases apply:
(fl+ fl fl)
returns fl.The following examples assume that the rounding mode is not roundTowardsNegative.
(fl+ 0.0 -0.0) ⇒ +0.0(fl+ -0.0 0.0) ⇒ +0.0(fl+ -0.0 -0.0) ⇒ -0.0
When given two arguments, this procedure always returns the correctly rounded value. When given more than two arguments, the implementation may rearrange arguments or use an algorithm like compensated summation to minimize error.
When one argument is given, the value is returned with the sign bit
flipped.
When more than one argument is given, the procedure is the equivalent
of (fl+ fl1 (fl- fl2) …).
When given no arguments, returns positive 1.0. When given one argument, returns that argument.
When given more than one argument, computes the product of the arguments. When no argument is NaN and no operation returns a NaN, the returned sign is the exclusive OR of the sign bits of each argument. The following special cases apply:
When given two arguments, this procedure always returns the correctly rounded value. When given more than two arguments, the implementation may rearrange arguments or use an alternative algorithm to minimize error.
When given one argument, computes the reciprocal of the given argument. The reciprocal of infinity is the appropriately signed zero, and the reciprocal of zero is the appropriately signed infinity.
When given more than one argument, divides the first argument by the rest. The returned sign, when the number is not NaN, is the exclusive OR of the signs of the input arguments. The following special cases apply:
When given one or two arguments, the correctly rounded value is returned.
Return fl1*fl2+fl3 correctly rounded.
When the value of the operation is exactly zero, it has the same rule for the sign of zero as the sum operation. If the value is rounded to zero, it takes the sign of the exact result.
If, interpreted separately, the sum or multiplication would return a NaN, then this operation will return a NaN.
Returns the absolute value of fl. The absolute value of any zero is positive zero, and the absolute value of any infinity is positive infinity.
Returns |fl1 - fl2|.
The behavior on infinities, zeroes, and NaNs is equivalent to the behavior
of (flabs (fl- fl1 fl2)).
Let x = fl1 - fl2. If x is positive, return it. If x is a NaN, return that NaN. Otherwise return positive zero.
Equivalent to (flcopysign 1.0 fl).
Returns the numerator/denominator of fl as a flonum. The numerator and denominator must represent fl in lowest terms, although any pair of numbers that when divided yield fl in the current rounding mode is acceptable, subject to the constraints below.
The denominator is always positive. The numerator of an infinite flonum is itself. The denominator of an infinite or zero flonum is 1.0. The numerator and denominator of a NaN is a NaN.
(flfloor fl)(flceiling fl)(fltruncate fl)(flround fl)(flround-away fl)These procedures find an integer near fl. When given an infinity or zero, these procedures always return that value. When given a NaN, they return a NaN.
The flfloor procedure returns the greatest integer flonum
not larger than fl.
The flceiling procedure returns the least integer flonum
not larger than fl.
The fltruncate procedure returns the closest integer flonum
whose absolute value is not not larger than the absolute value of fl.
The flround procedure returns the closest integer flonum: when
fl is halfway between two integers, it rounds to even.
The flround-away procedure returns the closest integer
flonum: when fl is halfway between two integers, it rounds
to the number further from zero.
(flround-away 2.5)⇒ 3.0(flround 2.5)⇒ 2.0(flround-away 3.5)⇒ 4.0(flround 3.5)⇒ 4.0
Note: The flround procedure
in the R6RS and
SRFI 144 implements
Scheme’s round ties-to-even behavior, which is the
behavior of roundeven in C11.
The following special cases apply to the procedures in this section:
| Operation | Side conditions | Exceptions | Return |
|---|---|---|---|
(⟨prefix⟩-remainder ±0.0 y) |
y ≠ 0.0 | ±0.0 |
|
(⟨prefix⟩-remainder x y) |
y = 0 | invalidOperation | NaN |
(⟨prefix⟩-remainder x y) |
x infinite | invalidOperation | NaN |
(⟨prefix⟩-remainder x ±inf.0) |
x is finite | x | |
(⟨prefix⟩-quotient x ±inf.0) |
x is finite | (flcopysign 0.0 x) |
Let q = truncate(fl1/fl2) and let r be a flonum such that fl1 = qfl2 + r.
Then fltruncate-quotient returns q and
fltruncate-remainder returns r. The remainder
is always correctly rounded.
Rationale:
These procedures are renamed from
flquotient and flremainder in SRFI 144.
Let q = roundtoeven(fl1/fl2) and let r be a flonum such that fl1 = qfl2 + r.
This procedure returns two values: a correctly signed integer whose magnitude is congruent to the magnitude of q modulo k, where k ≥ 3, and the correctly rounded remainder.
Let q = roundtoeven(fl1/fl2) and let r be a flonum such that fl1 = qfl2 + r.
Then flround-quotient returns q and
flround-remainder returns r. The remainder
is always correctly rounded.
Returns afl, where a is respectively the mathematical constant e, 2, or 10.
If the argument is positive infinity, the result is positive infinity. If the argument is negative infinity, the result is positive 1.
Returns afl − 1, where
a is respectively the mathematical constant e, 2, or 10.
It is expected that this will be more accurate than
(fl- (flexp fl) 1.0) etc when
fl is small.
If the argument is positive infinity, the result is positive infinity. If the argument is negative infinity, the result is positive 0.
Returns fl1fl2. The following special cases apply:
| Operation | Side conditions | Exceptions | Return |
|---|---|---|---|
(flexpt x ±0.0) |
x is not NaN | 1.0 | |
(flexpt ±0.0 y) |
y < 0, y odd | divideByZero | ±inf.0 |
(flexpt ±0.0 −inf.0) |
+inf.0 |
||
(flexpt ±0.0 +inf.0) |
+0.0 |
||
(flexpt ±0.0 y) |
y > 0, y odd | ±inf.0 |
|
(flexpt −1.0 ±inf.0) |
1.0 |
||
(flexpt +1.0 y) |
y is not NaN | 1.0 |
|
(flexpt x +inf.0) |
−1 < x < 1 | +0.0 |
|
(flexpt x +inf.0) |
x < −1 or for 1 < x | +inf.0 |
|
(flexpt x −inf.0) |
−1 < x < 1 | +inf.0 |
|
(flexpt x +inf.0) |
x < −1 or for 1 < x | +0.0 |
|
(flexpt +inf.0 y) |
y < 0 | +0.0 |
|
(flexpt +inf.0 y) |
y > 0 | +inf.0 |
|
(flexpt −inf.0 y) |
y < 0, y odd | -0.0 |
|
(flexpt −inf.0 y) |
y > 0, y odd | -inf.0 |
|
(flexpt −inf.0 y) |
y < 0, y finite, not odd | +0.0 |
|
(flexpt −inf.0 y) |
y > 0, y finite, not odd | +inf.0 |
|
(flexpt ±0.0 y) |
y < 0 and y finite, not odd | divideByZero | +inf.0 |
(flexpt ±0.0 y) |
y > 0, y finite and not odd | +0.0 |
|
(flexpt x, y) |
finite x < 0, finite non-integer y | invalid operation | NaN |
Let nan be a quiet NaN.
It is unspecified if (flexpt nan ±0.0)
returns 1.0 or a NaN.
It is unspecified if (flexpt 1.0 nan)
returns 1.0 or a NaN.
Rationale:
IEEE 754 mandates that (flexpt nan ±0.0)
and (flexpt 1.0 nan)
returns 1.0. This rule allows for the usual Scheme
rule, where an inexact operation on NaNs returns NaN, while also
allowing for an implementation to FFI into an IEEE 754 math library,
which provides this rule.
Returns loga(fl), where a is respectively the mathematical constant e, 2, or 10.
If the argument is positive infinity, the result is positive infinity. If the argument is negative 1, the result is negative infinity, and a divide-by-zero exception is raised. If the argument is less than negative 1, NaN is returned, and an invalid exception is raised.
Returns loga(fl + 1), where a
is respectively the mathematical constant e, 2, or 10.
It is expected that this will be more accurate than
(fllog (fl+ 1.0 fl)) etc when
fl is small.
If the argument is positive infinity, the result is positive infinity. If the argument is zero, the result is negative infinity, and a divide-by-zero exception is raised. If the argument is negative, NaN is returned, and an invalid exception is raised.
Note:
The procedure fllog+1 is renamed from the procedure
fllog1+ in SRFI 144.
Returns a procedure that computes the base fl logarithm of
its input, with similar rules applied to infinities, NaNs, and negative
arguments as fllog. It is an error
if fl is less than 1.0.
Calculate fl1/3. When passed a zero or an infinity, returns the argument.
Calculate (1 + fl)n. It is expected that
this function is more accurate than
(flexpt (fl+ 1.0 fl) n)
when fl is small. The following special cases apply:
| Operation | Side conditions | Exceptions | Return |
|---|---|---|---|
(flcompound x 0.0) |
x ≥ -1 | 1.0 | |
(flcompound x n) |
x < -1, n ≠ 0 | invalidOperation | NaN |
(flcompound -1.0 n) |
n < 0 | divideByZero | +inf.0 |
(flcompound -1.0 n) |
n > 0 | +0.0 |
|
(flcompound +inf.0 n) |
n > 0 | +inf.0 |
|
(flcompound +inf.0 n) |
n < 0 | +0.0 |
Let nan be a quiet NaN.
It is unspecified if (flcompound nan ±0.0)
returns 1.0 or NaN.
Calculate √(fl12 + fl22).
If one argument is zero, the returned value is the absolute value of the other argument.
If one argument is infinity, then the returned value is infinity, even if another value is NaN.
Calculates 1/√fl. When passed zero, returns the appropriately signed infinity and raises the divideByZero floating point exception. When passed positive infinity, returns positive zero. When passed a negative number, returns a NaN and raises the invalidOperation floating point exception.
Note: Reciprocal square root is available in many CPUs as a hardware operation.
Returns √fl. This function always returns a correctly rounded result. When passed a zero, returns that zero. When passed positive infinity, returns positive infinity. When passed a negative number, returns NaN and raises the invalidOperation floating-point exception.
Return the respective value at that point for the trigonometric function, with the argument measured in radians.
When an infinity is passed to any of these functions, NaN is returned and the invalidOperation floating point exception is raised.
When sin or tan are given zero, return that zero.
Return sin(πfl).
When given a zero, return that zero. When given a positive integer, return positive zero. When given a negative integer, return negative zero.
When an infinity is passed to this function, NaN is returned and the invalidOperation floating point exception is raised.
Return cos(πfl).
Let fl = n + ½, where n is an integer. Then this function returns positive zero.
When an infinity is passed to this function, NaN is returned and the invalidOperation floating point exception is raised.
Return the value of tan(πfl). The following special cases apply:
| Operation | Side conditions | Exceptions | Return |
|---|---|---|---|
(fltanpi ±0.0) |
±0.0 |
||
(fltanpi n) |
n is positive and even, or negative and odd | +0.0 |
|
(fltanpi n) |
n is positive and odd, or negative and even | +0.0 |
|
(fltanpi x) |
x = n + 1/2 for even n | divideByZero | +inf.0 |
(fltanpi x) |
x = n + 1/2 for odd n | divideByZero | +inf.0 |
Compute the arcsine of the argument. When given a zero, return that zero. When given a value whose absolute value is greater than 1, return a NaN and raise the invalidOperation floating point exception.
The function flasinpi is defined as asin(fl)/π.
Compute the arccosine of the argument. When given a zero, positive one. When given a value whose absolute value is greater than 1, return a NaN and raise the invalidOperation floating point exception.
The function flacospi is defined as acos(fl)/π.
When given one argument, compute the arctan of the argument. At infinity, return the closest approximation to ±π/2.
When given two arguments, compute the atan2 function. When one of the arguments is a zero, returns the appropriate value from the atan table in the R7RS. The following special cases are added to the table:
| Operation | Side conditions | Return |
|---|---|---|
(flatan y -inf.0) |
finite nonzero y | (flcopysign π/2 y) |
(flatan y +inf.0) |
finite nonzero y | (flcopysign 0.0 y) |
(flatan ±inf.0 x) |
finite x | (flcopysign π/2 ±inf.0) |
(flatan ±inf.0 -inf.0) |
(flcopysign 3π/4 ±inf.0) |
|
(flatan ±inf.0 +inf.0) |
(flcopysign π/4 ±inf.0) |
The function flatanpi is the same as flatan
except that the output of atan is divided by π.
(flsinh fl)
Return sinh(fl).
When passed zero, return that zero. When passed infinity, return that infinity.
(flcosh fl)
Return cosh(fl).
When passed zero, return 1. When passed infinity, return positive infinity.
(fltanh fl)
Return tanh(fl).
When passed zero, return that zero. When passed infinity, return
(flcopysign 1.0 fl).
(flasinh fl)
Return asinh(fl).
When passed zero, return that zero. When passed infinity, return that infinity.
(flacosh fl)
Return acosh(fl).
When passed 1, return positive zero. When passed positive infinity, return positive infinity.
When passed a value less than 1, return a NaN and raise the invalidOperation floating-point exception.
(flatanh fl)
Return acosh(fl). The following special cases apply:
| Operation | Side conditions | Exceptions | Return |
|---|---|---|---|
(atanh ±0.0) |
±0.0 |
||
(atanh ±1.0) |
divideByZero | ±inf.0 |
|
(atanh x) |
|x| > 1 | invalidOperation | NaN |
(flerf fl)
Calculate
The following special cases apply:
| Operation | Side conditions | Return |
|---|---|---|
(flerf ±0.0) |
±0.0 |
|
(flerf ±inf.0) |
±1.0 |
(flerfc fl)
Calculate 1 − erf(fl). The following special cases apply:
| Operation | Side conditions | Return |
|---|---|---|
(flerfc -inf.0) |
+2.0 |
|
(flerf +inf.0) |
+0.0 |
(flgamma fl)
Computes
The following special cases apply:
| Operation | Side conditions | Exceptions | Return | |
|---|---|---|---|---|
(flgamma ±0.0) |
divideByZero | ±inf.0 | ||
(flgamma x) |
x is a negative and an integer or infinity | invalidOperation | NaN | |
(flgamma +inf.0) |
+inf.0 |
(fllog-gamma fl)
Returns two values: loge|Γ(fl)| and the sign of Γ(fl) times 1.0. The following special cases apply:
| Operation | Side conditions | Exceptions | Return |
|---|---|---|---|
(fllog-gamma 1.0) |
0.0 |
||
(fllog-gamma 2.0) |
0.0 |
||
(fllog-gamma x) |
x is a negative integer or 0 | invalidOperation | NaN |
(fllog-gamma ±inf.0) |
+inf.0 |
Calculate the nth bessel function of the first/second kind, respectively.
| Operation | Side conditions | Exceptions | Return |
|---|---|---|---|
(flfirst-bessel +inf.0 n) |
invalidOperation | NaN | |
(flsecond-bessel +inf.0 n) |
invalidOperation | NaN | |
(flsecond-bessel x n) |
x is zero | divideByZero | -inf.0 |
(flsecond-bessel x n) |
x is negative | invalidOperation | NaN |
(flfeatures)
Returns a list containing information about the floating-point operations in this library. The following symbols have defined meanings. An implementation may add other features, which should be symbols.
subnormals-are-zeroflush-to-zeroieee-754-2019subnormals-are-zero or flush-to-zero
appear.non-stopfast-fma(fl+* x y z) is at least as fast as or faster
than (fl+ (fl* x y) z). (Fused multiply-add must be rounded
correctly when IEEE 754 compliance mode is on, regardless of
whether fast-fma is available.)⟨name⟩-correctly-rounded where ⟨name⟩ is a procedure from the
libraryieee-754-2019 appears, then features corresponding
to functions the IEEE 754 be correctly rounded must not
appear.)Note: DAZ/FTZ modes are usually enabled by the compiler, or are baked-in features of the architecture. As such, this SRFI does not provide a portable way to manipulate this mode.
This should not be confused with the
features
procedure in the R7RS.
This is a run-time procedure that reports on the run-time environment,
and the flags may change over the runtime of the program.
These flags are not accessible through cond-expand.
(bytevector-flonum-ref
bv
k
[endianness])
It is an error if k to k +
flbyte-width
are not valid indices of bv.
If endianness is not supplied, it is an error if
k is not a multiple of flbyte-width.
Read the bytes in bv at k as a flonum of this type, with the endianness.
If the value is a NaN, then the NaN should not be coerced into another NaN.
(import (scheme base) (prefix (srfi 276 binary64) f64:)) (define bv (make-bytevector f64:flbyte-width)) (bytevector-u8-set! bv 0 #b01000000) (bytevector-u8-set! bv 1 #b00001001) (bytevector-u8-set! bv 2 #b00100001) (bytevector-u8-set! bv 3 #b11111011) (bytevector-u8-set! bv 4 #b01010100) (bytevector-u8-set! bv 5 #b01000100) (bytevector-u8-set! bv 6 #b00101101) (bytevector-u8-set! bv 7 #b00011000)(f64:bytevector-flonum-ref bv 0 'big)⇒ #fl(binary64 3.141592653589793116)
Rationale: Some implementations, in particular those that use NaN boxing, may only be able to represent a limited set of NaNs. Different systems may have different canonical NaNs. For these reasons portable code should not expect that different NaNs are distinguishable.
(bytevector-flonum-set!
bv
k
fl
[endianness])
It is an error if k to k +
byte-width
are not valid indices of bv.
If endianness is not supplied, it is an error if
k is not a multiple of byte-width.
Write fl to bv at k with endianness.
This procedure and
bytevector-flonum-ref
must to round-trip on all non-NaNs. That is, given a non-NaN flonum fl,
(let ((bv (make-bytevector flbyte-width)))
(bytevector-flonum-set! bv 0 fl)
(eqv? fl (bytevector-flonum-ref bv 0)))
always evaluates to #t. These procedures
should round-trip NaNs.
(import (scheme base) (prefix (srfi 276 binary32) f32)) (define bv (make-bytevector f32:flbyte-width)) (f32:bytevector-flonum-set! bv 0 #fl(binary32 1.41421353816986083984) 'little)bv⇒ #u8(#xf3 #x04 #xb5 #x3f)
(string->flonum
string
[radix])
It is an error if radix is not 2, 8, 10, or 16. The value of radix defaults to 10.
Read string as a number in that representation. This
procedure must round-trip with number->string.
(import (scheme base) (prefix (srfi 276 binary64) f64) (prefix (srfi 276 binary128) f128))(f128:string->flonum "1e400")⇒ #fl(binary128 1e400)(f64:string->flonum "1e400")⇒ #fl(binary64 +inf.0)(let ((v #fl(binary128 1e400))) (eqv? (f128:string->flonum (number->string v)) v))⇒ #t
Note:
There is no flonum->string procedure, as
number->string is already polymorphic.
(current-rounding-mode)
Returns the current rounding mode. This SRFI defines the following symbols which can be returned from this procedure. An implementation may add other rounding modes, which should be symbols. For example, an implementation with support for GNU MPFR may add MPFR's additional rounding modes.
round-to-nearest/ties-to-evenround-to-nearest/ties-to-awayround-towards-positiveround-towards-negativeround-towards-zeroNote: The rounding mode is independent of the behavior of the integer rounding functions and the integer division functions.
(rounding-mode? obj)
Returns #t if obj is a valid rounding mode,
and #f otherwise.
(with-rounding-mode rounding-mode body …)
Evaluate rounding-mode to a rounding mode. Then evaluate body … with that rounding mode in its dynamic extent. If the dynamic extent is exited, the rounding mode is restored to what it was previously. If the dynamic extent is re-entered, the rounding mode is restored back to the value that rounding-mode was evaluated to.
As an example, here is how a simplified form of
fltruncate-quotient
could be implemented:
(define (fltruncate-quotient fl1 fl2)
(let ((trial (fl/ fl1 fl2)))
(if (flinfinite? trial)
trial
(with-rounding-mode 'round-towards-zero
(fltruncate (fl/ fl1 fl2))))))
Rationale: If the operations in the dynamic extent are just procedures from this SRFI, then instead of setting the global rounding mode, then implementations on certain processors like RISC-V can compile the functions to instructions with specific rounding modes. See Zurstraßen 2023.
(set-rounding-mode! rounding-mode)
Sets the global rounding mode to rounding-mode. On implementations with multithreading, the rounding mode should be specific to a thread and not to the whole program.
For example, with-rounding-mode
could be implemented as
(define-syntax with-rounding-mode
(syntax-rules ()
((_ rounding-mode body1 body2 ...)
(let ((r rounding-mode)
(p (flrounding-mode)))
(dynamic-wind
(lambda () (set-rounding-mode! r))
(lambda () body1 body2 ...)
(lambda () (set-rounding-mode! p)))))))
(flexception-name? obj)
Returns #t if the object is a floating point exception,
and #f otherwise. The following are the standard
floating point exceptions:
invalid-operationdivide-by-zerooverflowunderflowinexactAn implementation may add more exceptions, which should be symbols.
(current-flexceptions)
Returns an immutable list of the current raised exceptions.
(possible-flexceptions)
Returns an immutable list of the exceptions that could possibly be raised.
(flexception-raised? exception)
Returns #t if exception was raised in the
current exception environment.
(raise-flexceptions! exception …)
Raise each exception.
(lower-flexceptions! exception …)
Lower each exception.
(with-flexceptions
exception-list body1 body2 …)
Evaluate exception-list to a list of exceptions. The body is evaluated in an environment that starts out with the exceptions that were in the list of exceptions. Raising and lowering exceptions affects the exceptions in the dynamic extent, and not the exceptions anywhere else.
An implementation may add more objects to the floating
point environment. For example, it may add a toggle to
signal Scheme exceptions when a floating-point exception
is raised. However, it must preserve the property that flenvironment=? decides the
equivalence of environments.
(current-flenvironment)
Returns the current floating point environment. The floating point environment encompasses all modifications possible at runtime.
(flenvironment? obj)
Returns #t if obj is an environment, and
#f otherwise.
(flenvironment=?
flenvironment1
flenvironment2
flenvironment3 …)
Returns #t if all flenvironments are equal.
Two environments are equal if, barring Scheme exceptions being signalled,
two procedures in this SRFI given the same arguments would return the
same results.
(flenvironment-rounding-mode
flenvironment)
Returns the rounding mode in the flenvironment.
(flenvironment-raised-exceptions
flenvironment)
Returns an immutable list of raised exceptions in the flenvironment.
(make-flenvironment
rounding-mode exception-list)
It is an error if exception-list is not a list of exception names.
Constructs an environment with the rounding-mode, and with the exceptions in exception-list raised.
(default-flenvironment)
Return the default environment. At runtime this is an implementation-specified
environment, and it may be modified by
with-flenvironment.
(restore-flenvironment!
flenvironment)
Set flenvironment as the current floating-point environment.
(with-flenvironment
flenvironment body1 body2 …)
Evaluate flenvironment to a floating point environment. When the dynamic extent of the body is first entered, the floating point environment is flenvironment. In addition, throughout the extent of the floating-point environment, the default environment is flenvironment.
When an implementation advertises that it implements,
e.g. flsqrt with one rounding, then it must
not reorder or optimize the program if it would return
a different result. For example, (fl/ 1.0 (flsqrt x))
may return a different result if implemented as two operations
literally, versus as one inverse square root operation. Implementations
may offer modes that optimize mathematical
operations at the expense of reproducibility.
Given the same rounding mode, input values,
with ieee-754-2019 and non-stop as features,
any set of operations that are correctly rounded will produce the same
answers on one correctly conforming implementation as on another with
the same rounding mode, input values, and features implicating correct
rounding.
This section is non-normative.
(import (scheme base)
(prefix (srfi 276 binary32) f32)
(srfi 151)
(rnrs bytevectors) ; for bytevector serialization operations
)
(unless (member 'ieee-754-2019 (f32:flfeatures))
(error "requires IEEE 754 arithmetic"))
(define (f32:kahan-sum lst)
(do ((sum #fl(binary32 0.0))
(c #fl(binary32 0.0))
(lst lst (cdr lst)))
((null? lst) sum)
(let* ((y (fl32:fl- (car lst) c))
(t (fl32:fl+ sum y)))
(set! c (fl32:fl- (fl32:fl- t sum) y))
(set! sum t))))
(define (f32:fast-inverse-square-root number)
(let ((bv (make-bytevector f32:flbyte-width))
(x2 (f32:fl* number #fl(binary32 0.5))))
(f32:bytevector-flonum-set! bv 0 number)
(let* ((i (bytevector-u32-native-ref bv 0))
(i (- #x5f3759df (arithmetic-shift i -1))))
(bytevector-u32-native-set! bv 0)
(let ((y (f32:bytevector-flonum-ref bv 0)))
(f32:fl* y (f32:fl- #fl(binary32 1.5) (f32:fl* x2 y y)))))))
This code will always calculate the correct results with the desired algorithmic properties on any conforming implementation that implements the binary32 format and follows the syntax recommendations. In particular, a conforming implementation will not re-order operations in such a way to make the output values differ.
SRFI 4 specifies
f32vectors and f64vectors, and
SRFI 160 specifies
c64vectors and c128vectors. Implementors should make
the elements of each vector the corresponding representation in the
table. If the corresponding cond-expand feature is available,
then the elements of the number vector must be that type.
| Vector | Representation | cond-expand feature |
|---|---|---|
| f32vector | binary32 | f32vector-is-binary32 |
| f64vector | binary64 | f64vector-is-binary64 |
| c64vector | each part is binary32 | c64vector-is-binary32 |
| c128vector | each part is binary64 | c128vector-is-binary64 |
On implementations with binary floating point of the corresponding precisions, the exponent specifiers in the table should map to the corresponding representation:
| Exponent | Representation |
|---|---|
s | binary16 |
f | binary32 |
d | binary64 |
Because there is not a lot of hardware with binary128 support,
this SRFI makes no recommendation for the l exponent.
Some formats that could be used for l include
binary128, x87 long double, and so-called
“double-double” arithmetic (see Dekker 1971
and Joldes, Muller, and Popescu 2017).
An implementation should use the floating-point operations available in hardware
as much as possible.
Most implementations only have one floating-point type (binary64), and those
implementations can copy most of their
SRFI 144
implementation to (srfi 276 binary64) with minor renamings.
The simplest way to implement the inspection portion of this SRFI is an FFI to C’s
fenv.h.
Checking the FTZ/DAZ mode (for example, on Intel CPUs) requires intrinsics to
check the MXCSR register.
Although it is possible to implement
bytevector-flonum-ref
and
bytevector-flonum-set!
in terms of flnormalized-fraction-exponent and
make-flonum, it is much easier to manipulate the byte
representation of the flonum directly.
A sample implementation will be provided that wraps MIT Scheme’s floating-point environment API.
Implementations that implement SRFI 276 are encouraged to also export SRFI 144 as a compatability library.
Thanks to those in Working Group 2 for discussing the semantics of this SRFI. In particular, I would like to thank Zhu Zihao for lots of information gathering.
I thank Bradley Lucier for his input.
I thank the authors of SRFI 144, as this work builds on theirs.
I also thank William Kahan, whose work on IEEE 754 and his many complaints about how programming language designers fail to understand it influenced the design of this SRFI (even if I could not incorporate all of his suggestions).
This section is non-normative.
This table documents procedures and constants in this SRFI that are based off of functions and constants in C23 and IEEE 754. The section and paragraph number of each function/constant in the latest C23 draft (see Meneide 2024) is given.
| SRFI | C23 | IEEE 754 |
|---|---|---|
fl-radix |
FLT_RADIX (5.2.5.3.3 ¶ 31) |
b |
fl-precision |
FLT_MANT_DIG (5.2.5.3.3 ¶ 31) |
p |
fl-maximum-exponent |
FLT_MAX_EXP (5.2.5.3.3 ¶ 31) |
emax |
fl-minimum-normalized-exponent |
FLT_MIN_EXP (5.2.5.3.3 ¶ 31) |
emin |
fl-greatest |
FLT_MAX (5.2.5.3.3 ¶ 32) | |
fl-least |
FLT_TRUE_MIN (5.2.5.3.3 ¶ 33) | |
fl-least-normal |
FLT_MIN (5.2.5.3.3 ¶ 33) | |
fl-epsilon |
FLT_EPSILON (5.2.5.3.3 ¶ 33) | |
fl-byte-width |
sizeof float | |
fladjacent |
nextafter (7.12.11.3) |
nextUp, nextDown |
flcopysign |
copysign (7.12.11.1) |
|
make-flonum |
scalbn (7.12.7.19) |
scaleB |
flinteger-fraction |
modf (7.12.6.18) |
|
flexponent |
logb (7.12.6.17) |
logB |
flnormalized-fraction-exponent |
frexp (7.12.6.7) |
|
flinteger-exponent |
ilogb (7.12.6.8) |
logB |
fl-integer-exponent-zero |
FP_ILOGB0 (7.12 ¶ 18) | |
fl-integer-exponent-nan |
FP_ILOGBNAN (7.12 ¶ 18) | |
flsign-negative? |
signbit (7.12.3.7) |
isSignMinus |
fl=? |
= (F.9.4) |
compareQuietEqual |
fl<?
fl<=?, etc. |
<, <=, etc. (F.9.4) |
compareSignalingGreater, compareSignalingGreaterEqual, etc. |
fl!=? |
!= (F.9.4) |
compareQuietNotEqual |
total=?, etc. |
totalorder (F.10.12.2) |
totalOrder |
flunordered? |
isunordered (7.12.17.6) |
compareQuietUnordered |
flzero? |
iszero (7.12.3.10) |
isZero |
flfinite? |
isfinite (7.12.3.3) |
isFinite |
flinfinite? |
isinf (7.12.3.4) |
isInfinite |
flnan? |
isnan (7.12.3.5) |
isNaN |
flnormal? |
isnormal (7.12.3.6) |
isNormal |
flsubnormal? |
issubnormal (7.12.3.9) |
isSubnormal |
flmax, flmin |
fmaximum,fminimum(7.12.12.4, F.10.9.4) |
maximum, minimum |
max-abs, min-abs |
fmaximum_mag,fminimum_mag(7.12.2.8) |
maximumMagnitude, minimumMagnitude |
max-filter-nans,min-filter-nans |
fmaximum_num,fminimum_num(7.12.12.5, F.10.9.5) |
maximumNumber, minimumNumber |
max-abs-filter-nans,min-abs-filter-nans |
fmaximum_num_mag,fminimum_num_mag(7.12.12.7) |
maximumMagnitudeNumber, minimumMagnitudeNumber |
fl+ |
+ (6.5.7) |
addition |
fl- |
- (6.5.7) |
subtraction, negate |
fl* |
* (6.5.6) |
multiplication |
fl/ |
/ (6.5.6) |
multiplication |
fl+* |
fma (7.12.13.1) |
fusedMultiplyAdd |
flabs |
fabs (7.12.7.3) |
abs |
flposdiff |
fdim (7.12.12.1) |
|
flfloor |
floor (7.12.9.2) |
roundToIntegralTowardNegative |
flceiling |
ceil (7.12.9.1) |
roundToIntegralTowardPositive |
fltruncate |
trunc (7.12.9.9) |
roundToIntegralTowardZero |
flround |
roundeven (7.12.9.8) |
roundToIntegralTiesToEven |
flround-away |
round (7.12.9.6) |
roundToIntegralTiesToAway |
fltruncate-remainder |
fmod (7.12.10.1) | |
flremquo |
remquo (7.12.10.3) |
|
flround-remainder |
remainder (7.12.10.2) |
remainder |
flexp |
exp (7.12.6.1) |
exp |
flexp2 |
exp2 (7.12.6.4) |
exp2 |
flexp10 |
exp10 (7.12.6.2) |
exp10 |
flexp-1 |
expm1 (7.12.6.6) |
expm1 |
flexp2-1 |
exp2m1 (7.12.6.5) |
exp2m1 |
flexp10-1 |
exp10m1 (7.12.6.3) |
exp10m1 |
flexpt |
pown (7.12.7.6),pow (7.12.7.5) |
pown, pow |
fllog |
log (7.12.6.11) |
log |
fllog2 |
log2 (7.12.6.15) |
log2 |
fllog10 |
log10 (7.12.6.12) |
log10 |
fllog+1 |
logp1 (7.12.6.14) |
logp1 |
fllog2+1 |
log2p1 (7.12.6.16) |
log2p1 |
fllog10+1 |
log10p1 (7.12.6.13) |
log10p1 |
flcbrt |
cbrt (7.12.7.1) | |
flcompound |
compoundn (7.12.7.2) |
compound |
flhypot |
hypot (7.12.7.4) |
hypot |
flrsqrt |
rsqrt (7.12.7.9) |
rSqrt |
flsqrt |
sqrt (7.12.7.10) |
squareRoot |
flsin |
sin (7.12.4.6) |
sin |
flcos |
cos (7.12.4.5) |
cos |
fltan |
tan (7.12.4.7) |
tan |
flsinpi |
sinpi (7.12.4.6) |
sinPi |
flcospi |
cospi (7.12.4.5) |
cosPi |
fltanpi |
tanpi (7.12.4.7) |
tanPi |
flasin |
asin (7.12.4.2) |
asin |
flacos |
acos (7.12.4.1) |
acos |
flatan |
atan (7.12.4.3) |
atan |
flasinpi |
asinpi (7.12.4.9) |
asinPi |
flacospi |
acospi (7.12.4.8) |
acosPi |
flatanpi |
atanpi (7.12.4.10) |
atanPi |
flsinh |
sinh (7.12.5.5) |
sinh |
flcosh |
cosh (7.12.4.4) |
cosh |
fltanh |
tanh (7.12.4.6) |
tanh |
flasinh |
asinh (7.12.5.2) |
asinh |
flacosh |
acosh (7.12.5.1) |
acosh |
flatanh |
atanh (7.12.5.3) |
atanh |
flerf |
erf (7.12.8.1) |
|
flerfc |
erfc (7.12.8.2) |
|
flgamma |
tgamma (7.12.8.4) |
|
fllog-gamma |
lgamma (7.12.8.3) |
|
current-rounding-mode |
fegetmode (7.6.5.1) |
saveModes |
set-rounding-mode! |
fesetmode (7.6.5.4) |
restoreModes |
current-flexceptions,flexception-raised?
|
fetestexcept (7.6.4.7) |
testFlags |
raise-flexceptions! |
fesetexcept (7.6.4.4) |
raiseFlags |
lower-flexceptions!
|
feclearexcept (7.6.4.1) |
lowerFlags |
In addition, some procedures and constants come from POSIX:
| SRFI | POSIX |
|---|---|
fl-e | M_E |
fl-log2-e | M_LOG2E |
fl-log10-e | M_LOG10E |
fl-log-2 | M_LN2 |
fl-log10 | M_LN10 |
fl-pi | M_PI |
fl-pi/2 | M_PI_2 |
fl-pi/4 | M_PI_4 |
fl-1/pi | M_1_PI |
fl-2/pi | M_2_PI |
fl-2/sqrt-pi | M_2_SQRTPI |
fl-sqrt-2 | M_SQRT2 |
fl-1/sqrt-2 | M_SQRT1_2 |
flfirst-bessel |
j0, j1, jn |
flsecond-bessel |
y0, y1, yn |
fllog-gamma |
lgamma, signgam |
© 2026 Peter McGoron.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS,” WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.