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-278@nospamsrfi.schemers.org. To subscribe to the list, follow these instructions. You can access previous messages via the mailing list archive.
This SRFI defines miscellaneous procedures on numbers that were either missing from the R7RS or are common extensions.
This SRFI adds a few procedures that can be categorized into the following:
exact-integer?).strictly-real?).
conjugate, hyperbolic functions).
The extended-domain procedures are more useful because they can be
used without invoking “it is an error” behavior. For example, in this
SRFI, (exact-integer? '()) and (nan? '())
both return #f. (Some proposed extensions to standard
procedures, such as
gcd on rational arguments, should be a part of a
different SRFI, such as
SRFI 141
extended to non-integers.)
The R6RS procedures are
useful when determining whether a number is exactly on the real number line,
as opposed to being approximately on the real number line. Procedures
like R6RS’s
div-and-mod are not supplied. They are similarly
relegated to an extended SRFI 141.
The common extensions are the conjugate procedure and the
(inverse) hyperbolic functions. The (inverse) hyperbolic functions are
commonly provided on Schemes that provide complex arithmetic (for example,
Gambit, Chez, Racket, Gauche, and Guile) because those implementations
are required to implement complex (inverse) trigonometric functions,
which are closely connected to complex (inverse) hyperbolic functions.
The procedure round-away has been added to correspond to
the roundTiesToAway rounding mode in IEEE 754-2019.
Requirement level verbs are in strong text.
The names of arguments have the same requirements as the R7RS. It is an error to call a procedure with a list of arguments that do not match the description given here.
When an example evaluates to an inexact number, that number is approximate.
The number that an implementation evaluates to should be close in both
parts of a complex number to that value. An exception is when one part
of a complex value is an infinity or a zero. An implementation
should evaluate to a number that has the appropriately
signed infinity or zero in that part (in the sense of eqv?).
The following are exported from the library defined by this SRFI.
conjugate
round-away
strictly-real?
strictly-rational?
strictly-integer?
exact-integer?
nan?
sinh
cosh
tanh
asinh
acosh
atanh
(conjugate z)
Returns the complex conjugate of the procedure.
If the implementation distinguishes the sign of inexact zero in the imaginary part of a complex number, then it must flip the sign of the inexact zero.
This procedure returns an exact value given an exact argument.
Note: If non-real complex numbers are not provided, this procedure is just the identity function.
(conjugate 1.0)⇒ 1.0(conjugate 1+2i)⇒ 1-2i(conjugate 1.0+0.0i)⇒ 1.0-0.0i(conjugate 1.0-0.0i)⇒ 1.0+0.0i
(round-away
x)
Round x to an integer, with ties broken by returning the number greater in absolute value. Equivalent to the IEEE 754-2019 [2] rounding mode roundTiesToAway.
This procedure returns an exact value given an exact argument.
(round-away 2.5)⇒ 3.0(round-away 5/2)⇒ 3(round-away 2.4)⇒ 2.0(round-away -2.5)⇒ -3.0(round-away 3.6)⇒ 4.0(round-away 3.5)⇒ 4.0(round-away 3.4)⇒ 3.0
Returns #t if the obj is of the corresponding
type, (zero? (imag-part obj)) is
#t, and (exact? (imag-part obj)).
Rationale: These procedures have the
semantics of real?, rational?, and
integer? in the R6RS.
It is sometimes useful to have a number represented internally as a
complex number even when its imaginary part is inexact zero: this
occurs when one wants to use the sign of the inexact zero for
computations. It is intended that a number that is
strictly-real?, etc. is not represented internally as
a compound number (compnum), and that all complex numbers with an
exact zero imaginary part are normalized and represented
as flonums, bignums, fixnums, ratnums, etc.
Another reason to distinguish between real? and
strictly-real? is the interpretation of what it means for
the imaginary part of a number to be inexact zero. When a number is
inexact zero, it is only approximately that number. As such,
if a number has an inexact zero imaginary part, then we don’t know if
it is actually on the real axis, or if the actual result of the
computation was actually slightly above or below the real axis.
On the other hand, if the imaginary part is exactly zero, then the
the number has to be on the real axis.
(strictly-real? 1.0)⇒ #t(strictly-real? 1)⇒ #t(strictly-real? 1+0i)⇒ #t(strictly-real? 1.0+0.0i)⇒ #f(strictly-real? 1.0-0.0i)⇒ #f
These procedures are the same as their counterparts in the Reports,
except that they return #f when passed an object
that is not number?.
Rationale: Implementations are
encouraged to replace the versions of these procedures in
(scheme base) with the one defined in this SRFI.
The ones defined in this SRFI are backwards-compatible with the
versions described in the
R7RS.
Calculates the value of the hyperbolic function for z.
(sinh 0)⇒ 0.0(sinh +inf.0)⇒ +inf.0(sinh -inf.0)⇒ -inf.0(cosh 0)⇒ 1.0(cosh +inf.0)⇒ +inf.0(cosh -inf.0)⇒ +inf.0(sinh +1.0i)⇒ +.8414709848078965i
Calculates the principal value of the inverse hyperbolic function at z.
It is an error to call these values on exact numbers on a location where the procedure is undefined mathematically. The implementation should raise an exception in such a scenario.
In general, inverse hyperbolic functions are multiply valued. The following principal expressions are derived from the table in the Reports and from [1]. (For those that cannot render the math, this image shows the equations.)
The value of for non-real is defined in terms of as
where is the angle of specified as
with chosen such that .
With log defined this way, the values of the transcendental functions relevant to this SRFI go according to the following formulæ:
(The inverse trigonometric functions are included for comparison.)
When an implementation distinguishes the sign of inexact zero in some number, and if that number lies on a branch cut, then the implementation must return a value reasonably close to the appropriate one-sided limit of the function approaching the branch cut.
(atanh 1.0+0.0i)⇒ -inf.0+.7853981633974483i(atanh 1.0-0.0i)⇒ -inf.0-.7853981633974483i(atanh -1.0+0.0i)⇒ +inf.0+.7853981633974483i(atanh -1.0-0.0i)⇒ +inf.0-.7853981633974483i(atanh 0.0+1.0i)⇒ 0.0+0.7853981633974483i(atanh 1)⇒ error(atanh 0.0-1.0i)⇒ 0.0-.7853981633974483i(acosh 0.0+0.0i)⇒ 0.+1.5707963267948966i(acosh 0.0-0.0i)⇒ 0.-1.5707963267948966i(acosh 1.0+0.0i)⇒ 0.+3.141592653589793i(acosh 1.0-0.0i)⇒ 0.-3.141592653589793i(asinh 0.0+2.0i)⇒ 1.3169578969248166+1.5707963267948966i(asinh -0.0+2.0i)⇒ -1.3169578969248166+1.5707963267948966i
A sample implementation is available in the SRFI repository. It depends on complex numbers, inexact numbers, SRFI 144, inexact infinities, and signed zeroes. In addition, complex numbers must be able to store signed zeros in any part. (Some implementations do not allow this, like Gauche.) The sample implementation has been tested on Chibi Scheme. A test suite that depends on those features is also available.
An implementation without complex numbers support can copy the implementations of the (inverse) hyperbolic functions from SRFI 144 instead of using the implementation in this repository. The other parts of the implementation are portable R7RS.
I thank Bradley Lucier and the Gambit project for writing high-quality implementations of the (inverse) hyperbolic functions. I have used Gambit to check that my code outputs the correct values.
I thank William Kahan for doing the hard part for me (and many other people).
[1]: Kahan, W. Branch cuts for complex elementary functions; or, Much ado about nothing's sign bit. In Iserles, A., and Powell, M. (eds.), The state of the art in numerical analysis. Clarendon Press (1987) pp 165-211.
[2]: IEEE Computer Society. IEEE Standard for Floating-Point Arithmetic (IEEE STD 754-2019). doi:10.1109/IEEESTD.2019.8766229. (2019). ISBN 978-1-5044-5924-2.
© 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.