From: Cory Spencer
Subject: Sequence question
Date: 
Message-ID: <9vpe8g$15a$1@nntp.itservices.ubc.ca>
I'm currently writing a program where I'm using read-sequence to read in
blocks of data three (unsigned) bytes at a time.  What I would like to be
able to do it to treat each 3 byte block as a single integer, instead of 3
individual bytes.  Instead of writing a series of shift lefts and
additions (shift the first byte left 8 bits, add the second, shift that
result left 8 bits, add the third), is there an easier method of
converting this sequence to an integer value?

Thanks for any help,

Cory

From: Kaz Kylheku
Subject: Re: Sequence question
Date: 
Message-ID: <PWXT7.21389$OY3.435575@news3.calgary.shaw.ca>
In article <············@nntp.itservices.ubc.ca>, Cory Spencer wrote:
>I'm currently writing a program where I'm using read-sequence to read in
>blocks of data three (unsigned) bytes at a time.  What I would like to be
>able to do it to treat each 3 byte block as a single integer, instead of 3
>individual bytes.  Instead of writing a series of shift lefts and
>additions (shift the first byte left 8 bits, add the second, shift that
>result left 8 bits, add the third), is there an easier method of
>converting this sequence to an integer value?

How about:

      (+ (* #x10000 octet1) (* #x100 octet2) octet3)

Assuming the three values are in the range 0 to 255, as implied
by their names.
From: Raymond Wiker
Subject: Re: Sequence question
Date: 
Message-ID: <86vgf3624y.fsf@raw.grenland.fast.no>
Cory Spencer <········@interchange.ubc.ca> writes:

> I'm currently writing a program where I'm using read-sequence to read in
> blocks of data three (unsigned) bytes at a time.  What I would like to be
> able to do it to treat each 3 byte block as a single integer, instead of 3
> individual bytes.  Instead of writing a series of shift lefts and
> additions (shift the first byte left 8 bits, add the second, shift that
> result left 8 bits, add the third), is there an easier method of
> converting this sequence to an integer value?

        Two suggestions:

;;; This does not appear to work in SBCL - I'm getting values that
;;; appear to be 32-bit instead of 24-bit.

(with-open-file (in ".bashrc" :direction :input
		    :element-type '(unsigned-byte 24))
  (do ((elt (read-byte in nil) (read-byte in nil)))
      ((null elt))
    (format t "Read ~a~%" elt)))

;;; This approach gives values that look more reasonable, but is a bit
;;; more convoluted :-)

(defun read-int8 (stream)
  (read-byte stream nil))

(defmacro def-def-read-int-x (name numbytes)
  (let ((res (gensym "RES-"))
	(elt (gensym "ELT-"))
	(i (gensym "I-")))
    `(defun ,name (stream)
      (let ((,res 0))
	(dotimes (,i ,numbytes)
	  (let ((,elt (read-int8 stream)))
	    (if (null ,elt)
		(return-from ,name nil)
		(setf ,res (dpb ,elt (byte 8 (* (- 2 ,i) 8)) ,res)))))
	,res))))

(def-def-read-int-x read-int16 2)
(def-def-read-int-x read-int24 3)
(def-def-read-int-x read-int32 4)

(with-open-file (in ".bashrc" :direction :input
		    :element-type '(unsigned-byte 8))
  (do ((elt (read-int24 in) (read-int24 in)))
      ((null elt))
    (format t "Read ~a~%" elt)))

-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/
From: Sam Steingold
Subject: Re: Sequence question
Date: 
Message-ID: <uk7vj45ww.fsf@xchange.com>
> * In message <············@nntp.itservices.ubc.ca>
> * On the subject of "Sequence question"
> * Sent on 19 Dec 2001 07:05:52 GMT
> * Honorable Cory Spencer <········@interchange.ubc.ca> writes:
>
> I'm currently writing a program where I'm using read-sequence to read
> in blocks of data three (unsigned) bytes at a time.  What I would like
> to be able to do it to treat each 3 byte block as a single integer,
> instead of 3 individual bytes.  Instead of writing a series of shift
> lefts and additions (shift the first byte left 8 bits, add the second,
> shift that result left 8 bits, add the third), is there an easier
> method of converting this sequence to an integer value?

if you are using CLISP, you can use READ-INTEGER
<http://clisp.cons.org/impnotes.html#d39e14329>

-- 
Sam Steingold (http://www.podval.org/~sds)
Keep Jerusalem united! <http://www.onejerusalem.org/Petition.asp>
Read, think and remember! <http://www.iris.org.il> <http://www.memri.org/>
NY survival guide: when crossing a street, mind cars, not streetlights.
From: Bruce Hoult
Subject: Re: Sequence question
Date: 
Message-ID: <bruce-8AE06F.20204519122001@news.paradise.net.nz>
In article <············@nntp.itservices.ubc.ca>, Cory Spencer 
<········@interchange.ubc.ca> wrote:

> I'm currently writing a program where I'm using read-sequence to read in
> blocks of data three (unsigned) bytes at a time.  What I would like to be
> able to do it to treat each 3 byte block as a single integer, instead of 3
> individual bytes.  Instead of writing a series of shift lefts and
> additions (shift the first byte left 8 bits, add the second, shift that
> result left 8 bits, add the third), is there an easier method of
> converting this sequence to an integer value?

On modern CPUs with barrel shifters and several integer execution units 
there is no faster portable way.

The only thing that has a chance of being faster is to read several 
groups of 2, 4, or 8 bytes into an integer variable (or Altivec, or SSE 
etc) and then use shifting and masking to extract the values.  i.e. read 
3 16 bit integers to produce 2 values, or read 3 32 bit integers to 
produce 4 values, or read 3 64 bit integers to produce 8 values.  But 
this only works if your CPU has the same byte-endianess as the source 
data, which is only a 50/50 chance.

-- Bruce