;;; SRFI-143 — Fixnums ;;; ;;; Author: John Cowan ;;; ;;; Copyright (c) 2016 John Cowan. All Rights Reserved. ;;; ;;; Permission is hereby granted, free of charge, to any person obtaining a ;;; copy of this software and associated documentation files (the "Software"), ;;; to deal in the Software without restriction, including without limitation ;;; the rights to use, copy, modify, merge, publish, distribute, sublicense, ;;; and/or sell copies of the Software, and to permit persons to whom the ;;; Software is furnished to do so, subject to the following conditions: ;;; ;;; The above copyright notice and this permission notice shall be included in ;;; all copies or substantial portions of the Software. ;;; ;;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ;;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ;;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ;;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ;;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ;;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ;;; DEALINGS IN THE SOFTWARE. (define fxquotient fx/) (define (fxzero? i) (fx=? i 0)) (define (fxpositive? i) (fx>? i 0)) (define (fxnegative? i) (fx y 0) (values (+ q 1) (- x (* (+ q 1) y)))) (else (values (- q 1) (- x (* (- q 1) y)))))))) ;;; Bitwise functions cloned from SRFI 151, fixnum version (define fxbit-count (letrec ((logcnt (lambda (n tot) (if (fxzero? n) tot (logcnt (fxquotient n 16) (fx+ (vector-ref '#(0 1 1 2 1 2 2 3 1 2 2 3 2 3 3 4) (fxremainder n 16)) tot)))))) (lambda (n) (cond ((fxnegative? n) (logcnt (fxnot n) 0)) ((fxpositive? n) (logcnt n 0)) (else 0))))) ;; Helper function (define (mask start end) (fxnot (fxarithmetic-shift-left -1 (fx- end start)))) (define (fxif mask n0 n1) (fxior (fxand mask n0) (fxand (fxnot mask) n1))) (define (fxbit-set? index n) (bit->boolean n index)) (define (fxcopy-bit index to bool) (if bool (fxior to (fxarithmetic-shift-left 1 index)) (fxand to (fxnot (fxarithmetic-shift-left 1 index))))) (define (fxfirst-set-bit i) (fx- (fxbit-count (fxxor i (fx- i 1))) 1)) (define (fxbit-field n start end) (fxand (mask start end) (fxarithmetic-shift n (fxneg start)))) (define (fxbit-field-rotate n count start end) (define width (fx- end start)) (set! count (modulo count width)) (let ((mask (fxnot (fxarithmetic-shift -1 width)))) (define zn (fxand mask (fxarithmetic-shift n (fxneg start)))) (fxior (fxarithmetic-shift (fxior (fxand mask (fxarithmetic-shift zn count)) (fxarithmetic-shift zn (fx- count width))) start) (fxand (fxnot (fxarithmetic-shift mask start)) n)))) (define (fxreverse k n) (do ((m (if (negative? n) (fxnot n) n) (fxarithmetic-shift-right m 1)) (k (fx+ -1 k) (fx+ -1 k)) (rvs 0 (fxior (fxarithmetic-shift-left rvs 1) (fxand 1 m)))) ((fxnegative? k) (if (fxnegative? n) (fxnot rvs) rvs)))) (define (fxbit-field-reverse n start end) (define width (fx- end start)) (let ((mask (fxnot (fxarithmetic-shift-left -1 width)))) (define zn (fxand mask (fxarithmetic-shift-right n start))) (fxior (fxarithmetic-shift-left (fxreverse width zn) start) (fxand (fxnot (fxarithmetic-shift-left mask start)) n))))