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