1 ;------------------------------------------------------------------------------
11 (define fixnums (make-vector (+ (- max-fix min-fix) 1)))
15 (vector-ref fixnums (- n min-fix))))
17 (let loop ((n min-fix))
20 (vector-set! fixnums (- n min-fix) (make-num (modulo n #x10000) #f))
23 (let loop ((n min-fix))
28 (if (< n 0) (fixnum -1) (fixnum 0)))
31 (define minus1 (fixnum -1))
32 (define zero (fixnum 0))
33 (define one (fixnum 1))
38 (if (or (< lo16 0) (> lo16 #xffff))
39 (error "lo16 out of range"))
44 (cond ((and (eq? (num-shr16 result) zero)
45 (<= (num-lo16 result) max-fix))
46 (if (not (eq? result (fixnum (num-lo16 result))))
47 (pp (list name "nonneg number is not normalized" (dec result) (num-lo16 result)))))
48 ((and (eq? (num-shr16 result) minus1)
49 (>= (num-lo16 result) (+ #x10000 min-fix)))
50 (if (not (eq? result (fixnum (- (num-lo16 result) #x10000))))
51 (pp (list name "neg number is not normalized" (dec result) (- (num-lo16 result) #x10000))))))))
53 (define check-normalized
56 (let ((result (apply f args)))
57 (check-norm name result)
62 (if (eq? x zero) minus1 zero)))
66 (check-norm 'sign?.x x)
67 (or (eq? x zero) (eq? x minus1))))
71 (check-norm 'neg?.x x)
72 (cond ((eq? x zero) #f)
74 (else (neg? (num-shr16 x))))))
92 (let loop ((x x) (y y) (c 0))
104 (let ((x-lo16 (num-lo16 x))
105 (y-lo16 (num-lo16 y)))
106 (cond ((= x-lo16 y-lo16) c)
107 ((< x-lo16 y-lo16) -1)
110 (define int-len-nonneg
112 (check-norm 'int-len-nonneg.x x)
113 (let loop1 ((x x) (n 0))
114 (let ((shr16 (num-shr16 x)))
116 (let loop2 ((lo16 (num-lo16 x)) (n n))
119 (loop2 (arithmetic-shift lo16 -1)
121 (loop1 shr16 (+ 16 n)))))))
124 (check-normalized 'shift-left
126 (check-norm 'shift-left.x x)
127 (if (< n 0) (error "xxxxxxxxxxx"))
130 (let loop1 ((x x) (n n))
131 (if (= (bitwise-and n 15) 0)
132 (let loop2 ((x x) (n n))
135 (loop2 (make-num #x0000 x)
141 (check-normalized 'shl
143 (check-norm 'shl.x x)
144 (let loop ((x x) (minus-c zero) (r #f))
145 (cond ((eq? x minus-c)
148 (let ((z (+ (* 2 (num-lo16 x)) (if (eq? minus-c zero) 0 1))))
150 (if (>= z #x10000) minus1 zero)
151 (make-num (modulo z #x10000) r)))))))))
154 (check-normalized 'shr
156 (check-norm 'shr.x x)
157 (let loop ((x x) (r #f))
163 (let ((z (+ (arithmetic-shift (num-lo16 x) -1)
164 (if (even? (num-lo16 (num-shr16 x))) #x0000 #x8000))))
166 (make-num z r)))))))))
169 (check-normalized 'add
171 (check-norm 'add.x x)
172 (check-norm 'add.y y)
173 (let loop ((x x) (y y) (minus-c zero) (r #f))
174 (cond ((eq? x minus-c)
179 (let ((z (+ (num-lo16 x) (num-lo16 y) (if (eq? minus-c zero) 0 1))))
182 (if (>= z #x10000) minus1 zero)
183 (make-num (modulo z #x10000) r)))))))))
186 (check-normalized 'sub
188 (check-norm 'sub.x x)
189 (check-norm 'sub.y y)
190 (let loop ((x x) (y y) (minus-c minus1) (r #f))
191 (cond ((and (eq? x minus-c) (sign? y))
193 ((eq? y (invert minus-c))
196 (let ((z (+ (num-lo16 x) (- #xffff (num-lo16 y)) (if (eq? minus-c zero) 0 1))))
199 (if (>= z #x10000) minus1 zero)
200 (make-num (modulo z #x10000) r)))))))))
203 (check-normalized 'scale
205 (check-norm 'scale.x x)
212 (let loop ((x x) (carry 0) (r #f))
214 (norm r (build-nonneg carry)))
216 (norm r (build-neg (+ (modulo (- n16) #x10000) carry))))
218 (let ((m (+ (* n16 (num-lo16 x)) carry)))
220 (arithmetic-shift m -16)
221 (make-num (modulo m #x10000) r)))))))))))
224 (check-normalized 'neg
226 (check-norm 'neg.x x)
230 (check-normalized 'build-nonneg
232 (if (<= lo16 max-fix) (fixnum lo16) (make-num lo16 zero)))))
235 (check-normalized 'build-neg
237 (if (>= lo16 (+ #x10000 min-fix)) (fixnum (- lo16 #x10000)) (make-num lo16 minus1)))))
240 (check-normalized 'mul
242 (check-norm 'mul.x x)
243 (check-norm 'mul.y y)
245 (neg (mulnonneg (neg x) y))
249 (lambda (x y) ; x is nonnegative
250 (check-norm 'mulnonneg.x x)
251 (check-norm 'mulnonneg.y y)
252 (let loop ((x x) (s zero) (r #f))
255 (let ((a (add s (scale (num-lo16 x) y))))
258 (make-num (num-lo16 a) r)))))))
261 (check-normalized 'rem
263 (check-norm 'rem.x x)
264 (check-norm 'rem.y y)
267 (neg (cdr (divnonneg (neg x) (neg y))))
268 (neg (cdr (divnonneg (neg x) y))))
270 (cdr (divnonneg x (neg y)))
271 (cdr (divnonneg x y)))))))
274 (check-normalized 'div
276 (check-norm 'div.x x)
277 (check-norm 'div.y y)
280 (car (divnonneg (neg x) (neg y)))
281 (neg (car (divnonneg (neg x) y))))
283 (neg (car (divnonneg x (neg y))))
284 (car (divnonneg x y)))))))
288 (let ((x (decode x)) (y (decode y)))
289 (let ((lx (integer-length x))
290 (ly (integer-length y)))
292 (let loop ((i b) (a x) (b (arithmetic-shift y b)) (r 0))
293 ; (pp (list i a b r))
295 (cons (encode r) (encode a))
300 (arithmetic-shift b -1)
304 (arithmetic-shift b -1)
309 (check-norm 'divnonneg.x x)
310 (check-norm 'divnonneg.y y)
311 (let ((lx (int-len-nonneg x))
312 (ly (int-len-nonneg y)))
313 (if (not (and (= lx (integer-length (decode x)))
314 (= ly (integer-length (decode y)))))
319 (let loop ((i b) (a x) (b (shift-left y b)) (r zero))
320 ; (pp (list i (decode a) (decode b) (decode r)))
334 (check-normalized 'norm2
337 (let ((lo16 (num-lo16 r))
338 (newr (num-shr16 r)))
340 (if (cond ((eq? shr16 zero) (= lo16 #x0000))
341 ((eq? shr16 minus1) (= lo16 #xffff))
345 (num-shr16-set! r shr16)
350 (check-normalized 'norm
352 (check-norm 'norm.shr16 shr16)
354 (let ((lo16 (num-lo16 r))
355 (newr (num-shr16 r)))
356 (cond ((eq? shr16 zero)
357 (cond ((<= lo16 max-fix)
358 (norm newr (fixnum lo16)))
360 (num-shr16-set! r shr16)
363 (cond ((>= lo16 (+ #x10000 min-fix))
364 (norm newr (fixnum (- lo16 #x10000))))
366 (num-shr16-set! r shr16)
369 (num-shr16-set! r shr16)
373 (define #%list->string
375 (list->string (map integer->char (map decode lst)))))
382 (define #%quotient div)
383 (define #%remainder rem)
385 (define #%number->string
389 (#%cons (make-num 45 zero) (#%number->string-aux (#%neg n) '()))
390 (#%number->string-aux n '())))))
392 (define #%number->string-aux
394 (let ((rest (#%cons (#%+ (make-num 48 zero) (#%remainder n (make-num 10 zero))) lst)))
395 (if (#%< n (make-num 10 zero))
397 (#%number->string-aux (#%quotient n (make-num 10 zero)) rest)))))
399 ;------------------------------------------------------------------------------
403 (list (- (expt 2 (+ i -1)) 3)
404 (- (expt 2 (+ i -1)) 2)
405 (- (expt 2 (+ i -1)) 1)
407 (+ (expt 2 (+ i -1)) 1)
408 (+ (expt 2 (+ i -1)) 2)
409 (+ (expt 2 (+ i -1)) 3)
411 (- (expt 2 (+ i 0)) 3)
412 (- (expt 2 (+ i 0)) 2)
413 (- (expt 2 (+ i 0)) 1)
415 (+ (expt 2 (+ i 0)) 1)
416 (+ (expt 2 (+ i 0)) 2)
417 (+ (expt 2 (+ i 0)) 3)
419 (- (expt 2 (+ i 1)) 3)
420 (- (expt 2 (+ i 1)) 2)
421 (- (expt 2 (+ i 1)) 1)
423 (+ (expt 2 (+ i 1)) 1)
424 (+ (expt 2 (+ i 1)) 2)
425 (+ (expt 2 (+ i 1)) 3)
429 (append (fn (* 16 1))
434 (append (map - (reverse nums1))
435 (list -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10)
440 (cond ((eq? n zero) '(0))
441 ((eq? n minus1) '(-1))
442 (else (cons (num-lo16 n) (dec (num-shr16 n)))))))
446 (cond ((eq? n zero) 0)
448 (else (+ (* #x10000 (decode (num-shr16 n))) (num-lo16 n))))))
452 (cond ((and (>= n min-fix)
456 (make-num (modulo n #x10000)
457 (encode (arithmetic-shift n -16)))))))
459 ;------------------------------------------------------------------------------
468 (c (cond ((< x y) -1) ((= x y) 0) (else 1))))
469 (if (not (equal? c (cmp a b)))
470 (error "incorrect" x y (dec a) (dec b) c (cmp a b)))))
479 (c (integer-length x)))
480 (if (not (equal? c (int-len-nonneg a)))
481 (error "incorrect" x (dec a) c (int-len-nonneg a))))))
488 (c (encode (arithmetic-shift x 1))))
489 (if (not (equal? (dec c) (dec (shl a))))
490 (error "incorrect" x (dec a) (dec c) (dec (shl a))))))
497 (c (encode (arithmetic-shift x -1))))
498 (if (not (equal? (dec c) (dec (shr a))))
499 (error "incorrect" x (dec a) (dec c) (dec (shr a))))))
509 (c (encode (+ x y))))
510 (if (not (equal? (dec c) (dec (add a b))))
511 (error "incorrect" x y (dec a) (dec b) (dec c) (dec (add a b))))))
522 (c (encode (- x y))))
523 (if (not (equal? (dec c) (dec (sub a b))))
524 (error "incorrect" x y (dec a) (dec b) (dec c) (dec (sub a b))))))
534 (c (encode (* n16 x))))
535 (if (not (equal? (dec c) (dec (scale n16 a))))
536 (error "incorrect" x (dec a) (dec c) (dec (scale n16 a))))))
538 '(0 1 2 3 4 5 6 7 8 9 10 32767 32768 65535))
547 (c (encode (* x y))))
548 (if (not (equal? (dec c) (dec (mul a b))))
549 (error "incorrect" x y (dec a) (dec b) (dec c) (dec (mul a b))))))
561 (c (encode (quotient x y))))
562 (if (not (equal? (dec c) (dec (div a b))))
563 (error "incorrect" x y (dec a) (dec b) (dec c) (dec (div a b)))))))
575 (c (encode (remainder x y))))
576 (if (not (equal? (dec c) (dec (rem a b))))
577 (error "incorrect" x y (dec a) (dec b) (dec c) (dec (rem a b)))))))
586 (mul n (fact (sub n one))))))
588 (define n (time (fact (encode 50))))
589 (pp (time (#%number->string n)))