[gambit-list] Best way to read a negative number from a byte
David Rush
kumoyuki at gmail.com
Wed Aug 12 03:46:45 EDT 2009
2009/8/12 Ben Weaver <ben at orangesoda.net>:
> 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.
>
> Has anyone else tried to
> do something like this before? Is there a better way?
Well I don;t know about better, but I just convert to a plain old
unsigned integer first (by the usual methods) and then, since I know
the size of the physical representation I use the following code to
implement the two's complement conversion (larceny-specific, but I
know that Gambit has an analog for fixnum? and fxlogand):
(define max-fixnum-exponent
(let find-max-fixnum ((e 16))
(if (fixnum? (expt 2 e))
(find-max-fixnum (+ e 1))
(- e 1)
)))
(define (sign-bit value bit-number)
(if (> bit-number max-fixnum-exponent)
(sign-bit (quotient value (expt 2 max-fixnum-exponent))
(- bit-number max-fixnum-exponent))
(let ((mask (expt 2 (- bit-number 1))))
(= 0 (fxlogand value mask))
)))
(define (unsigned->signed value n-bits)
(if (sign-bit value (- n-bits 1))
value
(- value (expt 2 n-bits))
))
Obviously (sign-bit ...) is the expensive part of this code, and if
you were being clever and type-specific you could probably grab the
sign bit on the fly as part of the conversion from a byte-stream to
the unsigned integer form. HTH.
david rush
--
GPG Public key at http://cyber-rush.org/drr/gpg-public-key.txt
More information about the Gambit-list
mailing list