[net.unix] Query about C Floating Point Standar

rpw3@fortune.UUCP (12/17/83)

#R:dual:-16600:fortune:26900003:000:4136
fortune!rpw3    Dec 16 22:49:00 1983

[C fl. pt. in 'double'...]

	+--------
	| 1) Can someone quote chapter and verse of K&R for me?
	| 	I can't find it.
	+--------

All ref's are to K & R, "The C Programming Language", Prentice-Hall 1978.

> [p.184, para 6.2]
> "All floating arithmetic in C is carried out in double precision; ..."

> [p.184, para 6.6]
> "First, any operands of type char or short are converted to int, and
> any of float are converted to double.  Then, if either operand is
> double, the other is converted to double and that is the type of the
> result..."

	+--------
	| 2) Why, oh, why was it done this way?
	+--------

> [p.185, para 7.]
> "...otherwise the order of evaluation of expressions is undefined.
> In particular the compiler considers itself free to compute
> subexpressions in the order it believes most efficient, even if the
> subexpressions involve side effects. The order in which side effects
> take place is undefined.  Expressions involving a commutative and
> associative operator (*, +, &, |, ^) may be rearranged arbitrarily,
> even in the presence of parentheses; to force a particular order of
> evaluation an explicit temporary must be used..."

So it would seem that the compiler is not smart enough to maintain
more than two "types" of intermediate expressions: int & double. And
given the rearrangement rules (which I agree with, BTW), the compiler
would have to be quite smart indeed (maybe even as smart as FORTRAN!)
to make sure that significance was not lost due to a rearrangement.

For example, suppose on your machine single precision has 4 digits
of precision and double has 8 (just to keep it simple). Then the
following program:

	double x = 1234.5678;
	double y = 1234.5678;
	float  z = 1234.0;
	float  w = 1234.0;
	double q;

	q = x - (y - z) + w;

might or might not give q = 0.0, 1.0, 2.0, or other answers, depending
on the exact order and pairing of the adds and subtracts, UNLESS all
the intermediate values are widened (coerced) to the "higher" of the
two types. In that case, you always get q = 0.0 as an answer. (In case
you think this is silly, notice that a smart compiler, like a good
FORTRAN, might notice that it already had (float)(y - z) in another
register somewhere and want to use it.)

"C" justs gets a little paranoid/lazy and coerces everything to double
up front, and then forgets about the details. After all, I don't think
K&R were numerical analysts worrying about huge FORTRAN programs and
multiple CPU megasecs. (A megasec is about 11.5 days. I have run IBM
1620 "number cruncher" programs that long. We replaced the machine with
a PDP-10 the next year and the time went down to a few hours.)

While it would be possible to produce a compiler which did only and
exactly the arithmetic it needed to produce the semantics given in K&R
while minimizing the complexity of said arithmetic (e.g. only do 'char'
adds if you cannot tell from the result that we didn't use 'int'), the
internal data of the compiler would have to be extended a bit, and I am
not sure (not being a C compiler person, my forte was BLISS) that the
structure even allows for that level of detail. (The BLISS compilers
did.)

"C" also performs the same coercions on arguments to routines:

> [p.186, 1/2 way down]
> "Any actual arguments of type float are converted to double before
> the call; any of type char or short are converted to int; and as
> usual, array names are converted to pointers. No other conversions
> are performed automatically; in particular, the compiler does not
> compare the types of actual arguments with those of formal
> arguments."[!!!]

This last sentence reveals that C is definitely NOT strongly typed!
A more generous explanation is that the rule given minimizes the number
of stack types the compiler has to handle, and simplifies portablility
by allowing stack allocation to be multiples of "int" [assuming that
sizeof(float) and sizeof(double) are multiples of sizeof(int)].

Hope all this wind has helped.

Rob Warnock

UUCP:	{sri-unix,amd70,hpda,harpo,ihnp4,allegra}!fortune!rpw3
DDD:	(415)595-8444
USPS:	Fortune Systems Corp, 101 Twin Dolphins Drive, Redwood City, CA 94065