Floating point puzzle

Carl Schaefer carl at csli.STANFORD.EDU
Mon Aug 8 11:27:35 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?

Floats are converted to doubles when passed as function arguments.
The following inherently nonportable code prints the bit patterns of
your floats as floats and doubles:

#include <stdio.h>

void main()
{
  union {
    double d;
    float f;
    int i[2];
    } X;
  float x, y;

  x = 1.0/10.0;
  y = 1677721.0/16777216.0;
  X.f = x;
  (void) printf("x (float): %8x, %20.17f\n", X.i[0], X.f);
  X.f = y;
  (void) printf("y (float): %8x, %20.17f\n", X.i[0], X.f);
  X.d = x;
  (void) printf("x (double): %8x/%8x, %20.17f\n", X.i[0], X.i[1], X.d);
  X.d = y;
  (void) printf("y (double): %8x/%8x, %20.17f\n", X.i[0], X.i[1], X.d);
  exit(0);
}

produces:

x (float): 3dcccccd,  0.10000000149011612
y (float): 3dccccc8,  0.09999996423721313
x (double): 3fb99999/a0000000,  0.10000000149011612
y (double): 3fb99999/       0,  0.09999996423721313

when run on a sun4, sizeof(int) == sizeof(float) == 4, sizeof(double) == 8



More information about the Comp.std.c mailing list