Reputation: 2124
If I run the following:
int tokenIdx=ERROR; //ERROR=8
tokens[tokenIdx] = 57; //tokens is of type int[]
int totalTokens = 100;
int percent = (int)((100.0 * tokens[tokenIdx])/(float)totalTokens);
printf("%d%\n",percent);
int percent2 = (int)(100.0*(tokens[tokenIdx]/(1.0*totalTokens)));
printf("%d%\n",percent2);
the output is:
57%
56%
Why is this happening?
Upvotes: 1
Views: 388
Reputation: 49179
Floating point rounding error. In your first case, you're doing a double divided by a float, in the second, it's a double divided by a double. The int conversion is throwing away the fractional portion, which in the second case is probably .999999999998 or something like it.
Lessons learned: floating point isn't precise, mind your conversions, watch your types
If you really honestly want an integer percentage, do:
int percent = 100 * value / total;
where value
and total
are both ints.
If you need more precision (say 10ths), consider doing it in thousands or and dividing down to float:
float percent = (1000 * value / total) / 10f;
Provided that 1000 * value won't overflow in your problem domain.
Upvotes: 0
Reputation: 241691
Because 5700.0 and 100.0 can both be represented exactly as floating point numbers, and their ratio is exactly 57.0. On the other hand, 57.0/100.0 cannot be represented exactly as a floating pointer number, and multiplying it by 100.0 will not produced exactly 57.0. If it produces slightly less than 57.0 (as seems to be the case), then casting to (int)
, which truncates, will result in the integer 56.
Upvotes: 3