barkley@unc.cs.unc.edu (Matthew Barkley) (08/18/88)
In trying out the problem program from the "floating point puzzle" posting,
I came across some strange behavior in trying to make the program more con-
cise. Here's what I ran and what I got:
/* Puzzling floating-point program */
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);
printf("\n");
printf("x: %x %20.17f\n",x,x);
printf("y: %x %20.17f\n",y,y);
}
/* Here is the output: (from VAX 11/780) */
/* x: cccd3ecc 0.10000000149011612 */
/* y: ccc83ecc 0.09999996423721313 */
/* x: cccd3ecc 0.00000000000000000 */
/* y: ccc83ecc 0.00000000000000000 */
So, please gurus, tell me where the bug (if any) is. Is it unreasonable to
expect the 2 sets of output to be the same? (BTW, the results are more bizarre
if x and y are of type double.)
Matt Barkley barkley@unc.cs.unc.edu
Any opinions expressed are not necessarily shared by anyone else, and may
not even be my own. How an organization can have an opinion is beyond me.braner@batcomputer.tn.cornell.edu (braner) (08/19/88)
[]
The new FP puzzling output is due to the fact that (old) C does not check
the type of parameters passed to functions, and the function takes the
parameters off the stack _assuming_ what their types are and therefore
how many bytes they occupy on the stack. Thus, when printf() sees a "%x"
it takes sizeof(int) (usually 4) bytes off the stack. In the case
printf ("%x %f", f, g) where f,g are floats, the "%f" _could_ get g
correctly _if_ sizeof(int)==sizeof(float) (usually true) and _if_
a float is actually passed (usually false: f,g are converted to doubles
before passing). What actually happened was that the "%x" took the first
4 bytes of ((double) f) off the stack, and the "%f" took the latter 4 bytes
of ((double) f) plus the first 4 bytes of ((double) g). The "%f" saw
a 0 in what it interpreted as the exponent field (really the mantissa tail
attached to 'f' when converting it to double) and concluded that the second
parameter is a 0. The results would have been different (but still garbage)
in a machine with the opposite word ordering in a double, where the first
word is the less significant part of the mantissa.
- Moshe Braner
Message for nitpickers: I did not mean to imply that _all_ C compilers
pass function parameters on the stack, nor that _all_ machines _have_ a
stack at all!