[comp.std.c] Is a CAST

heim@tub.UUCP (Heiner Marxen) (07/10/90)

Hello all you C gurus!

Consider the following little C program:
	double	a[] ={ -1.9, -1.1, 1.1, 1.9 };
	main() { int i;
		for(i=0;i<4;++i) printf(" %d", (int)(a[i]));
		printf("\n"); exit(0);
	}
What exactly is its output?

It occurs to me that most C programmers assume that the cast operator
from double to int truncates the value (rounds towards 0), i.e. the above
program is expected to print " -1 -1 1 1".  But, is this behaviour
guaranteed/enforced by the definition of C?  Is an ANSI/pre-ANSI compiler
broken if it makes the above `rounding to nearest' and print " -2 -1 1 2"?
I have several pieces of information (listed below), but I'm just not sure.

 - In the C Reference Manual of BSD4.3 (reprint of K&R of 1978) in section 6.3
   I read ``Conversions of floating values to integral type are rather machine
   dependant.''  I can't find anything else there.

 - With one exception every C compiler I have tried did rounding towards zero.
   Are there any C compilers doing it differently?

 - In ``ANSI C, A Lexical Guide'' from 1988 (based on the draft proposal)
   under `conversions' I read ``When a floating type is converted to an
   integral type, the fractional portion is thrown away.''  IMHO this is
   quite sure a rounding towards zero.  Is this the same in the final standard?
   Is it the only relevant statement?

A similar question applies to integer division.  Consider the C program
	main() { printf("%d %d\n", 4/3, 5/3); }
Is "1 1" its only legal output, or may it print "1 2"?

In order to save net bandwidth I suggest to use e-mail.
If appropriate I will summarize to the net.
Of course, the ultimate answer to all my questions may be posted directly :-)

Heiner Marxen				heiner@specs.UUCP

gwyn@smoke.BRL.MIL (Doug Gwyn) (07/10/90)

In article <1431@tub.UUCP> heim@tub.UUCP (Heiner Marxen) writes:
>It occurs to me that most C programmers assume that the cast operator
>from double to int truncates the value (rounds towards 0), i.e. the above
>program is expected to print " -1 -1 1 1".  But, is this behaviour
>guaranteed/enforced by the definition of C?

The C standard requires that conversion of a floating type to an integer
type discard the fractional part, i.e. truncate toward zero.  Pre-ANSI C
implementations differ in their treatment of such cases.  I even found
one compiler recently that rounded on
	double d = 0.9; long i = d;
but truncated on
	double d = 0.9; long i = (long)d;

>A similar question applies to integer division.  Consider the C program
>	main() { printf("%d %d\n", 4/3, 5/3); }
>Is "1 1" its only legal output, or may it print "1 2"?

Integer division of positive operands has always been defined in C as
truncating toward zero (discarding remainder).  Behavior with negative
operands has deliberately been allowed to vary, in order to permit the
simple use of a hardware-divide instruction in the generated code.
The C standard DOES require that i/j and i%j obey a certain definite
algebraic relationship, though: (i/j)*j+i%j==i.