This site is a static rendering of the Trac instance that was used by R7RS-WG1 for its work on R7RS-small (PDF), which was ratified in 2013. For more information, see Home. For a version of this page that may be more recent, see FlonumsCowan in WG2's repo for R7RS-large.

Flonums­Cowan

cowan
2015-12-01 01:46:48
11history
source

Flonums package

Flonums are a subset of the inexact real numbers provided by a Scheme implementation. In most Schemes, the flonums and the inexact reals are the same.

The procedures in this package don't have hard-coded prefixes. The intent is that they be placed in a module. Users can then import this module with their own prefix such as fl, or ƒ if their Scheme implementation supports that character, or with no prefix at all if the intent is to override the normal Scheme arithmetic routines.

R6RS flonum library

This section uses fl, fl1, fl2, etc., as parameter names for flonum arguments, and ifl as a name for integer-valued flonum arguments, i.e., flonums for which the integer? predicate returns true.

(flonum? obj)procedure 

Returns #t if obj is a flonum, #f otherwise.

(real->flonum x)procedure 

Returns the best flonum representation of x.

The value returned is a flonum that is numerically closest to the argument.

Note: If flonums are represented in binary floating point, then implementations should break ties by preferring the floating-point representation whose least significant bit is zero.

(fl=? fl1 fl2 fl3 ...)procedure 
(fl<? fl1 fl2 fl3 ...)procedure 
(fl<=? fl1 fl2 fl3 ...)procedure 
(fl>? fl1 fl2 fl3 ...)procedure 
(fl>=? fl1 fl2 fl3 ...)procedure 

These procedures return #t if their arguments are (respectively): equal, monotonically increasing, monotonically decreasing, monotonically nondecreasing, or monotonically nonincreasing, #f otherwise. These predicates must be transitive.

(fl= +inf.0 +inf.0)           ⇒  #t

(fl= -inf.0 +inf.0)           ⇒  #f

(fl= -inf.0 -inf.0)           ⇒  #t

(fl= 0.0 -0.0)                ⇒  #t

(fl< 0.0 -0.0)                ⇒  #f

(fl= +nan.0 fl)               ⇒  #f

(fl< +nan.0 fl)               ⇒  #f

(flinteger? fl)procedure 
(flzero? fl)procedure 
(flpositive? fl)procedure 
(flnegative? fl)procedure 
(flodd? ifl)procedure 
(fleven? ifl)procedure 
(flfinite? fl)procedure 
(flinfinite? fl)procedure 
(flnan? fl)procedure 

These numerical predicates test a flonum for a particular property, returning #t or #f. The flinteger? procedure tests whether the number object is an integer, flzero? tests whether it is fl=? to zero, flpositive? tests whether it is greater than zero, flnegative? tests whether it is less than zero, flodd? tests whether it is odd, fleven? tests whether it is even, flfinite? tests whether it is not an infinity and not a NaN, flinfinite? tests whether it is an infinity, and flnan? tests whether it is a NaN.

(flnegative? -0.0)   ⇒ #f

(flfinite? +inf.0)   ⇒ #f

(flfinite? 5.0)      ⇒ #t

(flinfinite? 5.0)    ⇒ #f

(flinfinite? +inf.0) ⇒ #t

Note: (flnegative? -0.0) must return #f, else it would lose the correspondence with (fl< -0.0 0.0), which is #f according to IEEE 754 [7].

(flmax fl1 fl2 ...)procedure 
(flmin fl1 fl2 ...)procedure 

These procedures return the maximum or minimum of their arguments. They always return a NaN when one or more of the arguments is a NaN.

(fl+ fl1 ...)procedure 
(fl* fl1 ...)procedure 

These procedures return the flonum sum or product of their flonum arguments. In general, they should return the flonum that best approximates the mathematical sum or product. (For implementations that represent flonums using IEEE binary floating point, the meaning of “best” is defined by the IEEE standards.)

(fl+ +inf.0 -inf.0)      ⇒  +nan.0

(fl+ +nan.0 fl)          ⇒  +nan.0

(fl* +nan.0 fl)          ⇒  +nan.0

(fl- fl1 fl2 ...)procedure 
(fl- fl)procedure 
(fl/ fl1 fl2 ...)procedure 
(fl/ fl)procedure 

