chickadee » srfi-278

SRFI 278: Supplemental Numerics

This SRFI defines miscellaneous procedures on numbers that were either missing from the R7RS or are common extensions, such as hyperbolic functions and a function corresponding to a new IEEE 754 rounding mode.

Description

This SRFI adds a few procedures that can be categorized into the following:

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. In addition, the rationalize procedure has been extended to different types of intervals to make it more useful in simplifying rational numbers while also preserving properties such as rounding.

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 the implementation of complex inverse trigonometric functions is closely linked to the implementation of complex inverse hyperbolic functions.

The procedure round-away has been added to correspond to the roundTiesToAway rounding mode in IEEE 754-2019. In addition, unordered? and ordered? have been added to determine whether two arguments have a sensible order relationship. The procedures nonpositive?, nonnegative?, nonzero? are procedures that are negations of the corresponding procedures without non, but will still always return #f when passed a NaN. Finally, the procedure sign-negative? is useful for determining the sign of zeroes and NaNs.

The R6RS number predicates are more useful than the R5RS equivalents. This is because the R6RS and R7RS introduced signed inexact zero to the number system. That means that 1.0+0.0i, 1.0-0.0i, and 1.0 may be distinct. The R5RS definition says each of these is real?: this SRFI and the R6RS say that only 1.0 is real?, and the other two are not.

The reason for this is the interpretation of the sign of inexact zero. A positive inexact zero is a number that is potentially above zero, but too small for the number format, and similarly for negative inexact zero. Hence a number with an inexact zero imaginary part is potentially not on the real axis. This has consequences for functions that have branch cuts on the real axis, in particular, functions like atanh, which has a branch cut when the real part |x|≥1. For example:

(atanh 2.0+0.0i) ⇒ .5493061443340549+π/2i
(atanh 2.0-0.0i) ⇒ .5493061443340549-π/2i
(angle -1.0+0.0i) ⇒ π
(angle -1.0-0.0i) ⇒ -π

The interpretation of unsigned zero imaginary part is more complicated. One cannot promote unsigned imaginary zero to inexact imaginary zero of a fixed sign. This is because the principal values of log and angle are defined for unsigned imaginary zero such that values are continuous when approached counterclockwise. This is one of the reasons why a number with an exact (unsigned) zero imaginary part is real?, while ones with inexact (signed) zero imaginary part is not real?.

Author

Peter McGoron

Repository

https://github.com/mcgoron-peter/srfi-278

Requirements

API

All procedures are exported from (srfi 278).

conjugate zprocedure

Returns the complex conujugate of z.

round-away xprocedure

Rounds x to the nearest integer, breaking ties by rounding away from zero.

imaginary? objprocedure

Returns #t if obj is a complex number with an exact zero real part, and false otherwise.

real? objprocedure
rational? objprocedure
integer? objprocedure

R6RS numerical tower predicates.

sign-negative? xprocedure

Returns #t if x has a negative sign: that is:

  • It is less than zero.
  • It is a NaN with a negative sign bit.
  • It is negative zero.

Returns #f otherwise.

ordered? x yprocedure

Returns #t if x and y are not both NaNs.

unordered? x yprocedure

Opposite of ordered?.

!= z_1 z_2 z_3 ...procedure

Returns #t if there exists one argument that is not equal to another argument in the list. Otherwise, returns #f.

Note: Because of the handling of NaNs, (!= x y) is not necessarily equivalent to (not (= x y)).

nonnegative? xprocedure

Returns #t if x is greater than or equal to zero.

nonpositive? xprocedure

Returns #t if x is less than or equal to zero.

nonzero? zprocedure

Returns #t if z is either less than or greater than zero.

exact-integer? objprocedure
nan? objprocedure

Like the R7RS versions, but return #f when passed a non-number.

rationalize x yprocedure
rationalize x delta-lower delta-upper #!optional lower-inclusive? upper-inclusive?procedure

When not supplied, lower-inclusive? and upper-inclusive? default to #t.

This procedure is like rationalize in the R7RS. When delta-lower and delta-upper are specified, then the simplest rational between x−|delta-lower| and x+|delta-upper| is returned.

When lower-inclusive? is true, the lower bound of the range is inclusive; otherwise, it is exclusive. When upper-inclusive? is true, the upper bound of the range is inclusive; otherwise, it is exclusive. For example, (rationalize x -1 +1 #f #t) covers the range (x−1,x+1].

exact-integer-nth-root k nprocedure

See (chicken base).

exact-integer-log k bprocedure

Returns two nonnegative exact integers, s and r such that k=b^s+r and k<b^(s+1).

sinh zprocedure
cosh zprocedure
tanh zprocedure

Calculate the corresponding hyperbolic function.

asinh zprocedure
acosh zprocedure
atanh zprocedure

Calculate the corresponding inverse hyperbolic function. In general, inverse hyperbolic functions are multiply valued. See the SRFI for the principal expressions and the definitions of the branch cuts. These functions try very hard to be sensitive to the sign of zero.

Version History

1.0.0
Finalized SRFI
0.2.1
Fix build error
0.2.0
Updated to draft #2
0.1.0
CHICKEN 6 port

License

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

Contents »