Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top