Re: Converting bits to FLOAT
- From: Peter Seibel <peter@xxxxxxxxxxxxxxx>
- Date: Fri, 02 Sep 2005 18:33:30 GMT
Denis Bueno <gtg385h@xxxxxxxxxxxxxxx> writes:
> I'm parsing TIFF images in Lisp, and some of the bitfields in the image can
> (possibly) contain floats, packed in IEEE format. I've written functions that
> convert from other datatypes to the Lisp native format (shorts, longs,
> rationals, etc.), but can't figure out what to do for floats.
>
> Is there a way to convert a bunch of bits (say, a 4-byte unsigned int) into a
> FLOAT object? I see that DECODE-FLOAT allows one to go the other way....
It depends on the floating point representation. Here's some code I
wrote to deal with the two IEEE floating-point formats (one 4-bytes
and the other 8-bytes) used in Java class files. It also handles
not-a-number and positive-and-negative infinities, at the moment by
returning a symbol. In implementations that support those constructs
directly you might want to return the appropriate object. This code is
licensed under a BSD-style license so you're free to use it how you
wish. (I'm pretty sure it was in a clean working state last time I
touched it but there's no guarantees that there aren't horrendous bugs
in it.)
(defun encode-float-bits (float sign-byte exponent-byte mantissa-byte bias)
(multiple-value-bind (original-mantissa original-exponent sign) (integer-decode-float (float float 0d0))
(multiple-value-bind (mantissa exponent) (scale original-mantissa original-exponent (1+ (byte-size mantissa-byte)))
(incf exponent (byte-size mantissa-byte))
(when (zerop mantissa)
(setf exponent (- bias)))
(when (<= exponent (- bias))
(setf (values mantissa exponent) (denormalize original-mantissa original-exponent bias mantissa-byte)))
(incf exponent bias)
(when (> (integer-length exponent) (byte-size exponent-byte))
(setf mantissa 0 exponent (ldb (byte (byte-size exponent-byte) 0) (lognot 0))))
(let ((result 0))
(setf (ldb sign-byte result) (if (plusp sign) 0 1))
(setf (ldb exponent-byte result) exponent)
(setf (ldb mantissa-byte result) mantissa)
result))))
(defun decode-float-bits (bits sign-byte exponent-byte mantissa-byte bias)
(let ((sign (if (zerop (ldb sign-byte bits)) 1 -1))
(exponent (ldb exponent-byte bits))
(mantissa (ldb mantissa-byte bits)))
(if (= (logcount (ldb exponent-byte bits)) (byte-size exponent-byte))
(if (zerop mantissa)
(if (plusp sign) 'positive-infinity 'negative-infinity)
'not-a-number)
(progn
(when (plusp exponent)
(incf mantissa (expt 2 (byte-size mantissa-byte))))
(if (zerop exponent)
(setf exponent (- 1 bias (byte-size mantissa-byte)))
(setf exponent (- (- exponent (byte-size mantissa-byte)) bias)))
(float (* sign (* mantissa (expt 2 exponent))) 0d0)))))
(defun scale-integer (value bits)
"Scale an integer value so it fits in the given number of bits."
(if (zerop value)
(values 0 0)
(let ((scale (- bits (integer-length value))))
(values (round (* value (expt 2 scale))) scale))))
(defun scale (mantissa exponent mantissa-bits)
"Scale an integer value so it fits in the given number of bits."
(multiple-value-bind (mantissa scale) (scale-integer mantissa mantissa-bits)
(values mantissa (- exponent scale))))
(defun denormalize (mantissa exponent bias mantissa-byte)
(multiple-value-bind (mantissa exponent) (scale mantissa exponent (byte-size mantissa-byte))
(incf exponent (byte-size mantissa-byte))
(values (ash mantissa (- exponent (1+ (- bias)))) (- bias))))
(defun encode-single-float-bits (float)
(encode-float-bits float (byte 1 31) (byte 8 23) (byte 23 0) 127))
(defun encode-double-float-bits (float)
(encode-float-bits float (byte 1 63) (byte 11 52) (byte 52 0) 1023))
(defun decode-single-float-bits (bits)
(decode-float-bits bits (byte 1 31) (byte 8 23) (byte 23 0) 127))
(defun decode-double-float-bits (bits)
(decode-float-bits bits (byte 1 63) (byte 11 52) (byte 52 0) 1023))
-Peter
--
Peter Seibel * peter@xxxxxxxxxxxxxxx
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp * http://www.gigamonkeys.com/book/
.
- Follow-Ups:
- Re: Converting bits to FLOAT
- From: Denis Bueno
- Re: Converting bits to FLOAT
- References:
- Converting bits to FLOAT
- From: Denis Bueno
- Converting bits to FLOAT
- Prev by Date: Re: GC in Jon's raytracing benchmark
- Next by Date: Re: GC in Jon's raytracing benchmark
- Previous by thread: Re: Converting bits to FLOAT
- Next by thread: Re: Converting bits to FLOAT
- Index(es):
Relevant Pages
|