Fix bug with equal? on small bit-vectors.
This commit is contained in:
parent
c389bfab3b
commit
9de70551dc
|
@ -87,6 +87,36 @@
|
|||
(eq-hash-code (bit-vector #t #f #t #f #t)))
|
||||
#f))
|
||||
|
||||
(test-case "bit-vector, equal-proc (via equal?)"
|
||||
;; Zero length bit-vectors are equal...
|
||||
(equal? (make-bit-vector 0 #t)
|
||||
(make-bit-vector 0 #t))
|
||||
;; ...even if fill value differed, because it's N/A
|
||||
(equal? (make-bit-vector 0 #t)
|
||||
(make-bit-vector 0 #f))
|
||||
;; Check a range of bit lengths spanning a few 8-bit bytes:
|
||||
(for ([len (in-range 1 24)])
|
||||
(check-equal?
|
||||
(equal? (make-bit-vector len #t)
|
||||
(make-bit-vector len #t))
|
||||
#t)
|
||||
(check-equal?
|
||||
(equal? (make-bit-vector len #t)
|
||||
(make-bit-vector len #f))
|
||||
#f))
|
||||
;; Attempt to flush out potential bugs wrt to unused bits
|
||||
;; that might be set by a "fill" value (implementation
|
||||
;; detail we don't know for sure here), but should
|
||||
;; definitely be ignored by equal?.
|
||||
(let ([x (make-bit-vector 1 #t)] ;#t fill value
|
||||
[y (make-bit-vector 1 #f)]) ;#f fill value
|
||||
;; Set the only bit to #t in both
|
||||
(bit-vector-set! x 0 #t)
|
||||
(bit-vector-set! y 0 #t)
|
||||
;; Should be equal, regardless of different fill values
|
||||
;; in make-bit-vector:
|
||||
(check-equal? (equal? x y) #t)))
|
||||
|
||||
(test-case "for/bit-vector"
|
||||
(check-equal? (for/bit-vector ([i 5]) (odd? i))
|
||||
(bit-vector #f #t #f #t #f))
|
||||
|
|
|
@ -148,8 +148,7 @@
|
|||
bit-vector-copy
|
||||
#f)
|
||||
|
||||
; A bit vector is represented as a vector of words.
|
||||
; Each word contains 30 or 62 bits depending on the size of a fixnum.
|
||||
;; A bit vector is represented as bytes.
|
||||
(serializable-struct bit-vector (words size)
|
||||
; words is the bytes of words
|
||||
; size is the number of bits in bitvector
|
||||
|
@ -187,11 +186,22 @@
|
|||
[nx (bit-vector-size x)]
|
||||
[ny (bit-vector-size y)])
|
||||
(and (= nx ny)
|
||||
(for/and ([index (in-range (- (bytes-length vx) 1))])
|
||||
(eq? (bytes-ref vx index)
|
||||
(bytes-ref vy index)))
|
||||
; TODO: check last word
|
||||
)))
|
||||
(or (zero? nx) ;zero-length bit-vectors are equal
|
||||
(let ([last-index (sub1 (bytes-length vx))])
|
||||
(and
|
||||
;; Check all but last byte.
|
||||
;; These use all bits, therefore simple eq?.
|
||||
(for/and ([index (in-range (sub1 last-index))])
|
||||
(eq? (bytes-ref vx index)
|
||||
(bytes-ref vy index)))
|
||||
;; Check the used bits of the last byte.
|
||||
(let ([used-bits (min 8 (remainder nx 256))])
|
||||
(eq? (bitwise-bit-field (bytes-ref vx last-index)
|
||||
0
|
||||
used-bits)
|
||||
(bitwise-bit-field (bytes-ref vy last-index)
|
||||
0
|
||||
used-bits)))))))))
|
||||
(define (hash-code x hc)
|
||||
(let ([v (bit-vector-words x)]
|
||||
[n (bit-vector-size x)])
|
||||
|
|
Loading…
Reference in New Issue
Block a user