With two or more arguments, these procedures return the flonum difference or quotient of their flonum arguments, associating to the left. With one argument, however, they return the additive or multiplicative flonum inverse of their argument. In general, they should return the flonum that best approximates the mathematical difference or quotient. (For implementations that represent flonums using IEEE binary floating point, the meaning of “best” is reasonably well-defined by the IEEE standards.)

(fl- +inf.0 +inf.0)      ⇒  +nan.0

For undefined quotients, fl/ behaves as specified by the IEEE standards:

(fl/ 1.0 0.0)  ⇒ +inf.0

(fl/ -1.0 0.0) ⇒ -inf.0

(fl/ 0.0 0.0)  ⇒ +nan.0

(flabs fl)procedure 

Returns the absolute value of fl.

(fldiv-and-mod fl1 fl2)procedure 
(fldiv fl1 fl2)procedure 
(flmod fl1 fl2)procedure 
(fldiv0-and-mod0 fl1 fl2)procedure 
(fldiv0 fl1 fl2)procedure 
(flmod0 fl1 fl2)procedure 

These procedures implement number-theoretic integer division and return the results of the corresponding mathematical operations specified in report section on “Integer division”. For zero divisors, these procedures may return a NaN or some unspecified flonum.

(fldiv fl1 fl2)         ⇒ fl1 div fl2

(flmod fl1 fl2)         ⇒ fl1 mod fl2

(fldiv-and-mod fl1 fl2)     
⇒ fl1 div fl2fl1 mod fl2
; two return values

(fldiv0 fl1 fl2)        ⇒ fl1 div0 fl2

(flmod0 fl1 fl2)        ⇒ fl1 mod0 fl2

(fldiv0-and-mod0 fl1 fl2)   
⇒ fl1 div0 fl2fl1 mod0 fl2
; two return values

(flnumerator fl)procedure 
(fldenominator fl)procedure 

These procedures return the numerator or denominator of fl as a flonum; the result is computed as if fl was represented as a fraction in lowest terms. The denominator is always positive. The denominator of 0.0 is defined to be 1.0.

(flnumerator +inf.0)           ⇒  +inf.0

(flnumerator -inf.0)           ⇒  -inf.0

(fldenominator +inf.0)         ⇒  1.0

(fldenominator -inf.0)         ⇒  1.0

(flnumerator 0.75)             ⇒  3.0 ; probably

(fldenominator 0.75)           ⇒  4.0 ; probably

Implementations should implement following behavior:

(flnumerator -0.0)             ⇒ -0.0

(flfloor fl)procedure 
(flceiling fl)procedure 
(fltruncate fl)procedure 
(flround fl)procedure 

These procedures return integral flonums for flonum arguments that are not infinities or NaNs. For such arguments, flfloor returns the largest integral flonum not larger than fl. The flceiling procedure returns the smallest integral flonum not smaller than fl. The fltruncate procedure returns the integral flonum closest to fl whose absolute value is not larger than the absolute value of fl. The flround procedure returns the closest integral flonum to fl, rounding to even when fl represents a number halfway between two integers.

Although infinities and NaNs are not integer objects, these procedures return an infinity when given an infinity as an argument, and a NaN when given a NaN:

(flfloor +inf.0)                       ⇒  +inf.0

(flceiling -inf.0)                     ⇒  -inf.0

(fltruncate +nan.0)                    ⇒  +nan.0

(flexp fl)procedure 
(fllog fl)procedure 
(fllog fl1 fl2)procedure 
(flsin fl)procedure 
(flcos fl)procedure 
(fltan fl)procedure 
(flasin fl)procedure 
(flacos fl)procedure 
(flatan fl)procedure 
(flatan fl1 fl2)procedure 

These procedures compute the usual transcendental functions. The flexp procedure computes the base-e exponential of fl. The fllog procedure with a single argument computes the natural logarithm of fl (not the base ten logarithm); (fllog fl1 fl2) computes the base-fl2 logarithm of fl1. The flasin, flacos, and flatan procedures compute arcsine, arccosine, and arctangent, respectively. (flatan fl1 fl2) computes the arc tangent of fl1/fl2.

See report section on “Transcendental functions” for the underlying mathematical operations. In the event that these operations do not yield a real result for the given arguments, the result may be a NaN, or may be some unspecified flonum.

