1 ;;; fixnums.scm --- The R6RS fixnums arithmetic library
3 ;; Copyright (C) 2010, 2011, 2013 Free Software Foundation, Inc.
5 ;; This library is free software; you can redistribute it and/or
6 ;; modify it under the terms of the GNU Lesser General Public
7 ;; License as published by the Free Software Foundation; either
8 ;; version 3 of the License, or (at your option) any later version.
10 ;; This library is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ;; Lesser General Public License for more details.
15 ;; You should have received a copy of the GNU Lesser General Public
16 ;; License along with this library; if not, write to the Free Software
17 ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 (library (rnrs arithmetic fixnums (6))
72 fxarithmetic-shift-left
73 fxarithmetic-shift-right
77 (import (only (guile) ash
93 (rnrs arithmetic bitwise (6))
99 (let ((w (inexact->exact (round (/ (log (+ most-positive-fixnum 1)) (log 2))))))
102 (define (greatest-fixnum) most-positive-fixnum)
103 (define (least-fixnum) most-negative-fixnum)
105 (define (fixnum? obj)
106 (not (= 0 (logand 2 (object-address obj)))))
108 (define-inlinable (inline-fixnum? obj)
109 (not (= 0 (logand 2 (object-address obj)))))
111 (define-syntax assert-fixnum
114 (or (and (inline-fixnum? arg) ...)
115 (raise (make-assertion-violation))))))
117 (define (assert-fixnums args)
118 (or (for-all inline-fixnum? args) (raise (make-assertion-violation))))
120 (define-syntax define-fxop*
129 (assert-fixnums args)
130 (apply op args)))))))
132 ;; All these predicates don't check their arguments for fixnum-ness,
133 ;; as this doesn't seem to be strictly required by R6RS.
141 (define fxzero? zero?)
142 (define fxpositive? positive?)
143 (define fxnegative? negative?)
145 (define fxeven? even?)
147 (define-fxop* fxmax max)
148 (define-fxop* fxmin min)
150 (define (fx+ fx1 fx2)
151 (assert-fixnum fx1 fx2)
152 (let ((r (+ fx1 fx2)))
153 (or (inline-fixnum? r)
154 (raise (make-implementation-restriction-violation)))
157 (define (fx* fx1 fx2)
158 (assert-fixnum fx1 fx2)
159 (let ((r (* fx1 fx2)))
160 (or (inline-fixnum? r)
161 (raise (make-implementation-restriction-violation)))
164 (define* (fx- fx1 #:optional fx2)
169 (let ((r (- fx1 fx2)))
170 (or (inline-fixnum? r) (raise (make-assertion-violation)))
173 (or (inline-fixnum? r) (raise (make-assertion-violation)))
176 (define (fxdiv fx1 fx2)
177 (assert-fixnum fx1 fx2)
180 (define (fxmod fx1 fx2)
181 (assert-fixnum fx1 fx2)
184 (define (fxdiv-and-mod fx1 fx2)
185 (assert-fixnum fx1 fx2)
186 (div-and-mod fx1 fx2))
188 (define (fxdiv0 fx1 fx2)
189 (assert-fixnum fx1 fx2)
192 (define (fxmod0 fx1 fx2)
193 (assert-fixnum fx1 fx2)
196 (define (fxdiv0-and-mod0 fx1 fx2)
197 (assert-fixnum fx1 fx2)
198 (div0-and-mod0 fx1 fx2))
200 (define (fx+/carry fx1 fx2 fx3)
201 (assert-fixnum fx1 fx2 fx3)
202 (let* ((s (+ fx1 fx2 fx3))
203 (s0 (mod0 s (expt 2 (fixnum-width))))
204 (s1 (div0 s (expt 2 (fixnum-width)))))
207 (define (fx-/carry fx1 fx2 fx3)
208 (assert-fixnum fx1 fx2 fx3)
209 (let* ((d (- fx1 fx2 fx3))
210 (d0 (mod0 d (expt 2 (fixnum-width))))
211 (d1 (div0 d (expt 2 (fixnum-width)))))
214 (define (fx*/carry fx1 fx2 fx3)
215 (assert-fixnum fx1 fx2 fx3)
216 (let* ((s (+ (* fx1 fx2) fx3))
217 (s0 (mod0 s (expt 2 (fixnum-width))))
218 (s1 (div0 s (expt 2 (fixnum-width)))))
221 (define (fxnot fx) (assert-fixnum fx) (lognot fx))
222 (define-fxop* fxand logand)
223 (define-fxop* fxior logior)
224 (define-fxop* fxxor logxor)
226 (define (fxif fx1 fx2 fx3)
227 (assert-fixnum fx1 fx2 fx3)
228 (bitwise-if fx1 fx2 fx3))
230 (define (fxbit-count fx)
233 (bitwise-not (logcount fx))
236 (define (fxlength fx) (assert-fixnum fx) (bitwise-length fx))
237 (define (fxfirst-bit-set fx) (assert-fixnum fx) (bitwise-first-bit-set fx))
238 (define (fxbit-set? fx1 fx2) (assert-fixnum fx1 fx2) (logbit? fx2 fx1))
240 (define (fxcopy-bit fx1 fx2 fx3)
241 (assert-fixnum fx1 fx2 fx3)
242 (bitwise-copy-bit fx1 fx2 fx3))
244 (define (fxbit-field fx1 fx2 fx3)
245 (assert-fixnum fx1 fx2 fx3)
246 (bitwise-bit-field fx1 fx2 fx3))
248 (define (fxcopy-bit-field fx1 fx2 fx3 fx4)
249 (assert-fixnum fx1 fx2 fx3 fx4)
250 (bitwise-copy-bit-field fx1 fx2 fx3 fx4))
252 (define (fxarithmetic-shift fx1 fx2) (assert-fixnum fx1 fx2) (ash fx1 fx2))
253 (define fxarithmetic-shift-left fxarithmetic-shift)
255 (define (fxarithmetic-shift-right fx1 fx2)
256 (assert-fixnum fx1 fx2) (ash fx1 (- fx2)))
258 (define (fxrotate-bit-field fx1 fx2 fx3 fx4)
259 (assert-fixnum fx1 fx2 fx3 fx4)
260 (bitwise-rotate-bit-field fx1 fx2 fx3 fx4))
262 (define (fxreverse-bit-field fx1 fx2 fx3)
263 (assert-fixnum fx1 fx2 fx3)
264 (bitwise-reverse-bit-field fx1 fx2 fx3))