Subject: [clisp-list] inconsistency between gray streams and write-float

From: Bernard Urban <[email-masked]>
Date: 12 Jul 2001 21:20:10 +0200

Here a clisp-2.25 session, about implementing a gray stream 
which output is a vector of bytes:

[1]> (defclass my-byte-vector-stream (lisp:fundamental-binary-output-stream)
  ((vec :accessor stream-vec
        :initform (make-array 100 :element-type '(unsigned-byte 8)
                              :adjustable t
                              :fill-pointer 0))))

#<STANDARD-CLASS MY-BYTE-VECTOR-STREAM>
[2]> (defmethod lisp:stream-write-byte ((s my-byte-vector-stream) (byte integer))
  (vector-push-extend byte (stream-vec s) 100))

WARNING:
The generic function #<GENERIC-FUNCTION STREAM-WRITE-BYTE> is being modified, but has already been called.
#<STANDARD-METHOD
  (#<STANDARD-CLASS MY-BYTE-VECTOR-STREAM> #<BUILT-IN-CLASS INTEGER>)>
[3]> (defvar my-stream (make-instance 'my-byte-vector-stream))
MY-STREAM
[4]> (lisp:write-byte 56 my-stream)
56
[5]> (stream-vec my-stream) ;;; all is fine until here
#(56)
[6]> (lisp:write-float (atan 1) my-stream 'single-float :big) 

0.7853981
[7]> (stream-vec my-stream)
#(56 0 0 1 1)
[8]> (lisp:write-float 0.5e0 my-stream 'single-float :big) 
0.5
[9]> (stream-vec my-stream) 
#(56 0 0 1 1 0 0 1 1)

It is impossible that (0 0 1 1) is the IEEE representation of both
0.5 and (atan 1)... I discovered that write-float outputs not a 
sequence of 4 or 8 bytes, but a sequence of 32 or 64 bits. 
So to solve the problem, instead of using the default 
stream-write-byte-sequence, I must write something ugly:

[10]> (defmethod lisp:stream-write-byte-sequence ((s my-byte-vector-stream)
                                            (seq bit-vector)
                                            &optional (start 0) (end nil))
  (dotimes (n (/ (length seq) 8))
    (do ((i (* 8 n) (+ i 1))
         (z 0 (+ (* 2 z)
                 (sbit seq i))))
        ((>= i (* 8 (+ n 1))) (lisp:stream-write-byte s z)))))

WARNING:
The generic function #<GENERIC-FUNCTION STREAM-WRITE-BYTE-SEQUENCE> is being modified, but has already been called.
#<STANDARD-METHOD
  (#<STANDARD-CLASS MY-BYTE-VECTOR-STREAM> #<BUILT-IN-CLASS BIT-VECTOR>)>
[11]> (lisp:write-float (atan 1) my-stream 'single-float :big) 

0.7853981
[12]> (stream-vec my-stream)
#(56 0 0 1 1 0 0 1 1 63 73 15 218)
[13]> 

which is correct.

I will try read-float this evening...

-- 

Bernard Urban