[comp.sys.handhelds] New and Improved IEEE-754 conversion Porgram

oscar@oscar.uucp (Oscar R. Mitchell) (02/17/90)

+----------------------------------------------------------------------------+
|   original version obtained from internet newsgroup  'comp.sys.handhelds'  |
|(authored by: Russell Williams -> ..uunet!elxsi!rw -> ..ucbvax!sun!elxsi!rw)|
+----------------------------------------------------------------------------+




	                          HP-28s
	      'IEEE 754 std. Binary format <-> Decimal format'
	                    Conversion Program




(the following is text from the original article)
>    A while back someone posted a request for IEEE conversions -- here are
> some simple routines to do them.  They handle 32 and 64 bit values,
> NaNs and infinities.
>
>    THESE ROUTINES PROVIDE ONLY APPROXIMATE RESULTS.  They are not accurate
> to the last bit.  The HP-28S cannot accurately represent the decimal
> equivalents of 64 bit IEEE values, but even 32 bit conversions will have
> small errors.
>
>    B->F converts binary numbers in IEEE 32 or 64 bit format to HP 28S
> real numbers.  NaNs and Infinities are returned as ascii strings.
> F->B converts an HP28S real number to 32 or 64 bit IEEE format depending
> on the setting of the binary word size.
>
>    DFLDS is used by B->F, and extracts binary fields from a 64 bit IEEE
> number.  SFLDS (also used by B->F) extracts binary fields from a 32 bit IEEE
> number.  FVAL computes an HP28S real value given the sign, exponent, fraction,
> and maximum legal exponent value.  "/=" represents the 28S "not equal"
> operator.
(end of original text)


