Floating point puzzle

Leo de Wit leo at philmds.UUCP
Mon Aug 8 21:53:49 AEST 1988


In article <3117 at emory.uucp> riddle at emory.uucp (Larry Riddle) writes:
|The following is a very simple C program compiled and run on a Sun-4
|with no special command line options.
|
|main()
|{
|	float x,y;
|	x = 1.0/10.0;
|	y = 1677721.0/16777216.0; 
|	printf("x: %x",x);
|	printf("%20.17f\n",x);
|	printf("y: %x",y);
|	printf("%20.17f\n",y);
|}
|
|Here is the output:
|
|x: 3fb99999 0.10000000149011612 
|y: 3fb99999 0.09999996423721313
|
|Notice that x and y, which have been declared as floats, and thus have
|a 32 bit representation (according to the manual this obeys IEEE
|floating point arithmetic standards), both are printed the same in hex,
|but give different values when printed as floats. I believe that the
|hex is a straight translation of the internal bit representation. The
|division in computing x and y is done in double precision (64 bits) and
|then converted to floats.
|
|Can anyone enlighten me on why this output comes out this way?

I think I can. On a SUN-3 the same results were achieved. The problem
is that you do not get the internal representation of x and y, but of
x and y converted to double (because that's what is passed to printf).
By coincidence the part of the double that is printed of x and y is
the same (I tried it also on Ultrix were it was _different_).
By using a union that contains a float and a int the following values
for x and y were obtained (writing into the float part and reading
from the int part):
x: 3dcccccd
y: 3dccccc8
which shows both that x and y _have_ different binary representations,
and that the value is quite different from the original one (3fb99999).

All this might also answer the second question in the original article
about the IEEE float representation, simply because the wrong values
were used.

Note that I do not recommend this union kludge; it is however probably
the only way to get to the bit patterns; or else, cast x and y to a
pointer so that their values will not be converted to double
(this is of course not portable because the pointer needs to be the
same size as a float).

Any more Riddles 8-) ?

     Leo.



More information about the Comp.lang.c mailing list