同样的计算,不同的结果?
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。
- counter * 100 / cap --> (counter * 100) / cap
- 计数器/上限 * 100 --> (计数器/上限) * 100
因此对于值,例如counter = 5, cap = 25(期望count和cap都是int变量),第一种情况下求值:5 * 100 = 500,则500 / 25 = 20
在第二种情况下,评估是:5 / 25 = 0(整数数学!),然后 0 * 100 = 0。
我的目标是计算 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。
- counter * 100 / cap --> (counter * 100) / cap
- 计数器/上限 * 100 --> (计数器/上限) * 100
因此对于值,例如counter = 5, cap = 25(期望count和cap都是int变量),第一种情况下求值:5 * 100 = 500,则500 / 25 = 20
在第二种情况下,评估是:5 / 25 = 0(整数数学!),然后 0 * 100 = 0。