tags:

views:

265

answers:

4

I meant to ask: why is the output of the following code 1 million?

If the program runs indefinitely but produces no output, write INFINITE LOOP as the answer to the question. All of the programs compile and run. They may or may not contain serious errors, however. You should assume that int is four bytes. You should assume that float has the equivalent of six decimal digits of precision. You may round your answer off to the nearest power of 10 (e.g., you can say 1,000 instead of 210 (i.e., 1024)).

___1,000,000__________

int main(void) {
  float k = 1;
  while (k != k + 1) {
    k = k + 1;
  }
  printf(“%g”, k); // %g means output a floating point variable in decimal
}
+14  A: 

It doesn't run forever for the simple reason that floating point numbers are not perfect.

At some point, k will become big enough so that adding 1 to it will have no effect.

At that point, k will be equal to k+1 and your loop will exit.

Floating point numbers can be differentiated by a single unit only when they're in a certain range.

As an example, let's say you have an integer type with 3 decimal digits of precision for a positive integer and a single-decimal-digit exponent.

With this, you can represent the numbers 0 through 999 perfectly as 000x100 through 999x100 (since 100 is 1):

What happens when you want to represent 1000? You need to use 100x101. This is still represented perfectly.

However, there is no accurate way to represent 1001 with this scheme, the next number you can represent is 101x101 which is 1010.

So, when you add 1 to 1000, you'll get the closest match which is 1000.

paxdiablo
+6  A: 

The code is using a float variable.

As specified in the question, float has 6 digits of precision, meaning that any digits after the sixth will be inaccurate. Therefore, once you pass a million, the final digit will be inaccurate, so that incrementing it can have no effect.

SLaks
+2  A: 

The output of this program is not specified by the C standard, since the semantics of the float type are not specified. One likely result (what you will get on a platform for which float arithmetic is evaluated in IEEE-754 single precision) is 2^24.

All integers smaller than 2^24 are exactly representable in single precision, so the computation will not stop before that point. The next representable single precision number after 2^24, however, is 2^24 + 2. Since 2^24 + 1 is exactly halfway between that number and 2^24, in the default IEEE-754 rounding mode it rounds to the one whose trailing bit is zero, which is 2^24.

Other likely answers include 2^53 and 2^64. Still other answers are possible. Infinity (the floating-point value) could result on a platform for which the default rounding mode is round up, for example. As others have noted, an infinite loop is also possible on platforms that evaluate floating-point expressions in a wider type (which is the source of all sorts of programmer confusion, but allowed by the C standard).

Stephen Canon
+1  A: 

Actually, on most C compilers, this will run forever (infinite loop), though the precise behavior is implementation defined.

The reason that most compilers will give an infinite loop is that they evaluate all floating point expressions at double precision and only round values back to float (single) precision when storing into a variable. So when the value of k gets to about 2^24, k == k + 1 will still evaluate as false (as a double can hold the value k+1 without rounding), but the k = k + 1 assignment will be a noop, as k+1 needs to be rounded to fit into a float

edit

gcc on x86 gets this infinite loop behavior. Interestingly on x64 it does not, as it uses sse instructions which do the comparison in float precision.

Chris Dodd
Which C compilers did you try this on? I tried on GCC and it halted almost instantly.
Amuck