有人可以向我解释为什么以下代码的结果不同?提前致谢。所有变量都是双倍的。
首先:
volume=(4/3)*(Math.PI*Math.pow(raio,3))
如果我声明raio = 5,结果将是= 392,xxx
如果符合以下条件,结果也是392
volume=(Math.PI*Math.pow(raio,3))*(4/3);
第二
volume=(Math.PI*Math.pow(raio,3))*4/3;
如果我声明raio = 5,结果现在是正确的:523,xxx
答案 0 :(得分:4)
这是因为当你使用时:
volume=(Math.PI*Math.pow(raio,3))*(4/3);
将(4/3)评估为整数除法,因此(4/3)= 1。
因此,
volume=(Math.PI*Math.pow(raio,3))*4/3;
会起作用,因为它是一个双* 4,这是一个双倍,然后除以3,这也是一个双倍。
如果您尝试这样做:
volume=(Math.PI*Math.pow(raio,3))*(4.0/3.0);
你应该看到它有效。
请注意,您可能只能使用4.0 / 3或只需4 / 3.0。
答案 1 :(得分:1)
(pi * raio^3)*(4/3) != (pi * raio^3)*4 / 3.
在第二个中,它乘以4,然后除以3.在第一个中,它乘以(4/3)
更不用说4和3不是双打
答案 2 :(得分:1)
在第一次计算中,你有效地运行1 *(Math.PI * Math.pow(raio,3)),因为4/3在整数中完成并在第二次计算中计算为1.第一个参数被计算为double,导致表达式的其余部分被计算为double。尝试运行(4.0 / 3.0)*(Math.PI * Math.pow(raio,3))
答案 3 :(得分:1)
在您的第一个案例中,(4/3) returns an int which is 1;
使用MathExpression*(4.0/3.0);
答案 4 :(得分:1)
Math.PIS定义为double PI = 3.141592653589793;
当您执行任何一个变量为double的操作时,另一个变量将自动提升为double。两个例子的不同之处在于第4/3段。
当在括号中使用时,它被视为int并且结果为1,而在另一个示例中,4被乘以double值以得到double,然后得到3得到1.333333。< / p>
总结:volume=(Math.PI*Math.pow(raio,3))*(4/3);
评估为
volume = (392.6990816987241)*(4/3)
volume = (392.6990816987241) * (1) //<--int division
volume = 392.6990816987241
而volume=(Math.PI*Math.pow(raio,3))*4/3;
被评估为
volume = (392.6990816987241) *4/3
volume = 1570.7963267948965/3 //division of double by int
volume = 523.5987755982989
如果您注意到,第二个结果是1.33333
次第一次结果。
如果在第一个示例中,如果将一个参数更改为double,例如4.0或3.0或两者即。
volume=(Math.PI*Math.pow(raio,3))*(4.0/3)
or volume=(Math.PI*Math.pow(raio,3))*(4/3.0)
or volume=(Math.PI*Math.pow(raio,3))*(4.0/3.0)
您将获得与示例2中相同的结果。
希望这有帮助。
答案 5 :(得分:1)
首先,查看此优先级表:http://www.seas.upenn.edu/~palsetia/java/precedenceTable.html
优先级决定在其他表达式之前将哪个表达式解析为值。在您给出的第一个和第二个例子中:
4/3
的大括号将自行解决后面的分部产生1
,因为两个int
eger文字的分割导致int
eger类型不能代表小数。在第一个和第二个例子的计算中,这些小数都会丢失。
与此相反,最后一个表达式从左到右解析。大括号不会影响计算的顺序,因为它们包含了第一个表达式,无论如何它首先会被解析。第一个大括号会生成double
类型,然后与int
4
相乘。这里发生的事情称为implicit conversion
这实际上是一种特殊形式的隐式转换,称为类型促销。为了合并int
和double
,Java首先升级 int
到double
以使类型兼容。在某种程度上,double
可以被视为比int
更通用的类型。当前一次计算的结果除以int
3
时,会发生同样的情况。
因为隐式转换发生在划分任何int
eger值之前,所以保留4/3
的小数,导致另一个结果,而不是前两个示例。在这些示例中,您可以使用显式转化来获得所需的结果:
(double) 4/3
请注意,显式转换 - 看起来像类型转换的语句 - 具有比除法更高的优先级,即4
将首先转换为double
,然后将此除数除以{ {1}}在将此数字另一个隐式转换为3
类型之前的内容。当然,您也可以使用双字double
而不是显式转换,并观察相同的结果。
PS:第二个和第一个例子还包含4d
结果的隐式转换,当它与包含pi的另一个括号的结果相乘时。此时,小数已经丢失。