这两个函数的操作顺序是什么?

4

我在编写一个计算球体体积的函数时遇到了问题,我不知道为什么如果我把4/3 * PI改成PI * 4/3,结果会不同。 如果我加上括号,像(4/3) * PI和PI * (4/3),两种情况下我得到的答案都是错误的。 这是因为在计算顺序中,乘法和除法具有相同的优先级,按照从左到右的顺序进行计算。所以,在没有括号的情况下,4/3 * PI等于(4 / 3)× PI,而PI * 4/3等于(PI × 4)/ 3。这就是为什么会出现不同的结果。

#define PI 3.141592

float Volume(int radius){
      return (4/3 * PI * pow(radius, 3));
}

float Volume(int radius){
      return (PI * 4/3 * pow(radius, 3)); //the good one
}

1
当你将两个整数相除时,你会得到一个带有截断商的整数。 - eesiraed
1
https://dev59.com/hWsz5IYBdhLWcg3w6MXn - MPops
2个回答

6
根据C++标准(5.6乘法运算符):
1. 乘法运算符*、除法运算符/和取模运算符%从左向右分组。
因此,这个表达式:
4/3 * PI 

被评估的方式类似于

( 4/3 ) * PI 

因此,在这个子表达式4 / 3中使用了整数算术,结果等于1

这个表达式

PI * 4/3

也是从左到右进行评估的,就像

( PI * 4 )/3

但在这种情况下,使用的是浮点数算术运算。操作数4被转换为具有双精度类型的变量PI的类型,因为根据通常的算术转换规则,PI的类型为double。然后,轮到操作数3也被转换为双精度类型,因为其左操作数(表达式)( PI * 4 )的类型为double。

在这个表达式中

PI * (4/3)

再次在括号内使用整数算术运算,子表达式的结果是1


2
为了获得正确的结果,请强制答案为浮点数,如下所示:
return 4.0/3 * PI * pow(radius, 3);

此外,*/运算符具有相同的优先级,因此表达式将从左到右进行计算。因此,在4/3周围加括号是正确的,但它会执行整数除法。

如果您想要使用浮点字面量,最好在整个程序中都使用它们:return (4.0/3. * PI * pow(radius, 3.));。大多数现代编译器都能够理解它,但不依赖于它更加明智和清晰。 - Jack Aidley
有趣,我以前从未听说过这个。我大多数时候看到人们将第一个数字变成浮点数,这样整个表达式就会是浮点数。 - Alexander Wu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接