C语言 计算结合是什么意思?



K&R的C语言有以下句子:

编译器将数学关联操作符视为计算关联操作符的许可被吊销。

这是在附录C中,它告诉我们与ANSI C之前有什么不同。但是我不知道计算关联与数学关联有什么不同。也许我猜数学上的结合法是a * b * c = (a * b) * c(左),或者a * (b * c)(右)。

考虑以下代码:

#include <stdio.h>
int main(void)
{
double a = 0x1p64;  //  Two the power of 64, 18,446,744,073,709,551,616.
double b = 1;
double c = -a;
printf("%gn", a+b+c);
}

在C语法中,a+b+c等价于(a+b)+c,所以先添加ab,再添加c。在double通常使用的格式中,a+b的结果是264,而不是264+1,因为double格式没有足够的精度来表示264+1,所以加法的结果是理想的数学结果,四舍五入到最接近的可表示值,即264。然后加上c得到0,因此输出" 0 "。

如果我们计算a+c+b,将ac相加将得到0,然后将b相加将得到1,并且将打印" 1 "。

因此,浮点操作通常不是关联的;a+b+ca+c+b不一样

在普通实数数学中,a+b+c等于a+c+b;实数的加法是结合法

在标准化之前,一些C编译器会将浮点表达式视为关联运算符(对于那些实数算术中的对应运算符是关联运算符的操作符)。C标准不允许在符合标准的实现中这样做。符合标准的编译器产生的结果必须与操作按照C语法指定的顺序执行一样。

在非标准模式下操作时,一些编译器可能仍然将浮点操作符视为关联操作符,非标准模式可以通过传递给编译器的标志或开关来选择。此外,由于C标准允许实现以比标称类型更高的精度执行浮点运算(例如,当计算a+b+c时,它可以像计算long double而不是double一样计算它),这可以产生与重新排列操作相同的结果,因此您仍然可以得到看起来像操作符已经关联重新排序的结果,这取决于C实现和使用的标志。

相关内容

  • 没有找到相关文章

最新更新