From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Mario Lang Newsgroups: gmane.emacs.devel Subject: IEEE single precision float values Date: Fri, 11 Feb 2005 10:34:52 +0100 Message-ID: <87hdkjsamb.fsf@lexx.delysid.org> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1108115967 14716 80.91.229.6 (11 Feb 2005 09:59:27 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Fri, 11 Feb 2005 09:59:27 +0000 (UTC) Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Feb 11 10:59:21 2005 Return-path: Original-Received: from lists.gnu.org ([199.232.76.165]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1CzXa4-00081y-00 for ; Fri, 11 Feb 2005 10:59:20 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1CzXoy-000770-5R for ged-emacs-devel@m.gmane.org; Fri, 11 Feb 2005 05:14:44 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1CzXUI-0001l3-1F for emacs-devel@gnu.org; Fri, 11 Feb 2005 04:53:22 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1CzXTe-0001QF-N2 for emacs-devel@gnu.org; Fri, 11 Feb 2005 04:52:44 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1CzXTc-0001Bg-LL for emacs-devel@gnu.org; Fri, 11 Feb 2005 04:52:40 -0500 Original-Received: from [213.46.255.13] (helo=viefep14-int.chello.at) by monty-python.gnu.org with esmtp (Exim 4.34) id 1CzXCC-0005RD-MN for emacs-devel@gnu.org; Fri, 11 Feb 2005 04:34:41 -0500 Original-Received: from lexx.delysid.org ([84.115.136.208]) by viefep14-int.chello.at (InterMail vM.6.01.03.05 201-2131-111-107-20040910) with ESMTP id <20050211093439.HPVY2993.viefep14-int.chello.at@lexx.delysid.org> for ; Fri, 11 Feb 2005 10:34:39 +0100 Original-Received: from mlang by lexx.delysid.org with local (Exim 3.36 #1 (Debian)) id 1CzXCO-0005eP-00 for ; Fri, 11 Feb 2005 10:34:52 +0100 Original-To: emacs-devel@gnu.org User-Agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.3 (gnu/linux) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:33245 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:33245 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