The problem is that pow
calculates the value not as an integer value (perhaps pow(x, y)
is calculated exp(ln(x)*y)
- but it doesn't HAVE to be exactly that way), but as a floating point value, and it will have a small rounding error. This may be "below" or "above" the correct value, and since conversion from float
to int
is by truncation, 950.999996
gets converted to 950
rather than 951
. You can solve that, in this case, by rounding the result of pow
to the nearest rather than truncating [assuming the result is less than +/-0.5 off from the infinitely precise value].
The way floating point values are calculated is ALWAYS with a degree of precision. Integer calculation is always exact to the least integer value of the calculation itself, but of courwse, the rules of C and C++ is that if one side is floating point, the calculation is performed in floating point.
I would completely eliminate the use of (often troublesome) pow
from the code. A much better way, both for calculating the correct value and speed, is to use a multiplier value that is updated each loop iteration. Something like this:
int imult = 1;
float fmult = 1.0f;
for(int i = number.length()-1; i >=0; i--)
{
valueInt += (number[i]-48) * imult;
imult *= 10;
valueFloat += (number[i]-48) * fmult;
fmult *= 10.0f;
}
[I'm showing both integer and float multiplier, not strictly required, you'd get just as good an answer using imult
in the second loop - but it becomes a floating point value either way, so I thought I'd show both variants]
For the valid range of int
and valid range of float
, this should give a more accurate result. Of course, integer values in float
are restricted to 23 bits before they start getting chopped because of lack of precision available in floating point format. So any value above around 8.3 million will be missing the least significant bit.