Reputation: 102
Here is my code :
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n, i, num, m, k = 0;
cout << "Enter a number :\n";
cin >> num;
n = log10(num);
while (n > 0) {
i = pow(10, n);
m = num / i;
k = k + pow(m, 3);
num = num % i;
--n;
cout << m << endl;
cout << num << endl;
}
k = k + pow(num, 3);
return 0;
}
When I input 111
it gives me this
1
12
1
2
I am using codeblocks. I don't know what is wrong.
Upvotes: 0
Views: 2477
Reputation:
pow
does floating-point exponentiation.
Floating point functions and operations are inexact, you cannot ever rely on them to give you the exact value that they would appear to compute, unless you are an expert on the fine details of IEEE floating point representations and the guarantees given by your library functions.
(and furthermore, floating-point numbers might even be incapable of representing the integers you want exactly)
This is particularly problematic when you convert the result to an integer, because the result is truncated to zero: int x = 0.999999;
sets x == 0
, not x == 1
. Even the tiniest error in the wrong direction completely spoils the result.
You could round to the nearest integer, but that has problems too; e.g. with sufficiently large numbers, your floating point numbers might not have enough precision to be near the result you want. Or if you do enough operations (or unstable operations) with the floating point numbers, the errors can accumulate to the point you get the wrong nearest integer.
If you want to do exact, integer arithmetic, then you should use functions that do so. e.g. write your own ipow
function that computes integer exponentiation without any floating-point operations at all.
Upvotes: 0
Reputation: 5321
Whenever I use pow expecting an integer result, I add .5 so I use (int)(pow(10,m)+.5)
instead of letting the compiler automatically convert pow(10,m)
to an int.
I have read many places telling me others have done exhaustive tests of some of the situations in which I add that .5
and found zero cases where it makes a difference. But accurately identifying the conditions in which it isn't needed can be quite hard. Using it when it isn't needed does no real harm.
If it makes a difference, it is a difference you want. If it doesn't make a difference, it had a tiny cost.
In the posted code, I would adjust every call to pow
that way, not just the one I used as an example.
There is no equally easy fix for your use of log10
, but it may be subject to the same problem. Since you expect a non integer answer and want that non integer answer truncated down to an integer, adding .5 would be very wrong. So you may need to find some more complicated work around for the fundamental problem of working with floating point. I'm not certain, but assuming 32-bit integers, I think adding 1e-10
to the result of log10
before converting to int
is both never enough to change log10(10^n-1)
into log10(10^n)
but always enough to correct the error that might have done the reverse.
Upvotes: 3