📜  C/C++和Java中的浮点运算和结合律

📅  最后修改于: 2020-03-30 03:46:13             🧑  作者: Mango

浮点运算是否遵循结合律?换句话说,对于表达式“(A + B)+ C”和“ A +(B + C)”,我们是否总是得到相同的结果
人们可能期望浮点数在编程语言中遵循数学上的结合律,因此遵循编程语言中的结合律规则。但是,并非在所有情况下都是如此。
考虑下面的C / C++程序。

// C/C++ 展示浮点运算可能不遵守结合律
#include
int main()
{
    // A,B绝对值相同,符号相反
    float A = -500000000;
    float B =  500000000;
    float C = 1;
    printf("A + (B + C)等于 %f \n", A + (B + C));
    printf("(A + B) + C 等于 %f", (A + B) + C);
    return 0;
}

输出:

A + (B + C) 等于 0.000000
(A + B) + C 等于 1.000000

从以上给出的输出中可以明显看出,浮点算法可能并非在每种情况下都遵循结合律。这是由于存储和表示浮点数的格式,在计算过程中它会四舍五入,因此,代数的结合律不一定适用于浮点数。在这种情况下,

以上输出的说明:
A +(B + C):
(B + C)= 500000000.0 + 1.0
        = 500000000.0
(在浮点运算中四舍五入)
A +(B + C)= -500000000.0 + 500000000.0
            = 0.000000
(A + B)+ C:
(A + B)= -500000000.0 + 500000000.0
        = 0.000000
(A + B)+ C = 0.000000 +1
            = 1.000000

Java呢?
我们在Java中获得相同的结果,因为Java对浮点数也使用类似的表示形式。

// Java 展示浮点运算可能不遵守结合律
import java.io.*;
class Main
{
    public static void main (String[] args)
    {
        // A,B绝对值相同,符号相反
        float A = -500000000;
        float B =  500000000;
        float C = 1;
        System.out.println("A + (B + C) 等于 " +
                          (A + (B + C)));
        System.out.println("(A + B) + C 等于 " +
                          ((A + B) + C));
    }
}

输出:

A + (B + C) 等于 0.000000
(A + B) + C 等于 1.000000

整数呢?
现在,当数据类型为整数时,让我们尝试相同的计算。这是一段代码供您观察:

#include
#include
int main()
{
   // A,B绝对值相同,符号相反
   int A = -500000000;
   int B =  500000000;
   int C = 1;
   printf(" A + (B + C) 等于 %d \n", A + (B + C));
   printf("(A + B) + C 等于 %d", (A + B) + C);
   return 0;
}

输出:

 A + (B + C) 等于 1
(A + B) + C 等于 1