[gambit-list] Best way to read a negative number from a byte stream?

Ben Weaver ben at orangesoda.net
Tue Aug 11 23:19:32 EDT 2009


Hi all,

I'm implementing Google's protocol buffers in Gambit-C.  One of the
basic data types is a "varint" which represents a 64-bit integer as a
variable number of bytes in a byte stream.

This is the first time I've tried to "decode" data from a byte stream
as a signed number in Scheme.  In other programming languages that
don't have bignums I would have relied on integer overflow and done
something like: `(+ 1 (bitwise-not value))'.  Has anyone else tried to
do something like this before?  Is there a better way?

I fiddled around with various approaches and ended up with this:

(define (negative-64bit-value value)
  (copy-bit-field 63 0 value -1))

Which is used in the following way:

;; This value was accumulated by folding bytes from a stream into an
;; accumulator.  The seed value was zero and each byte was added to
;; the accumulator after being aligned by ARITHMETIC-SHIFT.  It is not
;; known whether the value should be positive or negative until the
;; last byte in the sequence is read from the stream.
(define accumulated-value #x7fffffffffffffffffff)
;; => 604462909807314587353087

(negative-64bit-value accumulated-value)
;; => -1

Thanks,

-Ben



More information about the Gambit-list mailing list