This code uses gawk specific features, such as the [[1][strtonum]] function, so gawk is required to utilize this function.
This code is based on the fantastic [[2][tutorial on fp conversion by Orley and Matthews]].
# function to convert 4 "bytes" of hex chars into a floating point
# bytes are ordered
# [high....low]
# b3 b2 b1 b0
# based on http://ecpe.ece.iastate.edu/arun/CprE281_F05/ieee754/ie5.html
# http://babbage.cs.qc.edu/IEEE-754/Decimal.html was used to test my code
#
function HexToFP(b3,b2,b1,b0)
{
fval = 0
bias=127
# convert the character bytes into numbers
i3=strtonum("0x" b3)
i2=strtonum("0x" b2)
i1=strtonum("0x" b1)
i0=strtonum("0x" b0)
# first, we need to separate all the parts of the floating point
# upper most bit is the sign
sign=and(i3, 0x80)
# bits 23-30 (next 8) are the exponent
exponent=and(i3,0x7F)
tmp=and(i2,0x80)
tmp=rshift(tmp, 7)
exponent=lshift(exponent, 1)
exponent=or(exponent,tmp)
# bits 0-22 are the fraction
fraction=and(i2,0x7F)
fraction=lshift(fraction,8)
fraction=or(fraction,i1)
fraction=lshift(fraction,8)
fraction=or(fraction,i0)
#convert the fraction part into a decimal. need to look at the
# individual bits and compute the base 10 value
decfrac=0
for(i=22;i>=0;i--)
{
if( and( fraction , lshift(0x01,i) ))
decfrac = decfrac+2^(i-23)
}
fval=(1+decfrac) * 2^(exponent-bias)
if(sign)
fval=fval*-1
return fval
}
BEGIN {
}
{
print HexToFP($4, $3, $2, $1)
# for use with test program
# print HexToFP($4, $3, $2, $1) " ?= " $5
}
END {
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
float f[10];
char *p;
srand(time(NULL));
for(int i=0;i<10;i++)
{
f[i]=rand()%1000;
f[i]/=1000;
f[i]+=rand()%20000;
f[i]-=10000;
}
for(int j=0;j<10;j++)
{
p=(char *)&f[j];
for(int i=0;i<4;i++)
printf("%02x ",(*(p+i)&0xFF));
printf("%.3f\n",f[j]);
}
return 0;
}
Here's another form of the same thing, simplified a bit
function f_ieee754(x) { # upper most bit is the sign sign = and(x,0x80000000)
return fval } BEGIN { x = f_ieee754(0x41f24000) printf("x = %f\n",x) }
you should get 30.28125