mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-11 06:20:23 +02:00
Add four new sets of fast quotient and remainder operators
* libguile/numbers.c (scm_floor_divide, scm_floor_quotient, scm_floor_remainder, scm_ceiling_divide, scm_ceiling_quotient, scm_ceiling_remainder, scm_truncate_divide, scm_truncate_quotient, scm_truncate_remainder, scm_round_divide, scm_round_quotient, scm_round_remainder): New extensible procedures `floor/', `floor-quotient', `floor-remainder', `ceiling/', `ceiling-quotient', `ceiling-remainder', `truncate/', `truncate-quotient', `truncate-remainder', `round/', `round-quotient', and `round-remainder'. * libguile/numbers.h: Add function prototypes. * test-suite/tests/numbers.test: Add tests. * doc/ref/api-data.texi (Arithmetic): Add documentation. * NEWS: Add NEWS entry.
This commit is contained in:
parent
03ddd15bae
commit
8f9da3406b
5 changed files with 2451 additions and 3 deletions
28
NEWS
28
NEWS
|
@ -23,6 +23,34 @@ instead.
|
||||||
`define-once' is like Lisp's `defvar': it creates a toplevel binding,
|
`define-once' is like Lisp's `defvar': it creates a toplevel binding,
|
||||||
but only if one does not exist already.
|
but only if one does not exist already.
|
||||||
|
|
||||||
|
** Added four new sets of fast quotient and remainder operators
|
||||||
|
|
||||||
|
Added four new sets of fast quotient and remainder operators with
|
||||||
|
different semantics than the R5RS operators. They support not only
|
||||||
|
integers, but all reals, including exact rationals and inexact
|
||||||
|
floating point numbers.
|
||||||
|
|
||||||
|
These procedures accept two real numbers N and D, where the divisor D
|
||||||
|
must be non-zero. Each set of operators computes an integer quotient
|
||||||
|
Q and a real remainder R such that N = Q*D + R and |R| < |D|. They
|
||||||
|
differ only in how N/D is rounded to produce Q.
|
||||||
|
|
||||||
|
`floor-quotient' and `floor-remainder' compute Q and R, respectively,
|
||||||
|
where Q has been rounded toward negative infinity. `floor/' returns
|
||||||
|
both Q and R, and is more efficient than computing each separately.
|
||||||
|
Note that when applied to integers, `floor-remainder' is equivalent to
|
||||||
|
the R5RS integer-only `modulo' operator. `ceiling-quotient',
|
||||||
|
`ceiling-remainder', and `ceiling/' are similar except that Q is
|
||||||
|
rounded toward positive infinity.
|
||||||
|
|
||||||
|
For `truncate-quotient', `truncate-remainder', and `truncate/', Q is
|
||||||
|
rounded toward zero. Note that when applied to integers,
|
||||||
|
`truncate-quotient' and `truncate-remainder' are equivalent to the
|
||||||
|
R5RS integer-only operators `quotient' and `remainder'.
|
||||||
|
|
||||||
|
For `round-quotient', `round-remainder', and `round/', Q is rounded to
|
||||||
|
the nearest integer, with ties going to the nearest even integer.
|
||||||
|
|
||||||
** Improved exactness handling for complex number parsing
|
** Improved exactness handling for complex number parsing
|
||||||
|
|
||||||
When parsing non-real complex numbers, exactness specifiers are now
|
When parsing non-real complex numbers, exactness specifiers are now
|
||||||
|
|
|
@ -907,7 +907,7 @@ sign as @var{n}. In all cases quotient and remainder satisfy
|
||||||
(remainder -13 4) @result{} -1
|
(remainder -13 4) @result{} -1
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
See also @code{euclidean-quotient}, @code{euclidean-remainder} and
|
See also @code{truncate-quotient}, @code{truncate-remainder} and
|
||||||
related operations in @ref{Arithmetic}.
|
related operations in @ref{Arithmetic}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@ -924,7 +924,7 @@ sign as @var{d}.
|
||||||
(modulo -13 -4) @result{} -1
|
(modulo -13 -4) @result{} -1
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
See also @code{euclidean-quotient}, @code{euclidean-remainder} and
|
See also @code{floor-quotient}, @code{floor-remainder} and
|
||||||
related operations in @ref{Arithmetic}.
|
related operations in @ref{Arithmetic}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@ -1148,9 +1148,21 @@ Returns the magnitude or angle of @var{z} as a @code{double}.
|
||||||
@rnindex euclidean/
|
@rnindex euclidean/
|
||||||
@rnindex euclidean-quotient
|
@rnindex euclidean-quotient
|
||||||
@rnindex euclidean-remainder
|
@rnindex euclidean-remainder
|
||||||
|
@rnindex floor/
|
||||||
|
@rnindex floor-quotient
|
||||||
|
@rnindex floor-remainder
|
||||||
|
@rnindex ceiling/
|
||||||
|
@rnindex ceiling-quotient
|
||||||
|
@rnindex ceiling-remainder
|
||||||
|
@rnindex truncate/
|
||||||
|
@rnindex truncate-quotient
|
||||||
|
@rnindex truncate-remainder
|
||||||
@rnindex centered/
|
@rnindex centered/
|
||||||
@rnindex centered-quotient
|
@rnindex centered-quotient
|
||||||
@rnindex centered-remainder
|
@rnindex centered-remainder
|
||||||
|
@rnindex round/
|
||||||
|
@rnindex round-quotient
|
||||||
|
@rnindex round-remainder
|
||||||
|
|
||||||
The C arithmetic functions below always takes two arguments, while the
|
The C arithmetic functions below always takes two arguments, while the
|
||||||
Scheme functions can take an arbitrary number. When you need to
|
Scheme functions can take an arbitrary number. When you need to
|
||||||
|
@ -1281,6 +1293,93 @@ Note that these operators are equivalent to the R6RS operators
|
||||||
@end lisp
|
@end lisp
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Scheme Procedure} {} floor/ @var{x} @var{y}
|
||||||
|
@deftypefnx {Scheme Procedure} {} floor-quotient @var{x} @var{y}
|
||||||
|
@deftypefnx {Scheme Procedure} {} floor-remainder @var{x} @var{y}
|
||||||
|
@deftypefnx {C Function} void scm_floor_divide (SCM @var{x}, SCM @var{y}, SCM *@var{q}, SCM *@var{r})
|
||||||
|
@deftypefnx {C Function} SCM scm_floor_quotient (@var{x}, @var{y})
|
||||||
|
@deftypefnx {C Function} SCM scm_floor_remainder (@var{x}, @var{y})
|
||||||
|
These procedures accept two real numbers @var{x} and @var{y}, where the
|
||||||
|
divisor @var{y} must be non-zero. @code{floor-quotient} returns the
|
||||||
|
integer @var{q} and @code{floor-remainder} returns the real number
|
||||||
|
@var{r} such that @math{@var{q} = floor(@var{x}/@var{y})} and
|
||||||
|
@math{@var{x} = @var{q}*@var{y} + @var{r}}. @code{floor/} returns
|
||||||
|
both @var{q} and @var{r}, and is more efficient than computing each
|
||||||
|
separately. Note that @var{r}, if non-zero, will have the same sign
|
||||||
|
as @var{y}.
|
||||||
|
|
||||||
|
When @var{x} and @var{y} are integers, @code{floor-quotient} is
|
||||||
|
equivalent to the R5RS integer-only operator @code{modulo}.
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(floor-quotient 123 10) @result{} 12
|
||||||
|
(floor-remainder 123 10) @result{} 3
|
||||||
|
(floor/ 123 10) @result{} 12 and 3
|
||||||
|
(floor/ 123 -10) @result{} -13 and -7
|
||||||
|
(floor/ -123 10) @result{} -13 and 7
|
||||||
|
(floor/ -123 -10) @result{} 12 and -3
|
||||||
|
(floor/ -123.2 -63.5) @result{} 1.0 and -59.7
|
||||||
|
(floor/ 16/3 -10/7) @result{} -4 and -8/21
|
||||||
|
@end lisp
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Scheme Procedure} {} ceiling/ @var{x} @var{y}
|
||||||
|
@deftypefnx {Scheme Procedure} {} ceiling-quotient @var{x} @var{y}
|
||||||
|
@deftypefnx {Scheme Procedure} {} ceiling-remainder @var{x} @var{y}
|
||||||
|
@deftypefnx {C Function} void scm_ceiling_divide (SCM @var{x}, SCM @var{y}, SCM *@var{q}, SCM *@var{r})
|
||||||
|
@deftypefnx {C Function} SCM scm_ceiling_quotient (@var{x}, @var{y})
|
||||||
|
@deftypefnx {C Function} SCM scm_ceiling_remainder (@var{x}, @var{y})
|
||||||
|
These procedures accept two real numbers @var{x} and @var{y}, where the
|
||||||
|
divisor @var{y} must be non-zero. @code{ceiling-quotient} returns the
|
||||||
|
integer @var{q} and @code{ceiling-remainder} returns the real number
|
||||||
|
@var{r} such that @math{@var{q} = ceiling(@var{x}/@var{y})} and
|
||||||
|
@math{@var{x} = @var{q}*@var{y} + @var{r}}. @code{ceiling/} returns
|
||||||
|
both @var{q} and @var{r}, and is more efficient than computing each
|
||||||
|
separately. Note that @var{r}, if non-zero, will have the opposite sign
|
||||||
|
of @var{y}.
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(ceiling-quotient 123 10) @result{} 13
|
||||||
|
(ceiling-remainder 123 10) @result{} -7
|
||||||
|
(ceiling/ 123 10) @result{} 13 and -7
|
||||||
|
(ceiling/ 123 -10) @result{} -12 and 3
|
||||||
|
(ceiling/ -123 10) @result{} -12 and -3
|
||||||
|
(ceiling/ -123 -10) @result{} 13 and 7
|
||||||
|
(ceiling/ -123.2 -63.5) @result{} 2.0 and 3.8
|
||||||
|
(ceiling/ 16/3 -10/7) @result{} -3 and 22/21
|
||||||
|
@end lisp
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Scheme Procedure} {} truncate/ @var{x} @var{y}
|
||||||
|
@deftypefnx {Scheme Procedure} {} truncate-quotient @var{x} @var{y}
|
||||||
|
@deftypefnx {Scheme Procedure} {} truncate-remainder @var{x} @var{y}
|
||||||
|
@deftypefnx {C Function} void scm_truncate_divide (SCM @var{x}, SCM @var{y}, SCM *@var{q}, SCM *@var{r})
|
||||||
|
@deftypefnx {C Function} SCM scm_truncate_quotient (@var{x}, @var{y})
|
||||||
|
@deftypefnx {C Function} SCM scm_truncate_remainder (@var{x}, @var{y})
|
||||||
|
These procedures accept two real numbers @var{x} and @var{y}, where the
|
||||||
|
divisor @var{y} must be non-zero. @code{truncate-quotient} returns the
|
||||||
|
integer @var{q} and @code{truncate-remainder} returns the real number
|
||||||
|
@var{r} such that @var{q} is @math{@var{x}/@var{y}} rounded toward zero,
|
||||||
|
and @math{@var{x} = @var{q}*@var{y} + @var{r}}. @code{truncate/} returns
|
||||||
|
both @var{q} and @var{r}, and is more efficient than computing each
|
||||||
|
separately. Note that @var{r}, if non-zero, will have the same sign
|
||||||
|
as @var{x}.
|
||||||
|
|
||||||
|
When @var{x} and @var{y} are integers, these operators are equivalent to
|
||||||
|
the R5RS integer-only operators @code{quotient} and @code{remainder}.
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(truncate-quotient 123 10) @result{} 12
|
||||||
|
(truncate-remainder 123 10) @result{} 3
|
||||||
|
(truncate/ 123 10) @result{} 12 and 3
|
||||||
|
(truncate/ 123 -10) @result{} -12 and 3
|
||||||
|
(truncate/ -123 10) @result{} -12 and -3
|
||||||
|
(truncate/ -123 -10) @result{} 12 and -3
|
||||||
|
(truncate/ -123.2 -63.5) @result{} 1.0 and -59.7
|
||||||
|
(truncate/ 16/3 -10/7) @result{} -3 and 22/21
|
||||||
|
@end lisp
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
@deftypefn {Scheme Procedure} {} centered/ @var{x} @var{y}
|
@deftypefn {Scheme Procedure} {} centered/ @var{x} @var{y}
|
||||||
@deftypefnx {Scheme Procedure} {} centered-quotient @var{x} @var{y}
|
@deftypefnx {Scheme Procedure} {} centered-quotient @var{x} @var{y}
|
||||||
@deftypefnx {Scheme Procedure} {} centered-remainder @var{x} @var{y}
|
@deftypefnx {Scheme Procedure} {} centered-remainder @var{x} @var{y}
|
||||||
|
@ -1313,11 +1412,56 @@ Note that these operators are equivalent to the R6RS operators
|
||||||
(centered/ 123 -10) @result{} -12 and 3
|
(centered/ 123 -10) @result{} -12 and 3
|
||||||
(centered/ -123 10) @result{} -12 and -3
|
(centered/ -123 10) @result{} -12 and -3
|
||||||
(centered/ -123 -10) @result{} 12 and -3
|
(centered/ -123 -10) @result{} 12 and -3
|
||||||
|
(centered/ 125 10) @result{} 13 and -5
|
||||||
|
(centered/ 127 10) @result{} 13 and -3
|
||||||
|
(centered/ 135 10) @result{} 14 and -5
|
||||||
(centered/ -123.2 -63.5) @result{} 2.0 and 3.8
|
(centered/ -123.2 -63.5) @result{} 2.0 and 3.8
|
||||||
(centered/ 16/3 -10/7) @result{} -4 and -8/21
|
(centered/ 16/3 -10/7) @result{} -4 and -8/21
|
||||||
@end lisp
|
@end lisp
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {Scheme Procedure} {} round/ @var{x} @var{y}
|
||||||
|
@deftypefnx {Scheme Procedure} {} round-quotient @var{x} @var{y}
|
||||||
|
@deftypefnx {Scheme Procedure} {} round-remainder @var{x} @var{y}
|
||||||
|
@deftypefnx {C Function} void scm_round_divide (SCM @var{x}, SCM @var{y}, SCM *@var{q}, SCM *@var{r})
|
||||||
|
@deftypefnx {C Function} SCM scm_round_quotient (@var{x}, @var{y})
|
||||||
|
@deftypefnx {C Function} SCM scm_round_remainder (@var{x}, @var{y})
|
||||||
|
These procedures accept two real numbers @var{x} and @var{y}, where the
|
||||||
|
divisor @var{y} must be non-zero. @code{round-quotient} returns the
|
||||||
|
integer @var{q} and @code{round-remainder} returns the real number
|
||||||
|
@var{r} such that @math{@var{x} = @var{q}*@var{y} + @var{r}} and
|
||||||
|
@var{q} is @math{@var{x}/@var{y}} rounded to the nearest integer,
|
||||||
|
with ties going to the nearest even integer. @code{round/}
|
||||||
|
returns both @var{q} and @var{r}, and is more efficient than computing
|
||||||
|
each separately.
|
||||||
|
|
||||||
|
Note that @code{round/} and @code{centered/} are almost equivalent, but
|
||||||
|
their behavior differs when @math{@var{x}/@var{y}} lies exactly half-way
|
||||||
|
between two integers. In this case, @code{round/} chooses the nearest
|
||||||
|
even integer, whereas @code{centered/} chooses in such a way to satisfy
|
||||||
|
the constraint @math{-|@var{y}/2| <= @var{r} < |@var{y}/2|}, which
|
||||||
|
is stronger than the corresponding constraint for @code{round/},
|
||||||
|
@math{-|@var{y}/2| <= @var{r} <= |@var{y}/2|}. In particular,
|
||||||
|
when @var{x} and @var{y} are integers, the number of possible remainders
|
||||||
|
returned by @code{centered/} is @math{|@var{y}|}, whereas the number of
|
||||||
|
possible remainders returned by @code{round/} is @math{|@var{y}|+1} when
|
||||||
|
@var{y} is even.
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(round-quotient 123 10) @result{} 12
|
||||||
|
(round-remainder 123 10) @result{} 3
|
||||||
|
(round/ 123 10) @result{} 12 and 3
|
||||||
|
(round/ 123 -10) @result{} -12 and 3
|
||||||
|
(round/ -123 10) @result{} -12 and -3
|
||||||
|
(round/ -123 -10) @result{} 12 and -3
|
||||||
|
(round/ 125 10) @result{} 12 and 5
|
||||||
|
(round/ 127 10) @result{} 13 and -3
|
||||||
|
(round/ 135 10) @result{} 14 and -5
|
||||||
|
(round/ -123.2 -63.5) @result{} 2.0 and 3.8
|
||||||
|
(round/ 16/3 -10/7) @result{} -4 and -8/21
|
||||||
|
@end lisp
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
@node Scientific
|
@node Scientific
|
||||||
@subsubsection Scientific Functions
|
@subsubsection Scientific Functions
|
||||||
|
|
||||||
|
|
2187
libguile/numbers.c
2187
libguile/numbers.c
File diff suppressed because it is too large
Load diff
|
@ -181,9 +181,21 @@ SCM_API SCM scm_modulo (SCM x, SCM y);
|
||||||
SCM_API void scm_euclidean_divide (SCM x, SCM y, SCM *q, SCM *r);
|
SCM_API void scm_euclidean_divide (SCM x, SCM y, SCM *q, SCM *r);
|
||||||
SCM_API SCM scm_euclidean_quotient (SCM x, SCM y);
|
SCM_API SCM scm_euclidean_quotient (SCM x, SCM y);
|
||||||
SCM_API SCM scm_euclidean_remainder (SCM x, SCM y);
|
SCM_API SCM scm_euclidean_remainder (SCM x, SCM y);
|
||||||
|
SCM_API void scm_floor_divide (SCM x, SCM y, SCM *q, SCM *r);
|
||||||
|
SCM_API SCM scm_floor_quotient (SCM x, SCM y);
|
||||||
|
SCM_API SCM scm_floor_remainder (SCM x, SCM y);
|
||||||
|
SCM_API void scm_ceiling_divide (SCM x, SCM y, SCM *q, SCM *r);
|
||||||
|
SCM_API SCM scm_ceiling_quotient (SCM x, SCM y);
|
||||||
|
SCM_API SCM scm_ceiling_remainder (SCM x, SCM y);
|
||||||
|
SCM_API void scm_truncate_divide (SCM x, SCM y, SCM *q, SCM *r);
|
||||||
|
SCM_API SCM scm_truncate_quotient (SCM x, SCM y);
|
||||||
|
SCM_API SCM scm_truncate_remainder (SCM x, SCM y);
|
||||||
SCM_API void scm_centered_divide (SCM x, SCM y, SCM *q, SCM *r);
|
SCM_API void scm_centered_divide (SCM x, SCM y, SCM *q, SCM *r);
|
||||||
SCM_API SCM scm_centered_quotient (SCM x, SCM y);
|
SCM_API SCM scm_centered_quotient (SCM x, SCM y);
|
||||||
SCM_API SCM scm_centered_remainder (SCM x, SCM y);
|
SCM_API SCM scm_centered_remainder (SCM x, SCM y);
|
||||||
|
SCM_API void scm_round_divide (SCM x, SCM y, SCM *q, SCM *r);
|
||||||
|
SCM_API SCM scm_round_quotient (SCM x, SCM y);
|
||||||
|
SCM_API SCM scm_round_remainder (SCM x, SCM y);
|
||||||
SCM_API SCM scm_gcd (SCM x, SCM y);
|
SCM_API SCM scm_gcd (SCM x, SCM y);
|
||||||
SCM_API SCM scm_lcm (SCM n1, SCM n2);
|
SCM_API SCM scm_lcm (SCM n1, SCM n2);
|
||||||
SCM_API SCM scm_logand (SCM n1, SCM n2);
|
SCM_API SCM scm_logand (SCM n1, SCM n2);
|
||||||
|
@ -200,7 +212,11 @@ SCM_API SCM scm_logcount (SCM n);
|
||||||
SCM_API SCM scm_integer_length (SCM n);
|
SCM_API SCM scm_integer_length (SCM n);
|
||||||
|
|
||||||
SCM_INTERNAL SCM scm_i_euclidean_divide (SCM x, SCM y);
|
SCM_INTERNAL SCM scm_i_euclidean_divide (SCM x, SCM y);
|
||||||
|
SCM_INTERNAL SCM scm_i_floor_divide (SCM x, SCM y);
|
||||||
|
SCM_INTERNAL SCM scm_i_ceiling_divide (SCM x, SCM y);
|
||||||
|
SCM_INTERNAL SCM scm_i_truncate_divide (SCM x, SCM y);
|
||||||
SCM_INTERNAL SCM scm_i_centered_divide (SCM x, SCM y);
|
SCM_INTERNAL SCM scm_i_centered_divide (SCM x, SCM y);
|
||||||
|
SCM_INTERNAL SCM scm_i_round_divide (SCM x, SCM y);
|
||||||
|
|
||||||
SCM_INTERNAL SCM scm_i_gcd (SCM x, SCM y, SCM rest);
|
SCM_INTERNAL SCM scm_i_gcd (SCM x, SCM y, SCM rest);
|
||||||
SCM_INTERNAL SCM scm_i_lcm (SCM x, SCM y, SCM rest);
|
SCM_INTERNAL SCM scm_i_lcm (SCM x, SCM y, SCM rest);
|
||||||
|
|
|
@ -4148,6 +4148,42 @@
|
||||||
(test-within-range? 0 <= r < (abs y)))
|
(test-within-range? 0 <= r < (abs y)))
|
||||||
(test-eqv? q (/ x y)))))
|
(test-eqv? q (/ x y)))))
|
||||||
|
|
||||||
|
(define (valid-floor-answer? x y q r)
|
||||||
|
(and (eq? (exact? q)
|
||||||
|
(exact? r)
|
||||||
|
(and (exact? x) (exact? y)))
|
||||||
|
(test-eqv? r (- x (* q y)))
|
||||||
|
(if (and (finite? x) (finite? y))
|
||||||
|
(and (integer? q)
|
||||||
|
(if (> y 0)
|
||||||
|
(test-within-range? 0 <= r < y)
|
||||||
|
(test-within-range? y < r <= 0)))
|
||||||
|
(test-eqv? q (/ x y)))))
|
||||||
|
|
||||||
|
(define (valid-ceiling-answer? x y q r)
|
||||||
|
(and (eq? (exact? q)
|
||||||
|
(exact? r)
|
||||||
|
(and (exact? x) (exact? y)))
|
||||||
|
(test-eqv? r (- x (* q y)))
|
||||||
|
(if (and (finite? x) (finite? y))
|
||||||
|
(and (integer? q)
|
||||||
|
(if (> y 0)
|
||||||
|
(test-within-range? (- y) < r <= 0)
|
||||||
|
(test-within-range? 0 <= r < (- y))))
|
||||||
|
(test-eqv? q (/ x y)))))
|
||||||
|
|
||||||
|
(define (valid-truncate-answer? x y q r)
|
||||||
|
(and (eq? (exact? q)
|
||||||
|
(exact? r)
|
||||||
|
(and (exact? x) (exact? y)))
|
||||||
|
(test-eqv? r (- x (* q y)))
|
||||||
|
(if (and (finite? x) (finite? y))
|
||||||
|
(and (integer? q)
|
||||||
|
(if (> x 0)
|
||||||
|
(test-within-range? 0 <= r < (abs y))
|
||||||
|
(test-within-range? (- (abs y)) < r <= 0)))
|
||||||
|
(test-eqv? q (/ x y)))))
|
||||||
|
|
||||||
(define (valid-centered-answer? x y q r)
|
(define (valid-centered-answer? x y q r)
|
||||||
(and (eq? (exact? q)
|
(and (eq? (exact? q)
|
||||||
(exact? r)
|
(exact? r)
|
||||||
|
@ -4159,6 +4195,19 @@
|
||||||
(* -1/2 (abs y)) <= r < (* +1/2 (abs y))))
|
(* -1/2 (abs y)) <= r < (* +1/2 (abs y))))
|
||||||
(test-eqv? q (/ x y)))))
|
(test-eqv? q (/ x y)))))
|
||||||
|
|
||||||
|
(define (valid-round-answer? x y q r)
|
||||||
|
(and (eq? (exact? q)
|
||||||
|
(exact? r)
|
||||||
|
(and (exact? x) (exact? y)))
|
||||||
|
(test-eqv? r (- x (* q y)))
|
||||||
|
(if (and (finite? x) (finite? y))
|
||||||
|
(and (integer? q)
|
||||||
|
(let ((ay/2 (/ (abs y) 2)))
|
||||||
|
(if (even? q)
|
||||||
|
(test-within-range? (- ay/2) <= r <= ay/2)
|
||||||
|
(test-within-range? (- ay/2) < r < ay/2))))
|
||||||
|
(test-eqv? q (/ x y)))))
|
||||||
|
|
||||||
(define (for lsts f) (apply for-each f lsts))
|
(define (for lsts f) (apply for-each f lsts))
|
||||||
|
|
||||||
(define big (expt 10 (1+ (inexact->exact (ceiling (log10 fixnum-max))))))
|
(define big (expt 10 (1+ (inexact->exact (ceiling (log10 fixnum-max))))))
|
||||||
|
@ -4284,8 +4333,32 @@
|
||||||
euclidean-remainder
|
euclidean-remainder
|
||||||
valid-euclidean-answer?))
|
valid-euclidean-answer?))
|
||||||
|
|
||||||
|
(with-test-prefix "floor/"
|
||||||
|
(run-division-tests floor/
|
||||||
|
floor-quotient
|
||||||
|
floor-remainder
|
||||||
|
valid-floor-answer?))
|
||||||
|
|
||||||
|
(with-test-prefix "ceiling/"
|
||||||
|
(run-division-tests ceiling/
|
||||||
|
ceiling-quotient
|
||||||
|
ceiling-remainder
|
||||||
|
valid-ceiling-answer?))
|
||||||
|
|
||||||
|
(with-test-prefix "truncate/"
|
||||||
|
(run-division-tests truncate/
|
||||||
|
truncate-quotient
|
||||||
|
truncate-remainder
|
||||||
|
valid-truncate-answer?))
|
||||||
|
|
||||||
(with-test-prefix "centered/"
|
(with-test-prefix "centered/"
|
||||||
(run-division-tests centered/
|
(run-division-tests centered/
|
||||||
centered-quotient
|
centered-quotient
|
||||||
centered-remainder
|
centered-remainder
|
||||||
valid-centered-answer?)))
|
valid-centered-answer?))
|
||||||
|
|
||||||
|
(with-test-prefix "round/"
|
||||||
|
(run-division-tests round/
|
||||||
|
round-quotient
|
||||||
|
round-remainder
|
||||||
|
valid-round-answer?)))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue