C++数学问题和 5/4*pi 与 5*pi/4

C++ mathematical problem and 5/4*pi vs 5*pi/4

本文关键字:pi 问题 C++      更新时间:2023-10-16
#define M_PI acos(-1.0)
int main()
{
double z1 = sin(M_PI / 2 + 3 * x) / (1 - sin(3 * x - M_PI));
double z2 = 1 / tan(5 * M_PI / 4 + 3 * x / 2);  // line 14
double z3 = 1 / tan(5 / 4 * M_PI + 3 * x / 2);  // line 15
printf("%lf, %lf, %lf, z1, z2, z3);
}

正如您在 14 行和 15 行中看到的那样,我们有非常相似的表达式。那么为什么我们会得到不同的结果呢?

5 / 4 * M_PI被分组为(5 / 4) * M_PI5 / 4以整数算术计算,即1

以另一种方式写入它强制将其他系数转换为浮点数。

(最后一点,任何常见的浮点方案(包括IEEE754(都不保证华丽的定义#define M_PI acos(-1.0)在您的平台上浮点类型允许的精度范围内恢复 pi 的数学值。最好写成手写。

这是因为以下两种操作不同:

5 * M_PI / 4

5 / 4 * M_PI

操作从左到右执行。

在第一行,5 * M_PI (int * float( 返回一个浮点数 (15.7...(,该浮点数除以返回浮点数 (3.9...( 的 int (float/int(。

在第二行,5/4 返回等于 1 的 int (int/int(,然后乘以 M_PI (int * float( 返回浮点数,返回正好M_PI (3.14...(

这是不同的结果。

由于/*具有相同的运算符优先级,因此表达式的计算取决于关联性。关联性指示在表达式中应用相同优先级的运算符的顺序。这里的关联性是从左到右的。请参阅运算符优先级表。

因此5 / 4 * M_PI(5 / 4) * M_PI(5 / 4)是整数除法,计算结果为 1。 而5 * M_PI / 4(5 * M_PI) / 4,这会导致浮点除法,因为5 * M_PI是一个浮点值。