From e4da3edeec0384b0bae93a9721fa85e0b42a66c3 Mon Sep 17 00:00:00 2001 From: Ryan Culpepper Date: Sun, 16 Dec 2012 18:52:24 -0500 Subject: [PATCH] fix popcount bug in bit-vector --- collects/data/bit-vector.rkt | 2 +- collects/data/private/count-bits-in-fixnum.rkt | 4 ++-- collects/tests/data/bit-vector.rkt | 14 +++++++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/collects/data/bit-vector.rkt b/collects/data/bit-vector.rkt index fc6812095e..a0cd7c8226 100644 --- a/collects/data/bit-vector.rkt +++ b/collects/data/bit-vector.rkt @@ -21,7 +21,7 @@ (define (make-bit-vector size [fill #f]) (define-values (q r) (quotient/remainder size bits-in-a-word)) - (define word-size (add1 q)) + (define word-size (+ q (if (zero? r) 0 1))) (define words (make-fxvector word-size (if fill largest-fixnum 0))) (when (and fill (not (zero? r))) (fxvector-set! words q (- (expt 2 r) 1))) diff --git a/collects/data/private/count-bits-in-fixnum.rkt b/collects/data/private/count-bits-in-fixnum.rkt index d2b804996a..cec194422a 100644 --- a/collects/data/private/count-bits-in-fixnum.rkt +++ b/collects/data/private/count-bits-in-fixnum.rkt @@ -1,6 +1,6 @@ -#lang racket +#lang racket/base (require racket/unsafe/ops - (for-syntax racket/fixnum racket/vector)) + (for-syntax racket/base racket/fixnum racket/vector)) (provide fxpopcount) ;; Count set bits for 30 bit number in 5 steps. ;; for 62 bit number in 6. diff --git a/collects/tests/data/bit-vector.rkt b/collects/tests/data/bit-vector.rkt index 4a8528c6f4..cd70a85a8c 100644 --- a/collects/tests/data/bit-vector.rkt +++ b/collects/tests/data/bit-vector.rkt @@ -100,13 +100,17 @@ (test-case "bit-vector-popcount" (let () - (define (test) + (define (test len) (define fill (odd? (random 2))) - (define bv (make-bit-vector 1000 fill)) - (define ns (list->set (build-list 100 (λ (_) (random 1000))))) + (define bv (make-bit-vector len fill)) + (define ns (list->set (build-list 100 (λ (_) (random len))))) (for ([n (in-set ns)]) (bit-vector-set! bv n (not fill))) (define count - (if fill (- 1000 (set-count ns)) (set-count ns))) + (if fill (- len (set-count ns)) (set-count ns))) (check-equal? (bit-vector-popcount bv) count)) (for ([i (in-range 100)]) - (test)))) + (test 1000)) + ;; test multiples of possible word sizes + (for ([ws (in-list '(8 30 62))]) + (for ([i (in-range 10)]) + (test (* ws 10))))))