ref: 25ad19ea481a62ab7f332a6db33b54bfb74eeeff
parent: ebdc0451c39c70ce88b3b6ab9ba2b8e389ec519a
author: Matthew Flatt <mflatt@racket-lang.org>
date: Fri Dec 8 05:03:07 CST 2023
change `modulo` to `remainder` and add `modulo` The function formerly known as `modulo` was actually `remainder`, so rename it, but add `modulo` to the library. This change is not technically less backward-compatible than most changes, since it removes `modulo` from `zuo/kernel`. Thanks to @soegaard for noticing the problem and providing a first cut at a repair.
--- a/lib/zuo/build.zuo
+++ b/lib/zuo/build.zuo
@@ -79,7 +79,7 @@
(string=? s no-sha256)
;; also allow a concatenation of SHA-256s for multi-file targets
(and (>= (string-length s) sha256-length)
- (= 0 (modulo (string-length s) sha256-length)))))
+ (= 0 (remainder (string-length s) sha256-length)))))
(eq? s phony-sha256)))
;; public constructor
--- a/lib/zuo/private/base-common/lib.zuo
+++ b/lib/zuo/private/base-common/lib.zuo
@@ -41,3 +41,13 @@
(define (gensym sym)
(string->uninterned-symbol (symbol->string sym)))
+
+(define (modulo n m)
+ (let ([r (remainder n m)])
+ (if (>= m 0)
+ (if (>= n 0)
+ r
+ (- r))
+ (if (< n 0)
+ r
+ (+ r n)))))
--- a/lib/zuo/private/more.zuo
+++ b/lib/zuo/private/more.zuo
@@ -10,6 +10,8 @@
boolean?
string-tree?
+ modulo
+
equal?
assoc
member
@@ -58,6 +60,17 @@
(or (string? v)
(and (list? v)
(andmap string-tree? v))))
+
+(define (modulo n m)
+ (unless (integer? n) (arg-error 'modulo "integer" n))
+ (unless (integer? m) (arg-error 'modulo "integer" m))
+ (when (= m 0) (error "modulo: divide by zero"))
+ (let ([r (remainder n m)])
+ (if (eq? (>= m 0) (>= n 0))
+ r
+ (if (= r 0)
+ 0
+ (+ r m)))))
(define (equal? a b)
(or (eq? a b)
--- a/tests/integer.zuo
+++ b/tests/integer.zuo
@@ -63,16 +63,30 @@
(check-arg-fail (quotient 5 'apple) not-integer)
(check-arg-fail (quotient 5 0) "divide by zero")
+(check (remainder 5 2) 1)
+(check (remainder 2 2) 0)
+(check (remainder -5 2) -1)
+(check (remainder 5 -2) 1)
+(check (remainder -9223372036854775808 1) 0)
+(check (remainder -9223372036854775808 -1) 0)
+(check (remainder 9223372036854775807 -1) 0)
+(check (remainder -9223372036854775807 -1) 0)
+(check (remainder -9223372036854775808 9223372036854775807) -1)
+(check (remainder 9223372036854775807 -9223372036854775808) 9223372036854775807)
+(check-arg-fail (remainder -5) arity)
+(check-arg-fail (remainder 5 'apple) not-integer)
+(check-arg-fail (remainder 5 0) "divide by zero")
+
(check (modulo 5 2) 1)
(check (modulo 2 2) 0)
-(check (modulo -5 2) -1)
-(check (modulo 5 -2) 1)
+(check (modulo -5 2) 1)
+(check (modulo 5 -2) -1)
(check (modulo -9223372036854775808 1) 0)
(check (modulo -9223372036854775808 -1) 0)
(check (modulo 9223372036854775807 -1) 0)
(check (modulo -9223372036854775807 -1) 0)
-(check (modulo -9223372036854775808 9223372036854775807) -1)
-(check (modulo 9223372036854775807 -9223372036854775808) 9223372036854775807)
+(check (modulo -9223372036854775808 9223372036854775807) 9223372036854775806)
+(check (modulo 9223372036854775807 -9223372036854775808) -1)
(check-arg-fail (modulo -5) arity)
(check-arg-fail (modulo 5 'apple) not-integer)
(check-arg-fail (modulo 5 0) "divide by zero")
--- a/zuo-doc/fake-zuo.rkt
+++ b/zuo-doc/fake-zuo.rkt
@@ -91,6 +91,7 @@
*
quotient
modulo
+ remainder
<
<=
=
--- a/zuo-doc/lang-zuo-kernel.scrbl
+++ b/zuo-doc/lang-zuo-kernel.scrbl
@@ -73,7 +73,7 @@
pair? null? list? cons car cdr list append reverse length
list-ref list-set
- integer? + - * quotient modulo < <= = >= >
+ integer? + - * quotient remainder < <= = >= >
bitwise-and bitwise-ior bitwise-xor bitwise-not
string? string-length string-ref string-u32-ref substring string
--- a/zuo-doc/lang-zuo.scrbl
+++ b/zuo-doc/lang-zuo.scrbl
@@ -322,6 +322,7 @@
[(- [z integer?] [w integer?] ...+) integer?])]
@defproc[(* [z integer?] ...) integer?]
@defproc[(quotient [n integer?] [m integer?]) integer?]
+@defproc[(remainder [n integer?] [m integer?]) integer?]
@defproc[(modulo [n integer?] [m integer?]) integer?]
@defproc[(= [z integer?] [w integer?]) boolean?]
@defproc[(< [x integer?] [y integer?]) boolean?]
@@ -334,7 +335,7 @@
@defproc[(bitwise-not [n integer?]) integer?]
)]{
-Analogous to @realracket*[+ - * quotient modulo = < <= > >=
+Analogous to @realracket*[+ - * quotient remainder modulo = < <= > >=
bitwise-ior bitwise-and bitwise-xor bitwise-not] from
@racketmodname[racket], but on Zuo integers and sometimes constrained
to two arguments.}
--- a/zuo.c
+++ b/zuo.c
@@ -2783,14 +2783,14 @@
return zuo_integer(ZUO_INT_I(n) / m_i);
}
-static zuo_t *zuo_modulo(zuo_t *n, zuo_t *m) {
- const char *who = "modulo";
+static zuo_t *zuo_remainder(zuo_t *n, zuo_t *m) {
+ const char *who = "remainder";
zuo_int_t m_i;
check_ints(n, m, who);
m_i = ZUO_UINT_I(m);
if (m_i == 0) zuo_fail1w(who, "divide by zero", m);
if (m_i == -1) {
- /* avoid potential overflow a the minimum integer */
+ /* avoid potential overflow at the minimum integer */
return zuo_integer(0);
}
return zuo_integer(ZUO_INT_I(n) % m_i);
@@ -7156,7 +7156,7 @@
ZUO_TOP_ENV_SET_PRIMITIVEN("-", zuo_subtract, -2);
ZUO_TOP_ENV_SET_PRIMITIVEN("*", zuo_multiply, -1);
ZUO_TOP_ENV_SET_PRIMITIVE2("quotient", zuo_quotient);
- ZUO_TOP_ENV_SET_PRIMITIVE2("modulo", zuo_modulo);
+ ZUO_TOP_ENV_SET_PRIMITIVE2("remainder", zuo_remainder);
ZUO_TOP_ENV_SET_PRIMITIVE2("<", zuo_lt);
ZUO_TOP_ENV_SET_PRIMITIVE2("<=", zuo_le);
ZUO_TOP_ENV_SET_PRIMITIVE2("=", zuo_eql);