Floating point puzzle

Steve Summit scs at athena.mit.edu
Sun Aug 14 12:15:38 AEST 1988


In article <225800048 at uxe.cso.uiuc.edu> mcdonald at uxe.cso.uiuc.edu writes:
>I tried running the following program...
>
>#include <stdio.h>
>
>main()
>{
>union { 
>    float fl;
>    unsigned long  lo;
>} x,y;
>	x.fl = 1.0/10.0;
>	y.fl = 1677721.0/16777216.0; 
>	printf("x: %lx", x.lo);
>	printf("%20.17f\n",x.fl);
>	printf("y: %lx", y.lo);
>	printf("%20.17f\n",y.fl);
>}
>
>/* output is:
>
>x: 3dcccccd 0.10000000149011610
>y: 3dccccc8 0.09999996423721313
>
>/*
>
>Try running this program, or, if your compiler has 32bit ints, 
>substitute "int" for "long" and "%x" for %lx".

Look, folks, if you're going to write machine-dependent programs,
at least do so portably!  Use sizeof() so you don't have to know
how big floats and doubles are on your machine:

	main()
	{
	printfloat(1.0/10.0);
	printfloat(1677721.0/16777216.0);
	}

	int littlendian = 1;

	union u	{
		double d;
		char c[sizeof(double)];
		};

	printfloat(d)
	double d;
	{
	union u u;
	int i;

	u.d = d;
	printf("%-10.7g = ", d);
	for(i = 0; i < sizeof(d); i++)
		{
		int ii = littlendian ? sizeof(d) - 1 - i : i;
		printf("%02x", u.c[ii] & 0xff);
		}
	printf("\n");
	}

Oops, it's still a little machine-dependent: for a pleasingly-
arranged output, you have to know whether your machine stores
things least-significant or mist-significant byte first, which is
an issue I'll not diverge to now.

You can leave out the &0xff in the next-to-last printf if you
make the second member of the union an unsigned char array, if
your compiler understands them.  (Most newer ones do.)

If you don't like unions, you can do it with pointer punning:

	printfloat(d)
	double d;
	{
	int i;
	printf("%-10.7g = ", d);
	for(i = 0; i < sizeof(d); i++)
		{
		int ii = littlendian ? sizeof(d) - 1 - i : i;
		printf("%02x", ((char *)&d)[ii] & 0xff);
		}
	printf("\n");
	}

The output (on a VAX; your actual funny hex numbers may vary) is:

	0.1        = cccdcccccccc3ecc
	0.09999996 = 00000000ccc83ecc

They're quite a bit different, but the reasons why have been
explained already.

                                            Steve Summit
                                            scs at adam.pika.mit.edu



More information about the Comp.lang.c mailing list