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.
B->F:
<< IF RCWS 64 == THEN
DFLDS FVAL
ELSE
SFLDS FVAL 6 SCI
IFERR RND THEN
END
STD
END
>>
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
8388608
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
>>
SFLDS:
<< -> n
<< n RL #1h AND B->R n RL RLB #FFh AND B->R n #7FFFFFh AND B->R
8388608 / 255
>>
>>
DFLDS:
<< -> n
<< n RL #1h AND B->R n RLB RL RL RL RL #7FFh AND B->R
n #FFFFFFFFh AND B->R 2 52 ^ / 2047
>>
>>
FVAL:
<< -> s e f emax
<< IF 'e0' EVAL THEN
'(-1)^s*2^(e-(emax-1)/2)*(1+f)' EVAL
ELSE
IF 'e==0 AND f==0' EVAL THEN
0
ELSE
IF 'e==emax AND f/=0' EVAL THEN
"NaN"
ELSE
IF 'e==emax AND f==0' EVAL THEN
IF s THEN
"-Infinity"
ELSE
"+Infinity"
END
ELSE
'(-1)^s*2^((emax-3)/2)*f' EVAL
END
END
END
END
>>
>>
Russell Williams
..uunet!elxsi!rw
..ucbvax!sun!elxsi!rw