简体   繁体   English

计算关联是什么意思?

[英]What does computationally associative mean?

K&R's C language has the following sentence: K&R的C语言有如下一句话:

A compiler's license to treat mathematically associative operators as computationally associative is revoked.编译器将数学关联运算符视为计算关联运算符的许可已被撤销。

This is in the Appendix C, which tells what's different from before ANSI C. But I don't know how computationally associated is different from mathematically associated.这在附录 C 中,它说明了与 ANSI C 之前的不同之处。但我不知道计算关联与数学关联有何不同。 Maybe I guess the mathematically associative is a * b * c = (a * b) * c (left), or a * (b * c) (right).也许我猜数学上的关联是a * b * c = (a * b) * c (左)或a * (b * c) (右)。

Consider this code:考虑这段代码:

#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("%g\n", a+b+c);
}

In the C grammar, a+b+c is equivalent to (a+b)+c , so a and b are added first, and then c is added.在C语法中, a+b+c等价于(a+b)+c ,所以先加上ab ,再加c In the format commonly used for double , a+b yields 2 64 , not 2 64 +1, because the double format does not have enough precision to represent 2 64 +1, so the result of the addition is the ideal mathematical result rounded to the nearest representable value, which is 2 64 .double常用的格式中, a+b产生 2 64 ,而不是 2 64 +1,因为double格式没有足够的精度来表示 2 64 +1,所以加法的结果是四舍五入到的理想数学结果最接近的可表示值,即 2 64 Then adding c yields zero, so “0” is printed.然后添加c产生零,所以打印“0”。

If instead we calculated a+c+b , adding a and c would give zero, and then adding b would give one, and “1” would be printed.相反,如果我们计算a+c+b ,将ac将得到零,然后将b相加得到一,并且将打印“1”。

Thus, floating-point operations are not generally associative;因此,浮点运算通常不是关联的; a+b+c is not the same as a+c+b . a+b+ca+c+b不同。

In ordinary mathematics with real numbers, a + b + c is the same as a + c + b ;在实数的普通数学中, a + b + ca + c + b相同; addition of real numbers is associative.实数相加是结合的。

Prior to standardization, some C compilers would treat floating-point expressions as if operators were associative (for those operators whose counterparts in real-number-arithmetic were associative).在标准化之前,一些 C 编译器会将浮点表达式视为运算符是关联的(对于那些在实数算术中对应的运算符是关联的)。 The C standard does not permit that in implementations that conform to the standard. C 标准不允许在符合该标准的实现中这样做。 Conforming compilers must produce results as if the operations were performed in the order specified by the C grammar.符合标准的编译器必须产生结果,就好像操作是按照 C 语法指定的顺序执行的一样。

Some compilers may still treat floating-point operators as associative when operating in non-standard modes, which may be selected by flags or switches passed to the compiler.在非标准模式下运行时,某些编译器可能仍将浮点运算符视为关联运算符,这可能通过传递给编译器的标志或开关来选择。 Also, because the C standard allows implementations to perform floating-point arithmetic with more precision than the nominal type (eg, when computing a+b+c , it can calculate it as if the types were long double instead of double ), that can produce results that are the same as if operations were rearranged, so you can still get results that look like operators have been reordered associatively, depending on the C implementation and the flags used.此外,由于 C 标准允许实现以比标称类型更精确的方式执行浮点运算(例如,在计算a+b+c时,它可以将其计算为long double而不是double ),这可以产生的结果与重新排列操作的结果相同,因此您仍然可以获得看起来像操作符已关联重新排序的结果,具体取决于 C 实现和使用的标志。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM