r7rs-small-texinfo

Unnamed repository; edit this file 'description' to name the repository.
git clone https://kaka.farm/~git/r7rs-small-texinfo
Log | Files | Refs

commit ad8f528d5e290280db1ff5ac18b5e2adb9ccc779
parent 10f5ac8b3009c7c27e753a89bb2a42cc21fc25b9
Author: Wolfgang Corcoran-Mathe <wcm@sigwinch.xyz>
Date:   Fri,  2 Feb 2024 22:30:10 -0500

Numbers: Texify, part 2.

Diffstat:
Mdoc/r7rs-small/procedures/numbers.texinfo | 362++++++++++++++++++++++++++++++++++---------------------------------------------
1 file changed, 157 insertions(+), 205 deletions(-)

diff --git a/doc/r7rs-small/procedures/numbers.texinfo b/doc/r7rs-small/procedures/numbers.texinfo @@ -348,7 +348,7 @@ All of @var{a}, @var{b}, @var{r}, and @var{@greektheta{}} are real numbers. @node Numerical operations @subsection Numerical operations -The reader is referred to section 1.3.3 for a summary of the naming conventions used to +The reader is referred to @ref{Error situations and unspecified behavior} for a summary of the naming conventions used to specify restrictions on the types of arguments to numerical routines. The examples used in this section assume that any numerical constant written using an exact notation is indeed represented as an exact number. Some examples also assume that certain @@ -362,31 +362,23 @@ implementations that use IEEE binary doubles to represent inexact numbers. @deffnx procedure rational? obj @deffnx procedure integer? obj -These numerical type predicates can be applied to any kind of argument, including -non-numbers. They return #t if the object is of the named type, and otherwise they return -#f. In general, if a type predicate is true of a number then all higher type predicates are -also true of that number. Consequently, if a type predicate is false of a number, then all -lower type predicates are also false of that number. +These numerical type predicates can be applied to any kind of +argument, including non-numbers. They return @code{#t} if the object is +of the named type, and otherwise they return @code{#f}. +In general, if a type predicate is true of a number then all higher +type predicates are also true of that number. Consequently, if a type +predicate is false of a number, then all lower type predicates are +also false of that number. -If - -z is a complex number, then (real? - -z) is true if and only if (zero? (imag-part - -z)) is true. If - -x is an inexact real number, then (integer? +If @var{z} is a complex number, then @code{(real? }@var{z}@code{)} is true if +and only if @code{(zero? (imag-part }@var{z}@code{))} is true. +If @var{x} is an inexact real number, then +@code{(integer? }@var{x}@code{)} is true if and only if @code{(= }@var{x}@code{ (round }@var{x}@code{))}. -x) is true if and only if (= +The numbers @code{+inf.0}, @code{-inf.0}, and @code{+nan.0} are real but +not rational. -x (round - -x)). - -The numbers +inf.0, -inf.0, and +nan.0 are real but not rational. - -@example +@lisp (complex? 3+4i) @result{} #t (complex? 3) @result{} #t (real? 3) @result{} #t @@ -402,13 +394,13 @@ The numbers +inf.0, -inf.0, and +nan.0 are real but not rational. (integer? 3+0i) @result{} #t (integer? 3.0) @result{} #t (integer? 8/4) @result{} #t -@end example +@end lisp Note: The behavior of these type predicates on inexact numbers is unreliable, since any inaccuracy might affect the result. -Note: In many implementations the complex? procedure will be the same as -number?, but unusual implementations may represent some irrational numbers +Note: In many implementations the @code{complex?} procedure will be the same as +@code{number?}, but unusual implementations may represent some irrational numbers exactly or may extend the number system to support some kind of non-complex numbers. @@ -417,48 +409,48 @@ numbers. @deffn procedure exact? z @deffnx procedure inexact? z - These numerical predicates provide tests for the exactness of a quantity. For any Scheme number, precisely one of these predicates is true. -@example +@lisp (exact? 3.0) @result{} #f (exact? #e3.0) @result{} #t (inexact? 3.) @result{} #t -@end example +@end lisp @end deffn @deffn procedure exact-integer? z +Returns @code{#t} if @var{z} is both exact and an integer; +otherwise returns @code{#f}. -Returns #t if - -z is both exact and an integer; otherwise returns #f. - -@example +@lisp (exact-integer? 32) @result{} #t (exact-integer? 32.0) @result{} #f (exact-integer? 32/5) @result{} #f -@end example +@end lisp @end deffn @deffn {inexact library procedure} finite? z -The finite? procedure returns #t on all real numbers except +inf.0, -inf.0, and +nan.0, and -on complex numbers if their real and imaginary parts are both finite. Otherwise it returns -#f. +The @code{finite?} procedure returns @code{#t} on all real numbers except +@code{+inf.0}, @code{-inf.0}, and @code{+nan.0}, and on complex +numbers if their real and imaginary parts are both finite. +Otherwise it returns @code{#f}. -@example +@lisp (finite? 3) @result{} #t (finite? +inf.0) @result{} #f (finite? 3.0+inf.0i) @result{} #f -@end example +@end lisp @end deffn @deffn {inexact library procedure} infinite? z -The infinite? procedure returns #t on the real numbers +inf.0 and -inf.0, and on complex -numbers if their real or imaginary parts or both are infinite. Otherwise it returns #f. +The @code{infinite?} procedure returns @code{#t} on the real numbers +@code{+inf.0} and @code{-inf.0}, and on complex +numbers if their real or imaginary parts or both are infinite. +Otherwise it returns @code{#f}. @example (infinite? 3) @result{} #f @@ -470,8 +462,9 @@ numbers if their real or imaginary parts or both are infinite. Otherwise it retu @deffn {inexact library procedure} nan? z -The nan? procedure returns #t on +nan.0, and on complex numbers if their real or -imaginary parts or both are +nan.0. Otherwise it returns #f. +The @code{nan?} procedure returns @code{#t} on @code{+nan.0}, and on complex +numbers if their real or imaginary parts or both are @code{+nan.0}. +Otherwise it returns @code{#f}. @example (nan? +nan.0) @result{} #t @@ -481,31 +474,38 @@ imaginary parts or both are +nan.0. Otherwise it returns #f. @end example @end deffn -@deffn procedure = z1 z2 z3 @dots{} -@deffnx procedure < x1 x2 x3 @dots{} -@deffnx procedure > x1 x2 x3 @dots{} -@deffnx procedure <= x1 x2 x3 @dots{} -@deffnx procedure >= x1 x2 x3 @dots{} +@deffn procedure = z@sub{1} z@sub{2} z@sub{3}@dots{} +@deffnx procedure < x@sub{1} x@sub{2} x@sub{3}@dots{} +@deffnx procedure > x@sub{1} x@sub{2} x@sub{3}@dots{} +@deffnx procedure <= x@sub{1} x@sub{2} x@sub{3}@dots{} +@deffnx procedure >= x@sub{1} x@sub{2} x@sub{3}@dots{} -These procedures return #t if their arguments are (respectively): equal, monotonically -increasing, monotonically decreasing, monotonically non-decreasing, or monotonically -non-increasing, and #f otherwise. If any of the arguments are +nan.0, all the predicates -return #f. They do not distinguish between inexact zero and inexact negative zero. +These procedures return @code{#t} if their arguments are (respectively): +equal, monotonically increasing, monotonically decreasing, +monotonically non-decreasing, or monotonically non-increasing, +and @code{#f} otherwise. +If any of the arguments are @code{+nan.0}, all the predicates return @code{#f}. +They do not distinguish between inexact zero and inexact negative zero. These predicates are required to be transitive. -Note: The implementation approach of converting all arguments to inexact numbers -if any argument is inexact is not transitive. For example, let big be (expt 2 1000), and -assume that big is exact and that inexact numbers are represented by 64-bit IEEE -binary floating point numbers. Then (= (- big 1) (inexact big)) and (= (inexact big) (+ big -1)) would both be true with this approach, because of the limitations of IEEE -representations of large integers, whereas (= (- big 1) (+ big 1)) is false. Converting -inexact values to exact numbers that are the same (in the sense of =) to them will -avoid this problem, though special care must be taken with infinities. - -Note: While it is not an error to compare inexact numbers using these predicates, the -results are unreliable because a small inaccuracy can affect the result; this is -especially true of = and zero?. When in doubt, consult a numerical analyst. +Note: The implementation approach +of converting all arguments to inexact numbers +if any argument is inexact is not transitive. For example, let +@code{big} be @code{(expt 2 1000)}, and assume that @code{big} is exact and that +inexact numbers are represented by 64-bit IEEE binary floating point numbers. +Then @code{(= (- big 1) (inexact big))} and +@code{(= (inexact big) (+ big 1))} would both be true with this approach, +because of the limitations of IEEE +representations of large integers, whereas @code{(= (- big 1) (+ big 1))} +is false. Converting inexact values to exact numbers that are the same (in the sense of @code{=}) to them will avoid +this problem, though special care must be taken with infinities. + +Note: While it is not an error to compare inexact numbers using these +predicates, the results are unreliable because a small inaccuracy +can affect the result; this is especially true of @code{=} and @code{zero?}. +When in doubt, consult a numerical analyst. + @end deffn @deffn procedure zero? z @@ -514,12 +514,13 @@ especially true of = and zero?. When in doubt, consult a numerical analyst. @deffnx procedure odd? n @deffnx procedure even? n -These numerical predicates test a number for a particular property, returning #t or #f. +These numerical predicates test a number for a particular property, returning @code{#t} or @code{#f}. See note above. + @end deffn -@deffn procedure max x1 x2@dots{} -@deffnx procedure min x1 x2@dots{} +@deffn procedure max x@sub{1} x@sub{2}@dots{} +@deffnx procedure min x@sub{1} x@sub{2}@dots{} These procedures return the maximum or minimum of their arguments. @@ -530,14 +531,15 @@ These procedures return the maximum or minimum of their arguments. Note: If any argument is inexact, then the result will also be inexact (unless the procedure can prove that the inaccuracy is not large enough to affect the result, -which is possible only in unusual implementations). If min or max is used to compare +which is possible only in unusual implementations). If @code{min} or @code{max} is used to compare numbers of mixed exactness, and the numerical value of the result cannot be represented as an inexact number without loss of accuracy, then the procedure may report a violation of an implementation restriction. + @end deffn -@deffn procedure + z1 @dots{} -@deffnx procedure * z1 @dots{} +@deffn procedure + z@sub{1}@dots{} +@deffnx procedure * z@sub{1}@dots{} These procedures return the sum or product of their arguments. @@ -551,15 +553,15 @@ These procedures return the sum or product of their arguments. @end deffn @deffn procedure - z -@deffnx procedure - z1 z2@dots{} +@deffnx procedure - z@sub{1} z@sub{2}@dots{} @deffnx procedure / z -@deffnx procedure / z1 z2@dots{} +@deffnx procedure / z@sub{1} z@sub{2}@dots{} With two or more arguments, these procedures return the difference or quotient of their arguments, associating to the left. With one argument, however, they return the additive or multiplicative inverse of their argument. -It is an error if any argument of / other than the first is an exact zero. If the first +It is an error if any argument of @code{/} other than the first is an exact zero. If the first argument is an exact zero, an implementation may return an exact zero unless one of the other arguments is a NaN. @@ -570,6 +572,7 @@ other arguments is a NaN. (/ 3 4 5) @result{} 3/20 (/ 3) @result{} 1/3 @end example + @end deffn @deffn procedure abs x @@ -579,106 +582,55 @@ The abs procedure returns the absolute value of its argument. @example (abs -7) @result{} 7 @end example -@end deffn - -@deffn procedure floor/ n1 n2 -@deffnx procedure floor-quotient n1 n2 -@deffnx procedure floor-remainder n1 n2 -@deffnx procedure truncate/ n1 n2 -@deffnx procedure truncate-quotient n1 n2 -@deffnx procedure truncate-remainder n1 n2 - -These procedures implement number-theoretic (integer) division. It is an error if - -n2 is zero. The procedures ending in / return two integers; the other procedures return an -integer. All the procedures compute a quotient - -nq and remainder - -nr such that - -n1 = - -n2 - -nq + - -nr. For each of the division operators, there are three procedures defined as follows: - -(@svar{operator}/ - -n1 - -n2) @result{} - -nq - -nr -(@svar{operator}-quotient - -n1 - -n2) @result{} -nq -(@svar{operator}-remainder - -n1 - -n2) @result{} - -nr - -The remainder - -nr is determined by the choice of integer - -nq: - -nr = - -n1 − - -n2 - -nq. Each set of operators uses a different choice of - -nq: - - floor nq = ⌊ - - n1 / - - n2⌋ - truncate nq = texttruncate( - - n1 / - - n2) - -For any of the operators, and for integers - -n1 and - -n2 with - -n2 not equal to 0, - -(= - -n1 (+ (* - -n2 (@svar{operator}-quotient - -n1 - -n2)) - (@svar{operator}-remainder - -n1 +@end deffn -n2))) - @result{} #t +@deffn procedure floor/ n@sub{1} n@sub{2} +@deffnx procedure floor-quotient n@sub{1} n@sub{2} +@deffnx procedure floor-remainder n@sub{1} n@sub{2} +@deffnx procedure truncate/ n@sub{1} n@sub{2} +@deffnx procedure truncate-quotient n@sub{1} n@sub{2} +@deffnx procedure truncate-remainder n@sub{1} n@sub{2} + +These procedures implement +number-theoretic (integer) division. It is an error if @var{n} is zero. +The procedures ending in @code{/} return two integers; the other +procedures return an integer. All the procedures compute a +quotient @var{n@sub{q}} and remainder @var{n@sub{r}} such that +@var{n@sub{1}} = @var{n@sub{2}}@var{n@sub{q}} + @var{n@sub{r}}. For each of the +division operators, there are three procedures defined as follows: + +@c This is hideous. Can we do any better? +@lisp +(@r{@svar{operator}}/ @r{@var{n@sub{1}} @var{n@sub{2}}}) @result{} @r{@var{n@sub{q}} @var{n@sub{r}}} +(@r{@svar{operator}}-quotient @r{@var{n@sub{1}} @var{n@sub{2}}}) @result{} @r{@var{n@sub{q}}} +(@r{@svar{operator}}-remainder @r{@var{n@sub{1}} @var{n@sub{2}}}) @result{} @r{@var{n@sub{r}}} +@end lisp + +The remainder @var{n@sub{r}} is determined by the choice of integer +@var{n@sub{q}}: @var{n@sub{r}} = @var{n@sub{1}} @minus{} +@var{n@sub{2}}@var{n@sub{q}}. Each set of +operators uses a different choice of @var{n@sub{q}}: + +@table @code + +@item floor +@math{n_q = \lfloor n_1 / n_2 \rfloor} + +@item truncate +@math{n_q =} truncate@math{(n_1 / n_2)} + +@end table + +For any of the operators, and for integers @var{n@sub{1}} and @var{n@sub{2}} +with @var{n@sub{2}} not equal to 0, + +@lisp +(= @r{@var{n@sub{1}}} + (+ (* @r{@var{n@sub{2}}} (@r{@svar{operator}}-quotient @r{@var{n@sub{1}} @var{n@sub{2}}})) + (@r{@svar{operator}}-remainder @r{@var{n@sub{1}} @var{n@sub{2}}}))) + @result{} #t +@end lisp provided all numbers involved in that computation are exact. @@ -695,21 +647,24 @@ Examples: (truncate/ -5 -2) @result{} 2 -1 (truncate/ -5.0 -2) @result{} 2.0 -1.0 @end example + @end deffn -@deffn procedure quotient n1 n2 -@deffnx procedure remainder n1 n2 -@deffnx procedure modulo n1 n2 +@deffn procedure quotient n@sub{1} n@sub{2} +@deffnx procedure remainder n@sub{1} n@sub{2} +@deffnx procedure modulo n@sub{1} n@sub{2} -The quotient and remainder procedures are equivalent to truncate-quotient and -truncate-remainder, respectively, and modulo is equivalent to floor-remainder. +The @code{quotient} and @code{remainder} procedures are equivalent to +@code{truncate-quotient} and @code{truncate-remainder}, respectively, and +@code{modulo} is equivalent to @code{floor-remainder}. Note: These procedures are provided for backward compatibility with earlier versions of this report. + @end deffn -@deffn procedure gcd n1 @dots{} -@deffnx procedure lcm n1 @dots{} +@deffn procedure gcd n@sub{1}@dots{} +@deffnx procedure lcm n@sub{1}@dots{} These procedures return the greatest common divisor or least common multiple of their arguments. The result is always non-negative. @@ -721,6 +676,7 @@ arguments. The result is always non-negative. (lcm 32.0 -36) @result{} 288.0 ; inexact (lcm) @result{} 1 @end example + @end deffn @deffn procedure numerator q @@ -736,6 +692,7 @@ denominator is always positive. The denominator of 0 is defined to be 1. (denominator (inexact (/ 6 4))) @result{} 2.0 @end example + @end deffn @deffn procedure floor x @@ -743,26 +700,19 @@ denominator is always positive. The denominator of 0 is defined to be 1. @deffnx procedure truncate x @deffnx procedure round x -These procedures return integers. The floor procedure returns the largest integer not -larger than - -x. The ceiling procedure returns the smallest integer not smaller than - -x, truncate returns the integer closest to - -x whose absolute value is not larger than the absolute value of - -x, and round returns the closest integer to +These procedures return integers. +The @code{floor} procedure returns the largest integer not larger than @var{x}. +The @code{ceiling} procedure returns the smallest integer not smaller than @var{x}, +@code{truncate} returns the integer closest to @var{x} whose absolute +value is not larger than the absolute value of @var{x}, and @code{round} returns the +closest integer to @var{x}, rounding to even when @var{x} is halfway between two +integers. -x, rounding to even when - -x is halfway between two integers. - -Rationale: The round procedure rounds to even for consistency with the default +Rationale: The @code{round} procedure rounds to even for consistency with the default rounding mode specified by the IEEE 754 IEEE floating-point standard. Note: If the argument to one of these procedures is inexact, then the result will also -be inexact. If an exact value is needed, the result can be passed to the exact +be inexact. If an exact value is needed, the result can be passed to the @code{exact} procedure. If the argument is infinite or a NaN, then it is returned. @example @@ -779,20 +729,22 @@ procedure. If the argument is infinite or a NaN, then it is returned. (round 7/2) @result{} 4 ; exact (round 7) @result{} 7 @end example + @end deffn @deffn procedure rationalize x y -The rationalize procedure returns the simplest rational number differing from - -x by no more than - -y. A rational number r1 is simpler than another rational number r2 if r1 = p1/q1 and r2 = -p2/q2 (in lowest terms) and |p1| ≤|p2| and |q1| ≤|q2|. Thus 3/5 is simpler than 4/7. -Although not all rationals are comparable in this ordering (consider 2/7 and 3/5), any -interval contains a rational number that is simpler than every other rational number in -that interval (the simpler 2/5 lies between 2/7 and 3/5). Note that 0 = 0/1 is the simplest -rational of all. +@c TODO: Math mode is probably overkill here. Use normal insertions? +The @code{rationalize} procedure returns the @emph{simplest} rational number +differing from @var{x} by no more than @var{y}. A rational number @var{r@sub{1}} is +@emph{simpler} than another rational number +@var{r@sub{2}} if @math{r_1 = p_1/q_1} and @math{r_2 = p_2/q_2} (in lowest terms) and +@math{|p_1| \leq |p_2|} and @math{|q_1| \leq |q_2|}. Thus 3/5 is simpler than 4/7. +Although not all rationals are comparable in this ordering (consider 2/7 +and 3/5), any interval contains a rational number that is simpler than +every other rational number in that interval (the simpler 2/5 lies +between 2/7 and 3/5). Note that 0 = 0/1 is the simplest rational of +all. @example (rationalize