Implementations that use IEEE binary floating-point arithmetic should follow the relevant standards for these procedures.

(flexp +inf.0)                ⇒ +inf.0

(flexp -inf.0)                ⇒ 0.0

(fllog +inf.0)                ⇒ +inf.0

(fllog 0.0)                   ⇒ -inf.0

(fllog -0.0)                  ⇒ unspecified
; if -0.0 is distinguished

(fllog -inf.0)                ⇒ +nan.0

(flatan -inf.0)               
⇒ -1.5707963267948965
; approximately

(flatan +inf.0)               
⇒ 1.5707963267948965
; approximately

(flsqrt fl)procedure 

Returns the principal square root of fl. For −0.0, flsqrt should return −0.0; for other negative arguments, the result may be a NaN or some unspecified flonum.

(flsqrt +inf.0)               ⇒  +inf.0

(flsqrt -0.0)                 ⇒  -0.0

(flexpt fl1 fl2)procedure 

Either fl1 should be non-negative, or, if fl1 is negative, fl2 should be an integer object. The flexpt procedure returns fl1 raised to the power fl2. If fl1 is negative and fl2 is not an integer object, the result may be a NaN, or may be some unspecified flonum. If fl1 is zero, then the result is zero.

&no-infinitiescondition type 
(make-no-infinities-violation obj)procedure 
(no-infinities-violation? obj)procedure 
&no-nanscondition type 
(make-no-nans-violation obj)procedure 
(no-nans-violation? obj)procedure 

These condition types could be defined by the following code:

(define-condition-type &no-infinities

    &implementation-restriction

  make-no-infinities-violation

  no-infinities-violation?)

(define-condition-type &no-nans

    &implementation-restriction

  make-no-nans-violation no-nans-violation?)

These types describe that a program has executed an arithmetic operations that is specified to return an infinity or a NaN, respectively, on a Scheme implementation that is not able to represent the infinity or NaN. (See report section on “Representability of infinities and NaNs”.)

(fixnum->flonum fx)procedure 

Returns a flonum that is numerically closest to fx.

Note: The result of this procedure may not be numerically equal to fx, because the fixnum precision may be greater than the flonum precision.

R7RS-small-compatible procedures

The following R7RS-small procedures have flonum equivalents:

= < <= > >= integer? zero? positive? negative? odd? even? finite? infinite? nan? + - * / abs numerator denominator floor ceiling truncate round log sin cos tan asin acos atan sqrt expt

TODO: need to see about integer division procedures

C99 <math.h> constants

The following constants are defined in terms of the constants of the <math.h> header of ISO/IEC 9899:1999 (C language).

Scheme name

C name

Comments

e

M_E

Value of e

log2-e

M_LOG2E

Value of log2 e

log10-e

M_LOG10E

Value of log10 e

ln-2

M_LN2

Value of loge 2

ln-10

M_LN10

Value of loge 10

pi

M_PI

Value of pi

pi/2

M_PI_2

Value of pi/2

pi/4

M_PI_4

Value of pi/4

one-over-pi

M_1_PI

Value of 1/pi

two-over-pi

M_2_PI

Value of 2/pi

two-over-sqrt-pi

M_2_SQRTPI

Value of 2/sqrt(pi)

sqrt-2

M_SQRT2

Value of sqrt(2)

one-over-sqrt-2

M_SQRT1_2

Value of 1/sqrt(2)

maximum-flonum

HUGE_VAL

+inf.0 or else\\the largest finite flonum

fast-multiply-add

#t if FP_FAST_FMA is 1,\\or #f otherwise

multiply-add is fast

integer-exponent-zero

FP_ILOGB0

what (integer-binary-log 0) returns

integer-exponent-nan

FP_ILOGBNAN

what (integer-binary-log +0.nan) returns

C99 <math.h> procedures

The following procedures are defined in terms of the functions of the <math.h> header of ISO/IEC 9899:1999 (C language). In the C signatures, the types "double" and "int" are mapped to Scheme flonums and (suitably bounded) Scheme exact integers respectively.

Scheme name

C signature

Comments

acosh

double acosh(double)

hyperbolic arc cosine

asinh

double asinh(double)

hyperbolic arc sine

atanh

