ConvertHexToFloatingPoint

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]].

AWK Code

		# 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 {

}

C++ code for test program

#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

  1. #######################################
  2. function to convert from raw to ieee 754 float32
  3. x is the input number, 4 bytes assumed

function f_ieee754(x) { # upper most bit is the sign sign = and(x,0x80000000)

  1. bits 23-30 (next 8) are the exponent exponent = and(x,0x7F800000)
  2. shift them down, then offset exponent /= 0x800000 exponent -= 127
  3. bits 0-22 (lower 23) are the fractional component fraction = and(x,0x007FFFFF)
  4. divide them down to the right range, add 1 (as per spec) fraction /= 0x800000 fraction += 1
  5. put them together fval = fraction * 2^exponent
  6. factor in the sign of the original number if(sign != 0) fval *= -1

return fval } BEGIN { x = f_ieee754(0x41f24000) printf("x = %f\n",x) }

you should get 30.28125