This revised version increased the accuracy of the Single Precision computation
and incorporated a more complete conformance to the IEEE-754 Floating Point
Binary Standard (i.e. indication of +/-0 (zero), indication of NaN (not-a-number)
type (i.e. QNaN - quiet NaN, or SNaN - Signalling NaN - all with respective sign).

Also, work has been done to increase the accuracy of Double precision, however,
I have not been successful (I may change the algorithym used - to be similar to
what is done in C's printf/doprnt library functions (in other words, remove the
dependence on the 28s' B->R limitation)).


NOTE:
 Sorry for no checksums (I recently sold my 28s, awaiting HP's newest).
 However, I did do a 'memory reset' on my 28s and re-typed the programs in
 from this listing and they worked.


Enjoy,
Oscar.



	       ------------------------------------------------
(form feed)

	                    "Binary -to- Decimal"



B->F:
<< IF RCWS 64 == THEN
      DFLDS FVAL
   ELSE
      SFLDS FVAL 6 SCI
      IFERR RND THEN
      END
      STD
   END
>>


	       ------------------------------------------------
(form feed)

	                   "Decimal -to- Binary"



F->B:
<< ->NUM ABS LAST DUP
   IF 0 == THEN
      CLEAR #0h
   ELSE
      IF RCWS 64 == THEN
	 1 SF
      ELSE
	 1 CF
      END
      IF 0 < THEN
	 #1h
      ELSE
	 #0h
      END
      -> r s
      << 'FLOOR(LN(r)/LN(2))' EVAL -> e
	 << 'r/2^e-1' EVAL
	    IF 1 FS? THEN
	       2 52 ^
	    ELSE
	       2 23 ^
	    END
	    * -> m
	    << s RR e
	       IF 1 FS? THEN
	          1023 + R->B RRB RR RR RR RR
	       ELSE
	          127 + R->B RRB RR
	       END
	       + m +
	    >>
	 >>
      >>
   END
>>


	       ------------------------------------------------
(form feed)

	            "Single Precision Conversion (in Binary format)"



SFLDS:
<< -> num
 << num #400000h AND IF #0h == THEN 2 CF ELSE 2 SF END num -> n
   << n RL #1h AND B->R n RL RLB #FFh AND B->R n #7FFFFFh AND B->R
      2 23 ^ / 255
   >>
>>


	       ------------------------------------------------
(form feed)

	            "Double Precision Conversion (in Binary format)"



DFLDS:
<< -> num
 << num #8000000000000h AND IF #0h == THEN 2 CF ELSE 2 SF END num -> n
   << n RL #1h AND B->R n RLB RL RL RL RL #7FFh AND B->R
      n #FFFFFFFFFFFFFh AND B->R 2 52 ^ / 2047
   >>
>>


	       ------------------------------------------------
(form feed)

	                     "Decmail Conversion"



FVAL:
<< -> s e f emax
   << IF 'e<emax AND e>0' EVAL THEN
	 '(-1)^s*2^(e-(emax-1)/2)*(1+f)' EVAL
      ELSE
	 IF 'e==0 AND f==0' EVAL THEN
	    IF s THEN
	       "-ZERO"
	    ELSE
	       "+ZERO"
	    END
	 ELSE
	    IF 'e==emax AND f/=0' EVAL THEN
	      IF 2 FS? THEN
	          IF s THEN
	             "-QNaN"
	          ELSE
	             "+QNaN"
	          END
	      ELSE
	          IF s THEN
	             "-SNaN"
	          ELSE
	             "+SNaN"
	          END
	      END
	    ELSE
	       IF 'e==emax AND f==0' EVAL THEN
	          IF s THEN
	             "-INF"
	          ELSE
	             "+INF"
	          END
	       ELSE
	          '(-1)^s*2^((emax-3)/2)*f' EVAL
	       END
	    END
	 END
      END
   >>
>>


(form feed)
------------------------------------------------------------------------------
ORMitchell                                                            09/07/89
------------------------------------------------------------------------------

Revisions:
	01).   09/08/89   Changed the number of  F's  in DFLDS to 13, to
	                   properly mask-in the double precision mantissa
	                    (mask off the DP exponent and sign bits).
	                  This change allows 'B->F' to work for double prec..

	02).  09/11/89   -Added the ability to properly decode the correct
	                   NaN (whether +/-QNaN or +/-SNaN) to 'FVAL'
	                    (the logic needed to determine the mantissa's msb
	                     was added to both 'DFLDS' and 'SFLDS' by setting/
	                     clearing user flag #2).
	                 -Changed the constant '8388608' used in 'SFLDS' and
	                   'F->B' to '2^23' to be more consistant with the
	                   double precision routines.
	                 -Changed the first '-> n' instruction in 'SFLDS' and
	                   'DFLDS' to '-> num' in order to support the NaN code.

	03).  09/11/89   -Corrected typo in 'F->B' then function 'R-B' should
	                   have been 'R->B'.

	04).  09/29/89   -Added comments.




><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><
  Oscar R. Mitchell
   IBM Advanced Workstation Division
    (RISC System/6000(tm) Floating Point Processor Design Group)
   Mail Stop: ZIP 4359
   Austin, Texas   78758
   IBM Tieline:  678-6733
     USA Phone: (512)838-6733

    IBM VNet:  OSCAR at AUSVM6
    IBM InterNet:  oscar@oscar.austin.ibm.com
    USA InterNet:  uunet!cs.utexas.edu!ibmaus!auschs!oscar.austin.ibm.com!oscar
    CI$ Net: 76356.1170@compuserve.com

#include <standard.disclaimer>   /* I DO NOT speak for IBM, only for MYSELF */
><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><
(form feed)
******************** END OF IEEE-754 <-to-> HP28s LISTING *********************
*******************************************************************************
><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><
 IBM Advanced Workstations Division                  IBM Tieline:  678-6733
 RISC System/6000(tm) Floating Point Processor Design Group
   Mail Stop: ZIP 4359                                 USA Phone: (512)838-6733
   Austin, Texas  78758                   CI$ Net: 76356.1170@compuserve.com
   IBM VNet:  OSCAR at AUSVM6        IBM InterNet:  oscar@oscar.austin.ibm.com
   USA InterNet:  uunet!cs.utexas.edu!ibmaus!auschs!oscar.austin.ibm.com!oscar
#include <standard.disclaimer>  /* I DO NOT speak for IBM */  Oscar R. Mitchell