同样的计算,不同的结果?

Same Calculation, different result?

我的目标是计算 cap 的百分比 counter 是多少。 现在我 运行 解决了一个问题,我找不到下面两个公式之间的区别,据我的数学理解告诉我,它们是完全相同的计算。但只有第一个有效,括号没有区别。

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

这与 java 有什么关系还是只有我犯了一个可怕的思维错误?

这不是同一个计算,因为您处理的是 整数运算 ,它没有 Multiplicative inverse number 用于所有数字(只有 1 个有)。

在整数运算中,例如 1/2 == 0,而不是 0.5 - 因为它在实数运算中。这当然会导致以后相乘时的不一致。

如前所述 - 其根源在于整数运算不像实数运算,特别是除法运算符未定义为 a/b == a*b^-1,因为 b^-1在整数算术中甚至没有定义除 1 以外的所有数字。

你的错误是假设这些只是纯粹的抽象数字。我假设 counter 是一个 int... 所以第二个版本被评估为:

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

现在我们在这里处理 整数运算 - 所以如果 counter 在 [-99, 99] 范围内,例如 tmp将为 0。

请注意,即使您的第一个版本也可能无法运行 - 如果 counter 非常大,将其乘以 100 可能会溢出 int 的边界,从而导致负结果。尽管如此,如果预计 counter 处于更合理的范围内,这可能是您的最佳方法。

即使使用浮点运算,您仍然无法获得 "pure" 数字的行为,当然 - 在范围和精度方面仍然存在限制。

第一个案例

int i = counter * 100 / cap;

被评价为

(counter * 100) / cap;

第二种情况

int i = counter / cap * 100; 

是这样评价的

(counter / cap) * 100

因此结果不同

在Java中,运算符*和/具有相同的优先级,所以表达式是按顺序求值的。 IE。

  1. counter * 100 / cap --> (counter * 100) / cap
  2. 计数器/上限 * 100 --> (计数器/上限) * 100

因此对于值,例如counter = 5, cap = 25(期望count和cap都是int变量),第一种情况下求值:5 * 100 = 500,则500 / 25 = 20

在第二种情况下,评估是:5 / 25 = 0(整数数学!),然后 0 * 100 = 0。