为什么 Java 对不同括号的分数给出不同的答案
Why does Java give different answers for fractions with different parentheses
我不得不计算这个:1*5000*500/(10000*24645.16239360158)
但后来意识到我应该将它乘以 1000。根据我的操作方式,我会得到 2 个不同的答案。不过,我不确定为什么,因为括号的位置对乘法无关紧要。将不胜感激任何见解!
System.out.println(Double.toString(1000*1*5000*500/(10000*24645.16239360158)));
产出
-7.283243937828597
肯定不正确,因为它是负数
System.out.println(Double.toString(1000*(1*5000*500/(10000*24645.16239360158))));
另一方面,输出
10.143978603480635
(正确)
基本上在第二种情况下,我们在计算结果后将结果乘以 1000,并且以某种方式起作用。
谢谢!
您需要知道 int * int
会产生 int
(5 * 5
)。 int * double
产生 double
(5 * 5.0
).
您可能知道,这些数据类型具有不同的最大大小并以不同的方式存储值。
以下是其中的一些:
您可以使用 Integer.MAX_VALUE
和 Integer.MIN_VALUE
作为精确界限。
如果你需要超过那些值,又想有一个int
,你应该使用classBigInteger
。它可以处理任意大 integers
。
否则你将得到所谓的 overflow
,当你执行 Integer.MAX_VALUE + 1
时,结果将是 Integer.MIN_VALUE
。如果您还记得这个数字是如何以字节为单位存储的,例如 111
那么 +1
会 return 1000
但是没有地方可以存储第一个 1
,您将收到 000
,即 MIN_VALUE
。
您还应该知道,当您计算 5 / 2
时,它不会 return 2.5
而是 2
,因为您除以两个 int
,结果也将是 int
。如果你想要 double
,那么你需要做这样的事情 5 / 2.0
或 (5 + 0.0) / 2
.
任何表达式的计算都是由运算符优先级解析器完成的。如果你想改变优先级的优先级,你将不得不使用括号。
在第一种情况下'/'和'*'具有相同的优先级table。
在第二种情况下,“*”的优先级高于“/”。这就是为什么你得到不同的值作为输出。
这个表达式1000*1*5000*500/(10000*24645.16239360158),先计算1000*1*5000*500,结果为-1794967296,溢出.
这个表达式 1000*(1*5000*500/(10000*24645.16239360158)) 溢出没有发生。
是因为Java的隐式类型转换。默认情况下 Java 将使用 int。正如 user2357112 评论的那样,这个数字对于 int 来说太大了。
如果你想让你的第一个版本工作,添加一个 "d" 来告诉 Java 使用双精度。
双d = 1000d*1*5000*500/(10000*24645.16239360158)
System.out.println(d);
你会得到:
10.143978603480635
我不得不计算这个:1*5000*500/(10000*24645.16239360158)
但后来意识到我应该将它乘以 1000。根据我的操作方式,我会得到 2 个不同的答案。不过,我不确定为什么,因为括号的位置对乘法无关紧要。将不胜感激任何见解!
System.out.println(Double.toString(1000*1*5000*500/(10000*24645.16239360158)));
产出
-7.283243937828597
肯定不正确,因为它是负数
System.out.println(Double.toString(1000*(1*5000*500/(10000*24645.16239360158))));
另一方面,输出
10.143978603480635
(正确)
基本上在第二种情况下,我们在计算结果后将结果乘以 1000,并且以某种方式起作用。
谢谢!
您需要知道 int * int
会产生 int
(5 * 5
)。 int * double
产生 double
(5 * 5.0
).
您可能知道,这些数据类型具有不同的最大大小并以不同的方式存储值。
以下是其中的一些:
您可以使用 Integer.MAX_VALUE
和 Integer.MIN_VALUE
作为精确界限。
如果你需要超过那些值,又想有一个int
,你应该使用classBigInteger
。它可以处理任意大 integers
。
否则你将得到所谓的 overflow
,当你执行 Integer.MAX_VALUE + 1
时,结果将是 Integer.MIN_VALUE
。如果您还记得这个数字是如何以字节为单位存储的,例如 111
那么 +1
会 return 1000
但是没有地方可以存储第一个 1
,您将收到 000
,即 MIN_VALUE
。
您还应该知道,当您计算 5 / 2
时,它不会 return 2.5
而是 2
,因为您除以两个 int
,结果也将是 int
。如果你想要 double
,那么你需要做这样的事情 5 / 2.0
或 (5 + 0.0) / 2
.
任何表达式的计算都是由运算符优先级解析器完成的。如果你想改变优先级的优先级,你将不得不使用括号。
在第一种情况下'/'和'*'具有相同的优先级table。
在第二种情况下,“*”的优先级高于“/”。这就是为什么你得到不同的值作为输出。
这个表达式1000*1*5000*500/(10000*24645.16239360158),先计算1000*1*5000*500,结果为-1794967296,溢出.
这个表达式 1000*(1*5000*500/(10000*24645.16239360158)) 溢出没有发生。
是因为Java的隐式类型转换。默认情况下 Java 将使用 int。正如 user2357112 评论的那样,这个数字对于 int 来说太大了。
如果你想让你的第一个版本工作,添加一个 "d" 来告诉 Java 使用双精度。
双d = 1000d*1*5000*500/(10000*24645.16239360158) System.out.println(d);
你会得到: 10.143978603480635