* IEEE-754 binary rep functions
@ 2002-10-22 6:20 Heinz Eriksson
2002-10-23 14:19 ` Ehud Karni
0 siblings, 1 reply; 2+ messages in thread
From: Heinz Eriksson @ 2002-10-22 6:20 UTC (permalink / raw)
How would one write elisp functions to convert
to and from the binary representation of a
IEEE-754 (single precision) floating point number?
I don't care about NaN etc.
/hz
#The perl would be something like:
$number = 1.0;
$binrep = unpack("H8",pack("F", $number))
# 3f800000 on a big-endian
$float = unpack("F",pack("H8", $binrep))
# back to 1.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: IEEE-754 binary rep functions
2002-10-22 6:20 IEEE-754 binary rep functions Heinz Eriksson
@ 2002-10-23 14:19 ` Ehud Karni
0 siblings, 0 replies; 2+ messages in thread
From: Ehud Karni @ 2002-10-23 14:19 UTC (permalink / raw)
Cc: Gnu Emacs help, Gnu Emacs source code
On Tue, 22 Oct 2002 08:20:55 +0200, Heinz Eriksson
<heinz.eriksson@era.ericsson.se> wrote:
>
> How would one write elisp functions to convert
> to and from the binary representation of a
> IEEE-754 (single precision) floating point number?
> I don't care about NaN etc.
Bellow is my code for the conversions you asked for.
Save the code to a file "IEEE-754.el" and load it into your Emacs
session using `load-file'.
To convert from number to hex representation do:
(setq HEX-VAL (IEEE-float-2-hex -5.678e+9))
To convert from hex representation to floating number do:
(setq FLT-VAL (IEEE-hex-2-float "4fed0123"))
Ehud.
;; IEEE-754.el - convert 32 bit floating number to/from its hex
;; (big-endian) representation according to IEEE-754
;;
;; These functions deals correctly with 0 and -/+ infinity
;; Both kind of NaN (not a number) are ignored
;;
;; written by Ehud Karni <ehud@unix.mvs.co.il>
;; References: http://www.cs.berkeley.edu/~ejr/projects/754/
;; http://research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html
;; http://www.cs.berkeley.edu/~wkahan/ieee754status/ieee754.ps
;; Conversion on-line:
;; http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html
;; History of IEEE-754
;; http://www.cs.berkeley.edu/~wkahan/ieee754status/754story.html
;; the value of IEEE-754 float is:
;; Normal number (normalized)
;; ( 1 - 2*sign ) * 2 ** (exp - exp-bias) * ( 1 + mantissa / mantissa-divisor )
;; Very small number (De-normalized)
;; ( 1 - 2*sign ) * 2 ** (1 - exp-bias ) * ( mantissa / mantissa-divisor )
;;
;; for a 32 bit float (sign/exp/mantissa bits = 1/8/23) ===>
;; ( 1 - 2*sign ) * 2 ** (exp - 127) * ( 1 + mantissa / 8388608 )
;; for a 64 bit float (sign/exp/mantissa bits = 1/11/52) ===>
;; ( 1 - 2*sign ) * 2 ** (exp - 1023) * ( 1 + mantissa / 4503599627370496 )
(defvar IEEE-sign-mlt 128 "multiplier for sign") ; 1 bits
(defvar IEEE-exp-bias 127 "exponent bias for float" ; 8 bits
(defvar IEEE-mantissa-divisor ?\x800000 "mantissa divisor for float") ; 23 bits
(defvar IEEE-float-mantissa-divisor (/ 1.0 (float IEEE-mantissa-divisor))
"floated 1 / mantissa divisor")
(defun IEEE-float-2-hex (FNUM)
"Convert a floating point number FNUM to 8 Hex digits string (big endian)"
(interactive "nEnter float to convert: ")
(or (floatp-safe FNUM)
(setq FNUM (float FNUM)))
(let ((IEEE-sign 0)
(IEEE-exp 0)
(IEEE-mantissa 0)
hex
)
(and (< FNUM 0) ; negative
(setq IEEE-sign IEEE-sign-mlt) ; yes, sign=1 (* 2**7)
(setq FNUM (- FNUM))) ; negate (abs) it
(cond
((= FNUM 0)) ; Zero - we all set
((= FNUM 1e+INF) ; infinite ?
(setq IEEE-exp IEEE-exp-bias)) ; exp = max, mantissa = 0
(t ;; real float
(setq IEEE-exp (floor (log FNUM 2.0))) ; exponent [ log 2 FNUM ] - integer
(if (<= IEEE-exp (- IEEE-exp-bias)) ; check for De-normalized number
(setq IEEE-exp 0 ; really - IEEE-exp-bias
IEEE-mantissa (truncate (* IEEE-mantissa-divisor
0.5 FNUM (expt 2.0 IEEE-exp-bias))))
;; normal float
(setq IEEE-mantissa (truncate (* IEEE-mantissa-divisor
(- (/ FNUM (expt 2.0 IEEE-exp)) 1))))
(setq IEEE-exp (+ IEEE-exp IEEE-exp-bias))) ;; offset-ed exp
))
(setq hex (format "%02X%06X" (+ IEEE-sign (/ IEEE-exp 2))
(+ IEEE-mantissa
(* (% IEEE-exp 2) IEEE-mantissa-divisor))))
;; (message "Float=%f sign=%d, exp=%d, mant=%d HEX=%s"
;; FNUM IEEE-sign IEEE-exp IEEE-mantissa hex)
hex))
(defun IEEE-hex-2-float (HEX)
"Convert an 8 Hex digits string (big endian) to floating point number"
(interactive "sEnter hex value (8 hex digits): ")
(if (or (not (stringp HEX))
(/= (length HEX) 8)
(string-match "[^0-9a-fA-F]" HEX))
(error "Arg must be a string of EXACTLY 8 hex (1-8, a-f, A-F) digits"))
(let ((S-EXP (string-to-number (substring HEX 0 2) 16))
(MANTISSA (string-to-number (substring HEX 2) 16))
(RSLT 1)
IEEE-sign
IEEE-exp
IEEE-mantissa
)
(setq IEEE-mantissa (logior MANTISSA IEEE-mantissa-divisor)) ; always set upper bit
(if (= IEEE-mantissa IEEE-mantissa-divisor) ; = --> zero mantissa, check special cases
(cond
((string-equal HEX "00000000")
(setq RSLT (float 0))) ; Zero
((string-equal HEX "3F800000")
(setq RSLT 1e+INF)) ; + infinity
((string-equal HEX "BF800000")
(setq RSLT -1e+INF)) ; - infinity
))
(if (/= RSLT 1)
RSLT ; special cases (0, infinity)
(setq IEEE-sign (ash S-EXP -7)) ; shift right 7 bits
(setq IEEE-exp (+ (ash (% S-EXP IEEE-sign-mlt) 1) ; shift (part) exp 1
(ash MANTISSA -23))) ; 1 bit from mantissa
(if (= IEEE-exp 0) ; De-normalized ?
(setq IEEE-mantissa (ash
(logxor IEEE-mantissa IEEE-mantissa-divisor) 1))) ; clear upper bit
;; (message "Hex=%s sign=%d, exp=%d, mant=%d"
;; HEX IEEE-sign IEEE-exp IEEE-mantissa)
(* ; result float
(- 1 IEEE-sign IEEE-sign) ; sign
(expt 2.0 (- IEEE-exp IEEE-exp-bias)) ; 2 ** exponent (un-biased)
(float IEEE-mantissa) ; mantissa part
IEEE-float-mantissa-divisor ; 1 / mantissa divisor
))))
;; For test do (note: the re-computed float is NOT rounded)
;; (IEEE-hex-2-float (IEEE-float-2-hex 123.456))
;; ---------------------- IEEE-754.el ends here -----------------------
--
Ehud Karni Tel: +972-3-7966-561 /"\
Mivtach - Simon Fax: +972-3-7966-667 \ / ASCII Ribbon Campaign
Insurance agencies (USA) voice mail and X Against HTML Mail
http://www.mvs.co.il FAX: 1-815-5509341 / \
mailto:ehud@unix.mvs.co.il Better Safe Than Sorry
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2002-10-23 14:19 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-10-22 6:20 IEEE-754 binary rep functions Heinz Eriksson
2002-10-23 14:19 ` Ehud Karni
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.