Robert
Robert

Reputation: 178

Compiler calculating mistake

I have this big homework assignment and I got unexpected results, I traced it down to the following code

for (int i = 0; i < 4; i++)
    cout << (int)((7163 / (int) pow (10, 4 - i - 1))) % 10;

to which 7263 appears on the screen, instead of 7163! This does not happen to every 4 digit number and it leaves me confused, is there something wrong with my logic or the compiler's gone nuts. Any ideas how to fix it?

Upvotes: 0

Views: 97

Answers (2)

rici
rici

Reputation: 241721

The problem here is not with the compiler, but rather with the standard library implementation of the pow function.

But it is really not advisable to use (int)(pow(n, k)) to compute nk with two integers.

pow is not guaranteed to produce an exact answer; it may be out by a very small amount. (Actually, its accuracy is not guaranteed at all, but most implementations will try to not be wrong by more than the value of the low order bit of the result.) Since casting to (int) truncates rather than rounds, even a tiny error can result in the result being off by 1. And in this case, if the result of pow(10,2) ends up being 99.999999999999, then converting it to an int will make it 99, and 7163/99 is 72.

So if you insist on using pow, you need to ensure that the result is rounded rather than truncated (see the round standard library function). But it would be better to stick to integer arithmetic. For example:

for (int i = 1000; i > 0; i /= 10)
  std::cout << 7163 / i % 10;

Upvotes: 1

DjScribbles
DjScribbles

Reputation: 118

The problem, as I understand is that the result at i=1 yields a "2" when you would expect a "1".

7163 / (10^2) = 71.63... so it is pretty feasible to assume you are simply treading on a rounding error. How the value calculations are being done will depend on your environment, which you haven't specified, however it seems apparent that the assumptions your code makes about order of operations and data types are incorrect.

A heavy handed approach would be to more strictly cast your types and define your order of operations, leaving nothing to chance:

cout << ((int) (((int) 7163) / ((int) pow (10, 4 - i - 1)))) % 10;

Even still, you may need to incorporate a math library and perform a truncate operation on your division result if the environment insists on providing a floating point result.

Upvotes: 0

Related Questions