Xref: utzoo comp.lang.c:11761 comp.std.c:255 sci.math:4363 Path: utzoo!attcan!uunet!mcvax!philmds!leo From: leo@philmds.UUCP (Leo de Wit) Newsgroups: comp.lang.c,comp.std.c,sci.math Subject: Re: Floating point puzzle Keywords: floating point representation Message-ID: <578@philmds.UUCP> Date: 8 Aug 88 11:53:49 GMT References: <3117@emory.uucp> Reply-To: leo@philmds.UUCP (Leo de Wit) Organization: Philips I&E DTS Eindhoven Lines: 56 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? 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.