简体   繁体   中英

Same Calculation, different result?

My goal is to calculate how many percent counter out of cap is. Now I ran over a problem, I can't find the difference between the two formulas below, as far as my mathematical understanding tells me, it's exactly the same calculation. But only the first one works, brackets make no difference.

int i = counter * 100 / cap; //works
int i = counter / cap * 100; //doesn't work

Has this got something to do with java or is it just me who's made a horrible thinking mistake?

It is not the same calculation, since you are handling integer arithmetics , which does not have Multiplicative inverse number for all numbers (only 1 has it).

In integer arithmetics, for example, 1/2 == 0 , and not 0.5 - as it is in real numbers arithmetics. This will of course cause later on inconsistency when multiplying.

As already mentioned - the root of this is the fact that integer arithmetics does not behave like real numbers arithmetics, and in particular, the divide operator is not defined as a/b == a*b^-1 , since b^-1 is not even defined in integer arithmetics to all numbers but 1.

Your mistake is assuming that these are just pure, abstract numbers. I assume that counter is an int ... so the second version is evaluated as:

int tmp = counter / cap;
int i = tmp * 100;

Now we're dealing with integer arithmetic here - so if counter is in the range [-99, 99] for example, tmp will be 0.

Note that even your first version may not work, either - if counter is very large, multiplying it by 100 may overflow the bounds of int , leading to a negative result. Still, that's probably your best approach if counter is expected to be in a more reasonable range.

Even with floating point arithmetic, you still don't get the behaviour of "pure" numbers, of course - there are still limits both in terms of range and precision.

First case

int i = counter * 100 / cap;

is evaluated like

(counter * 100) / cap;

The second case

int i = counter / cap * 100; 

is evluated like this

(counter / cap) * 100

Hence different results

In Java, operators * and / have the same precedence, so the expressions are evaluated sequentially. Ie

  1. counter * 100 / cap --> (counter * 100) / cap
  2. counter / cap * 100 --> (counter / cap) * 100

So for values eg counter = 5, cap = 25 (expecting count and cap to be both int variables), the evaluation is in the first case: 5 * 100 = 500, then 500 / 25 = 20

In the second case, the evaluation is: 5 / 25 = 0 (integer math!), then 0 * 100 = 0.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM