Xref: utzoo comp.lang.c:11753 comp.std.c:251 sci.math:4361 Path: utzoo!attcan!uunet!husc6!cmcl2!nrl-cmf!ames!pasteur!ucbvax!decwrl!labrea!csli!carl From: carl@csli.STANFORD.EDU (Carl Schaefer) Newsgroups: comp.lang.c,comp.std.c,sci.math Subject: Re: Floating point puzzle Keywords: floating point representation Message-ID: <4934@csli.STANFORD.EDU> Date: 8 Aug 88 01:27:35 GMT References: <3117@emory.uucp> Reply-To: carl@csli.stanford.edu (Carl Schaefer) Followup-To: comp.lang.c Organization: Center for the Study of Language and Information, Stanford U. Lines: 66 In article <3117@emory.uucp> riddle@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 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