double atanh(double)

hyperbolic arc tangent

cbrt

double cbrt(double);

cube root

complementary-error-function

double erfc(double)

-

copy-sign

double copysign(double x, double y)

result has magnitude of x and sign of y

cosh

double cosh(double)

hyperbolic cosine

make-flonum

double ldexp(double x, int n)

x*2n

error-function

double erf(double)

-

exp

double exp(double)

ex

exp-binary

double exp,,2,,(double)

base-2 exponential

exp-minus-1

double expm1(double)

ex-1

exponent

double logb(double x)

the exponent of x, which is the integral part of log_r(|x|), as a signed floating-point value, for non-zero x, where r is the radix of the machine's floating-point arithmetic

first-bessel-order-0

double j0(double)

bessel function of the first kind, order 0

first-bessel-order-1

double j1(double)

bessel function of the first kind, order 1

first-bessel

double jn(int n, double)

bessel function of the first kind, order n

fraction-exponent

double modf(double, double *)

returns two values, fraction and int exponent

gamma

double tgamma(double)

-

hypotenuse

double hypot(double, double)

sqrt(x2+y2)

integer-exponent

int ilogb(double)

binary log as int

log-binary

double log2(double)

log base 2

log-decimal

double log10(double)

log base 10

log-gamma

double lgamma(double)

returns two values, log(|gamma(x)|) and sgn(gamma(x))

log-one-plus

double log1p(double x)

log (1+x)

multiply-add

double fma(double a, double b, double c)

a*b+c

next-after

double nextafter(double, double)

next flonum following x in the direction of y

normalized-fraction-exponent

double frexp(double, int *)

returns two values, fraction in range [1/2,1) and int exponent

positive-difference

double fdim(double, double)

-

||remquo||double remquo(double, double, int *)||returns two values, rounded remainder and low-order n bits of the quotient (n is implementation-defined)

scalbn

double scalbn(double x, int y)

x*ry, where r is the machine float radix

second-bessel-order-0

double y0(double)

bessel function of the second kind, order 0

second-bessel-order-1

double y1(double)

bessel function of the second kind, order 1

second-bessel

double yn(int n, double)

bessel function of the second kind, order n

sinh

double sinh(double)

hyperbolic sine

tanh

double tanh(double)

hyperbolic tangent

General remarks

In the event that these operations do not yield a real result for the given arguments, the result may be +nan.0, or may be some unspecified flonum.

Implementations that use IEEE binary floating-point arithmetic should follow the relevant standards for these procedures.

Compnum procedures from <complex.h>

A compnum is a general complex number whose real-part and imag-part are both flonums. The following procedures should be in a different library from the flonum procedures, since they will only be relevant to Schemes that support general complex numbers, and since there are conflicting names.

Scheme name

C signature

Comments

abs

double cabs(double complex)

same as magnitude

acos

double complex cacos(double complex)

-

acosh

double complex cacosh(double complex)

-

angle

double carg(double complex)

-

asin

double complex casin(double complex)

-

asinh

double complex casinh(double complex)

-

atan

double complex catan(double complex)

-

atanh

double complex catanh(double complex)

-

conjugate

double complex conj(double complex)

complex conjugate

cos

double complex ccos(double complex)

-

cosh

double complex ccosh(double complex)

-

exp

double complex cexp(double complex)

-

expt

double complex cpow(double complex, double complex)

-

imag-part

double cimag(double complex)

-

log

double complex clog(double complex)

-

magnitude

double cabs(double complex)

same as abs

||projection||double complex cproj(double complex)||projects to Riemann sphere

real-part

double creal(double complex)

-

sin

double complex csin(double complex)

-

sinh

double complex csinh(double complex)

-

sqrt

double complex csqrt(double complex)

-

tan

double complex ctan(double complex)

-

tanh

double complex ctanh(double complex)

-

Derived procedures

TODO: what library do these go in?

(cis z)

Returns eiz, a complex number whose real part is cos z and whose imaginary part is sin z.

(signum z)

Returns a complex number whose phase is the same as z but whose magnitude is 1, unless z is zero, in which case it returns z. As a consequence of this definition, negative real numbers return -1, positive real numbers return 1, and zero returns zero.

(decode-float z) and friends

See CL DECODE-FLOAT and friends.