added bit-vector <-> {string,list} operations
This commit is contained in:
parent
e4da3edeec
commit
810d07d8d5
|
@ -27,24 +27,27 @@
|
||||||
(fxvector-set! words q (- (expt 2 r) 1)))
|
(fxvector-set! words q (- (expt 2 r) 1)))
|
||||||
(bit-vector words size word-size))
|
(bit-vector words size word-size))
|
||||||
|
|
||||||
(define (bit-vector* . init-bits)
|
(define bit-vector*
|
||||||
(define bv (make-bit-vector (length init-bits)))
|
(let ([bit-vector
|
||||||
(for ([i (in-naturals)]
|
(lambda init-bits
|
||||||
[b (in-list init-bits)])
|
(list->bit-vector init-bits))])
|
||||||
(bit-vector-set! bv i b))
|
bit-vector))
|
||||||
bv)
|
|
||||||
|
|
||||||
(define (bit-vector-ref bv n
|
(define not-given (gensym))
|
||||||
[default (bad-index-error 'bit-vector-ref n)])
|
|
||||||
|
(define (bit-vector-ref bv n [default not-given])
|
||||||
(unless (exact-nonnegative-integer? n)
|
(unless (exact-nonnegative-integer? n)
|
||||||
(raise-type-error 'bit-vector-ref "exact nonnegative integer" n))
|
(raise-argument-error 'bit-vector-ref "exact-nonnegative-integer?" n))
|
||||||
(cond
|
(cond [(< n (bit-vector-size bv))
|
||||||
[(>= n (bit-vector-size bv))
|
(unsafe-bit-vector-ref bv n)]
|
||||||
(if (procedure? default)
|
[else
|
||||||
(default)
|
(cond [(eq? default not-given)
|
||||||
default)]
|
(raise-range-error 'bit-vector-ref
|
||||||
[else
|
"bit-vector"
|
||||||
(unsafe-bit-vector-ref bv n)]))
|
"" n bv 0 (sub1 (bit-vector-size bv)))]
|
||||||
|
[(procedure? default)
|
||||||
|
(default)]
|
||||||
|
[else default])]))
|
||||||
|
|
||||||
(define (unsafe-bit-vector-ref bv n)
|
(define (unsafe-bit-vector-ref bv n)
|
||||||
(define-values (wi bi) (quotient/remainder n bits-in-a-word))
|
(define-values (wi bi) (quotient/remainder n bits-in-a-word))
|
||||||
|
@ -97,6 +100,37 @@
|
||||||
(for/sum ([fx (in-fxvector (bit-vector-words bv))])
|
(for/sum ([fx (in-fxvector (bit-vector-words bv))])
|
||||||
(fxpopcount fx)))
|
(fxpopcount fx)))
|
||||||
|
|
||||||
|
(define (bit-vector->list bv)
|
||||||
|
(define len (bit-vector-size bv))
|
||||||
|
(let loop ([i 0])
|
||||||
|
(cond [(< i len)
|
||||||
|
(cons (unsafe-bit-vector-ref bv i)
|
||||||
|
(loop (add1 i)))]
|
||||||
|
[else null])))
|
||||||
|
|
||||||
|
(define (list->bit-vector init-bits)
|
||||||
|
(define len (length init-bits))
|
||||||
|
(define bv (make-bit-vector len))
|
||||||
|
(for ([i (in-range len)]
|
||||||
|
[b (in-list init-bits)])
|
||||||
|
(bit-vector-set! bv i b))
|
||||||
|
bv)
|
||||||
|
|
||||||
|
(define (bit-vector->string bv)
|
||||||
|
(let* ([l (bit-vector-size bv)]
|
||||||
|
[s (make-string l)])
|
||||||
|
(for ([i (in-range l)])
|
||||||
|
(string-set! s i (if (unsafe-bit-vector-ref bv i) #\1 #\0)))
|
||||||
|
s))
|
||||||
|
|
||||||
|
(define (string->bit-vector s)
|
||||||
|
(let* ([bv (make-bit-vector (string-length s) #f)])
|
||||||
|
(for ([i (in-range (string-length s))])
|
||||||
|
(when (eqv? (string-ref s i) #\1)
|
||||||
|
(bit-vector-set! bv i #t)))
|
||||||
|
bv))
|
||||||
|
|
||||||
|
|
||||||
(define-vector-wraps "bit-vector"
|
(define-vector-wraps "bit-vector"
|
||||||
bit-vector? bit-vector-length bit-vector-ref bit-vector-set! make-bit-vector
|
bit-vector? bit-vector-length bit-vector-ref bit-vector-set! make-bit-vector
|
||||||
unsafe-bit-vector-ref bit-vector-set! bit-vector-length
|
unsafe-bit-vector-ref bit-vector-set! bit-vector-length
|
||||||
|
@ -171,6 +205,14 @@
|
||||||
(-> bit-vector? any)]
|
(-> bit-vector? any)]
|
||||||
(rename bit-vector-copy*
|
(rename bit-vector-copy*
|
||||||
bit-vector-copy
|
bit-vector-copy
|
||||||
(-> bit-vector? bit-vector?)))
|
(-> bit-vector? bit-vector?))
|
||||||
|
[bit-vector->list
|
||||||
|
(-> bit-vector? (listof boolean?))]
|
||||||
|
[list->bit-vector
|
||||||
|
(-> (listof boolean?) bit-vector?)]
|
||||||
|
[bit-vector->string
|
||||||
|
(-> bit-vector? string?)]
|
||||||
|
[string->bit-vector
|
||||||
|
(-> (and/c string? #rx"^[01]*$") bit-vector?)])
|
||||||
|
|
||||||
(provide in-bit-vector for/bit-vector for*/bit-vector)
|
(provide in-bit-vector for/bit-vector for*/bit-vector)
|
||||||
|
|
|
@ -32,17 +32,19 @@ Creates a new bit-vector of size @racket[size]. All elements
|
||||||
are initialized to @racket[fill].
|
are initialized to @racket[fill].
|
||||||
|
|
||||||
@examples[#:eval the-eval
|
@examples[#:eval the-eval
|
||||||
(define bv (make-bit-vector 3))
|
(bit-vector-ref (make-bit-vector 3) 2)
|
||||||
(bit-vector-ref bv 1)]
|
(bit-vector-ref (make-bit-vector 3 #t) 2)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(bit-vector [elem boolean?] ...)
|
@defproc[(bit-vector [elem boolean?] ...)
|
||||||
bit-vector?]{
|
bit-vector?]{
|
||||||
|
|
||||||
Creates a new bit-vector containing each @racket[elem] in order.
|
Creates a new bit-vector containing each @racket[elem] in order.
|
||||||
|
|
||||||
@examples[#:eval the-eval
|
@examples[#:eval the-eval
|
||||||
(define bv (bit-vector #f #t #f))
|
(bit-vector-ref (bit-vector #f #t #f) 1)
|
||||||
(bit-vector-ref bv 1)]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(bit-vector? [v any/c]) boolean?]{
|
@defproc[(bit-vector? [v any/c]) boolean?]{
|
||||||
|
@ -56,8 +58,13 @@ Returns @racket[#t] if @racket[v] is a bit-vector, @racket[#f] otherwise.
|
||||||
any/c]{
|
any/c]{
|
||||||
|
|
||||||
Returns the element at index @racket[index], if @racket[index] is less
|
Returns the element at index @racket[index], if @racket[index] is less
|
||||||
than @racket[(bit-vector-length gv)]. Otherwise, @racket[default] is
|
than @racket[(bit-vector-length bv)]. Otherwise, @racket[default] is
|
||||||
invoked if it is a procedure, returned otherwise.
|
invoked if it is a procedure, returned otherwise.
|
||||||
|
|
||||||
|
@examples[#:eval the-eval
|
||||||
|
(bit-vector-ref (bit-vector #f #t) 1)
|
||||||
|
(bit-vector-ref (bit-vector #f #t) 5 'not-there)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(bit-vector-set!
|
@defproc[(bit-vector-set!
|
||||||
|
@ -68,9 +75,13 @@ invoked if it is a procedure, returned otherwise.
|
||||||
void?]{
|
void?]{
|
||||||
|
|
||||||
Sets the value at index @racket[index] to be @racket[value].
|
Sets the value at index @racket[index] to be @racket[value].
|
||||||
|
|
||||||
@examples[#:eval the-eval
|
@examples[#:eval the-eval
|
||||||
(define bv (bit-vector #f #t #f))
|
(define bv (bit-vector #f #t))
|
||||||
(bit-vector-ref bv 1)]
|
(bit-vector-ref bv 0)
|
||||||
|
(bit-vector-set! bv 0 #t)
|
||||||
|
(bit-vector-ref bv 0)
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@defproc[(bit-vector-length [bv bit-vector?])
|
@defproc[(bit-vector-length [bv bit-vector?])
|
||||||
|
@ -83,6 +94,7 @@ Returns the number of items in the bit-vector @racket[bv].
|
||||||
exact-nonnegative-integer?]{
|
exact-nonnegative-integer?]{
|
||||||
|
|
||||||
Returns the number of set bits in the bit-vector @racket[bv].
|
Returns the number of set bits in the bit-vector @racket[bv].
|
||||||
|
|
||||||
@examples[#:eval the-eval
|
@examples[#:eval the-eval
|
||||||
(bit-vector-popcount (bit-vector #f #t #t))]
|
(bit-vector-popcount (bit-vector #f #t #t))]
|
||||||
}
|
}
|
||||||
|
@ -103,10 +115,9 @@ to @racket[end] (exclusive).
|
||||||
Returns a sequence whose elements are the elements of the bit-vector
|
Returns a sequence whose elements are the elements of the bit-vector
|
||||||
@racket[bv]. Mutation of @racket[bv] while the sequence is running
|
@racket[bv]. Mutation of @racket[bv] while the sequence is running
|
||||||
changes the elements produced by the sequence. To obtain a sequence
|
changes the elements produced by the sequence. To obtain a sequence
|
||||||
from a snapshot of @racket[gv], use @racket[(in-vector
|
from a snapshot of @racket[bv], use @racket[(in-bit-vector
|
||||||
(bit-vector-copy bv))] instead.
|
(bit-vector-copy bv))] instead.
|
||||||
|
|
||||||
|
|
||||||
@examples[#:eval the-eval
|
@examples[#:eval the-eval
|
||||||
(define bv (bit-vector #f #t #f))
|
(define bv (bit-vector #f #t #f))
|
||||||
(for/list ([x (in-bit-vector bv)]) x)]
|
(for/list ([x (in-bit-vector bv)]) x)]
|
||||||
|
@ -133,11 +144,13 @@ the value of @racket[fill-expr], which defaults to @racket[#f] (i.e.,
|
||||||
the default argument of @racket[make-bit-vector]).
|
the default argument of @racket[make-bit-vector]).
|
||||||
|
|
||||||
@examples[#:eval the-eval
|
@examples[#:eval the-eval
|
||||||
(define (to-list bv) (for/list ([x bv]) x))
|
(bit-vector->list
|
||||||
(to-list (for/bit-vector ([i '(1 2 3)]) (odd? i)))
|
(for/bit-vector ([i '(1 2 3)]) (odd? i)))
|
||||||
(to-list (for/bit-vector #:length 2 ([i '(1 2 3)]) (odd? i)))
|
(bit-vector->list
|
||||||
(to-list (for/bit-vector #:length 4 ([i '(1 2 3)]) (odd? i)))
|
(for/bit-vector #:length 2 ([i '(1 2 3)]) (odd? i)))
|
||||||
(to-list
|
(bit-vector->list
|
||||||
|
(for/bit-vector #:length 4 ([i '(1 2 3)]) (odd? i)))
|
||||||
|
(bit-vector->list
|
||||||
(for/bit-vector #:length 4 #:fill #t ([i '(1 2 3)]) (odd? i)))
|
(for/bit-vector #:length 4 #:fill #t ([i '(1 2 3)]) (odd? i)))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -152,4 +165,20 @@ mutate a shared bit-vector.}
|
||||||
Like @racket[for/bit-vector] but with the implicit nesting of @racket[for*].
|
Like @racket[for/bit-vector] but with the implicit nesting of @racket[for*].
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@deftogether[[
|
||||||
|
@defproc[(bit-vector->list [bv bit-vector?]) (listof boolean?)]
|
||||||
|
@defproc[(list->bit-vector [bits (listof boolean?)]) bit-vector?]
|
||||||
|
@defproc[(bit-vector->string [bv bit-vector?]) (and/c string? #rx"^[01]*$")]
|
||||||
|
@defproc[(string->bit-vector [s (and/c string? #rx"^[01]*$")]) bit-vector?]
|
||||||
|
]]{
|
||||||
|
|
||||||
|
Converts between bit-vectors and their representations as lists and
|
||||||
|
strings.
|
||||||
|
|
||||||
|
@examples[#:eval the-eval
|
||||||
|
(bit-vector->list (string->bit-vector "100111"))
|
||||||
|
(bit-vector->string (list->bit-vector '(#t #f #t #t)))
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
@close-eval[the-eval]
|
@close-eval[the-eval]
|
||||||
|
|
|
@ -114,3 +114,13 @@
|
||||||
(for ([ws (in-list '(8 30 62))])
|
(for ([ws (in-list '(8 30 62))])
|
||||||
(for ([i (in-range 10)])
|
(for ([i (in-range 10)])
|
||||||
(test (* ws 10))))))
|
(test (* ws 10))))))
|
||||||
|
|
||||||
|
(test-case "bit-vector string->list"
|
||||||
|
(let ([bitstrings '("0" "1" "10" "11" "1010110011100011110000")])
|
||||||
|
(for ([s (in-list bitstrings)])
|
||||||
|
(check-equal? (bit-vector->string (string->bit-vector s)) s)
|
||||||
|
(let ([bitlist (for/list ([c (in-string s)]) (eqv? c #\1))])
|
||||||
|
(check-equal? (bit-vector->list (string->bit-vector s))
|
||||||
|
bitlist)
|
||||||
|
(check-equal? (string->bit-vector s)
|
||||||
|
(list->bit-vector bitlist))))))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user