Reputation: 356
#include <stdio.h>
/* print Fahrenheit-Celsius table
for fahr = 0, 20, ..., 300 */
main()
{
int fahr, celsius;
int lower, upper, step;
lower = 0;
upper = 300;
step = 20;
fahr = lower;
while (fahr <= upper) {
celsius = 5 * (fahr-32) / 9;
printf("%d\t%d\n", fahr, celsius);
fahr = fahr + step;
}
}
based on the above code I can't understand how you get the below result on the first line. Shouldn't it be 0 -17
? This example is on page 17 of the C programming language. I just want to make sure this isn't something to do with older implementations of C, and I'm not getting the same result as the book because I'm using a more current compiler.
1 -17
20 -6
40 4
60 15
80 26
100 37
120 48
140 60
160 71
180 82
200 93
220 104
240 115
260 126
280 137
300 148
Upvotes: 3
Views: 358
Reputation: 140826
Indeed, on the first time through the while loop, fahr
has the value 0, and that is what will be printed. This is probably a typo in your edition of the book: we have multiple reports in the comments that other editions have 0 where yours has 1.
You are right to be concerned about old C code behaving differently with newer compilers. However, this program does not have any of the things in it that usually cause problems with newer compilers: no pointer aliasing, no concurrency, no arithmetic overflow, etc. The computation of the first two values of the celsius
column does involve integer division with a negative dividend, which was partially implementation-defined prior to C1999; if the book had given -18
and -7
for those values, that would have been why. And modern compilers will issue a warning about the missing return type of main
, but that doesn't affect the semantics of the program. (I'm not aware of any modern C compiler that actually issues an error for "implicit int", either in its default mode or in its "strictly conforming to C2011" mode. There's usually a way to tell it to make that particular warning into an error, of course.) None of these issues could have have caused the first value of fahr
to be printed as 1.
Please learn from this that you should trust your ability to mentally simulate the execution of a program a little more, but printed books a little less. You would also be well-advised to get a newer C textbook—not just a newer edition of K&R, but an entirely new book, that covers the modern language. I regret to say I don't have any recommendations, though.
Upvotes: 4
Reputation: 214880
K&R was written when dinosaurs walked the earth. On pre-standard C and C90, the rounding direction of negative integer division was not well-defined. So you could get different results depending on compiler, it was implementation-defined behavior back in the days. I'm not sure if K&R were even aware of the issue - the book is filled to the brim with reliance on poorly-specified behavior.
This bug in the C language was not fixed until the year 1999, some 20 years after the book was written.
See What is the behavior of integer division?, the answer by schot in particular.
Also see the C99 rationale 6.5.5
In C89, division of integers involving negative operands could round upward or downward in an implementation-defined manner; the intent was to avoid incurring overhead in run-time code to check for special cases and enforce specific behavior. In Fortran, however, the result will always truncate toward zero, and the overhead seems to be acceptable to the numeric programming community. Therefore, C99 now requires similar behavior, which should facilitate porting of code from Fortran to C. The table in §7.20.6.2 of this document illustrates the required semantics.
Upvotes: 0