Decoding IEEE 754

19.03.2010 13:20

There's a discussion going on today on Zemanta's staff mailing list about floating point formats and precision. I thought the following C code might also be useful to anyone trying to understand how floating point values are handled in modern hardware.

This manually decodes and prints parts of the floating point number stored in C's double type. Of course, it assumes that hardware uses the IEEE 754 "double" for that. That should be true at least on all descendants of the Intel i386 architecture.

#include <stdint.h>
#include <stdio.h>

int main() {
	double a = 0.1f;
	uint8_t* ac = (uint8_t*) &a;

	int n;
	for(n=7;n>=0;n--) printf("%02x ", ac[n]);
	printf("\n\n");

	int64_t e, m, s;

	m = 1;		// 1 (implied bit)
	m<<=4;
	m += ac[6] & ((1<<4)-1);	// 5
	m<<=8;
	m += ac[5];	// 13
	m<<=8;
	m += ac[4];	// 21
	m<<=8;
	m += ac[3];	// 29
	m<<=8;
	m += ac[2];	// 37
	m<<=8;
	m += ac[1];	// 45
	m<<=8;
	m += ac[0];	// 53

	printf("mantissa = %lld * 2^(-52)\n", m);

	e = ac[7] & ((1<<7)-1);	// 7
	e<<=4;
	e += ac[6]>>4;	// 11

	e -= 1023;	// exponent bias

	printf("exponent = %lld\n", e);

	s = ac[7]>>7;

	printf("sign bit = %lld\n\n", s);

	printf("%f ~= (-1)^%lld * %lld * 2^(%lld)\n", a, s, m, e - 52);

	return 0;
}

Adjust the value of a to taste. By default it will print:

3f b9 99 99 a0 00 00 00 

mantissa = 7205759511166976 * 2^(-52)
exponent = -4
sign bit = 0

0.100000 ~= (-1)^0 * 7205759511166976 * 2^(-56)

By the way, bc, the arbitrary precision calculator, comes very handy when doing calculations that involve limits of floating point formats.

Posted by Tomaž | Categories: Code

Add a new comment


(No HTML tags allowed. Separate paragraphs with a blank line.)