emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

IEEE single precision float values


From: Mario Lang
Subject: IEEE single precision float values
Date: Fri, 11 Feb 2005 10:34:52 +0100
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.3 (gnu/linux)

Hi.

While trying to implement a elisp library for a binary
network protocol which uses IEEE 32-bit float data types
I realized Emacs Lisp does not have any way to generate or interpret those.

I came up with the following two functions below.  I think they
are generically useable for network IO and possibly reading
certain data records from files directly.  I am fairly sure
my version is very bad regarding performance though.
Either way, I'd like to contribute this for eventual inclusion
in a suitable file in lisp/.  If anyone wants to take the
job of writing C level primitives which do the same thing,
that would be even nicer.

(defun ieeefloat-to-emacs (string)
  "Convert a 32bit IEEE floating point value to Emacs floating point
representation."
  (assert (length string) 4)
  (let ((s (lsh (logand (aref string 3) #X80) -7))
        (e (+ (lsh (logand (aref string 3) #X7F) 1)
              (lsh (logand (aref string 2) #X80) -7)))
        (f (+ (aref string 0)
              (lsh (aref string 1) 8)
              (lsh (logand (aref string 2) #X7F) 16))))
    (cond
     ((and (= e 0) (= f 0))
      (* 0.0 (expt -1 s)))
     ((and (= e 255) (or (= f (1- (expt 2 23))) (= f 0)))
      (* 1.0e+INF (expt -1 s)))
     ((and (= e 255) (not (or (= f 0) (= f (1- (expt 2 23))))))
      0.0e+NaN)
     (t
      (* (round (* (* (expt -1 s)
                      (expt 2.0 (- e 127))
                      (1+ (/ f (expt 2.0 23))))
                   (expt 10.0 7.0)))
         (expt 10.0 -7.0))))))

(defun emacs-to-ieeefloat (value)
  "Convert Emacs floating point numers to 32bit IEEE floating
point representation."
  (let (s (e 0) f)
    (cond
     ((string= (format "%f" value) (format "%f" -0.0))
      (setq s 1 f 0))
     ((string= (format "%f" value) (format "%f" 0.0))
      (setq s 0 f 0))
     ((= value 1.0e+INF)
      (setq s 0 e 255 f (1- (expt 2 23))))
     ((= value -1.0e+INF)
      (setq s 1 e 255 f (1- (expt 2 23))))
     ((string= (format "%f" value) (format "%f" 0.0e+NaN))
      (setq s 0 e 255 f 1))
     (t
      (setq s (if (>= value 0.0)
                  (progn (setq f value) 0)
                (setq f (* -1 value)) 1))
      (while (>= (* f (expt 2.0 e)) 2.0) (setq e (1- e)))
      (unless (= e 0) (while (< (* f (expt 2.0 e)) 1.0) (setq e (1+ e))))
      (setq f (round (* (1- (* f (expt 2.0 e))) (expt 2 23)))
            e (+ (* -1 e) 127))))
    (concat (vector (logand f #XFF) (lsh (logand f #XFF00) -8)
                    (+ (lsh (logand e #X01) 7) (lsh (logand f #X7F0000) -16))
                    (+ (lsh s 7) (lsh (logand e #XFE) -1))))))

-- 
CYa,
  Mario




reply via email to

[Prev in Thread] Current Thread [Next in Thread]