Floating point puzzle

Mark Hall markhall at pyramid.pyramid.com
Tue Aug 9 02:21:16 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.

The use of the float as an expression (in this case, as the
arguments to printf) is always converted to a double.  For
example, witness the assembly generated on the pyramid:

        movw    $0x3dcccccd,lr0
        movw    $0x3dccccc8,lr1		#note the diff here in last 3 bits.
        cvtfd   lr0,tr1			#here's the conversion
        movw    $"x: %x",tr0
        call    _printf

Since exponents in double take up more bits than floats,
you may lose any difference in the mantissas with the call
to printf. Try putting printf("x: %x %x",x) and comparing
the bit patterns for your machine then. On the pyramid, they
turn out to be:

x: 3fb99999 a0000000 0.10000000149011611 #close to the sun output, eh?
y: 3fb99999 00000000 0.09999996423721313

hence the difference when you print out the float.  I leave it as
an exercise (mostly cuz of the flames for non-portable code) 
as to how you can print out the bits without converting to 
floating point.

-Mark Hall (smart mailer): markhall at pyramid.pyramid.com
	   (uucp paths  ): 
		{amdahl|decwrl|sun|seismo|lll-lcc}!pyramid!markhall



More information about the Comp.lang.c mailing list