给出以下任意值的浮点变量,用c / c ++。
float a, b, c, d;
在以下陈述中,我们可以假设它们中的任何一对总是会产生相同的结果吗?
float result_1 = a + b + c + d - c;
float result_2= a + b + c + (d - c);
float result_3 = a + b + d;
此外,对后续谓词是否有任何保证:
a + b - b == a
答案 0 :(得分:4)
不,你不能假设这一点。我打破了你的所有三个例子:(Live)
#include <iostream>
int main()
{
double a = 1, b = 1e100, c= 1e100, d= 1, c2 = .1, d2 = -.1, b2 = 1;
std::cout << ( a + b2 + c2 + d2 - c2 == a + b2 + c2 + (d2 - c2)) << "\n"
<< ( a + b2 + c + d - c == a + b2 + d) << "\n"
<< ( a == a + b -b);
}
输出:
0 0 0
==
和!=
在浮点类型上始终不安全,因为它有舍入错误。
答案 1 :(得分:0)
首先,我们在计算机上说明关于浮点数的标准警告。它们本质上是不精确的。没有办法在二进制文件中准确地说".1"
。所以,任何一个可能会给你一个错误的&#34;回答。但是,一般来说,他们应该给你同样错误的答案。
一般来说,乘法和除法的变化多于加法和减法。并且,在同一计算中处理非常大的数字和非常小的数字时,你会遇到麻烦。
[更新]下一句话错了。忽略它:
但是,据我所知,在这个极限情境中,似乎一切都正确平衡,所以虽然我不能断然说出来,但我认为你在这里安全。
答案 2 :(得分:0)
如果我运行以下代码:
#include <stdio.h>
int main(int argc, char* argv[])
{
float a = 0.1;
float b = 0.2;
float c = 0.3;
float d = 0.4;
float result1 = a + b + c + d - c;
float result2 = a + b + c + (d - c);
float result3 = a + b + d;
printf("result1 == result2: %s\n", result1 == result2 ? "Yes" : "No");
printf("result2 == result3: %s\n", result2 == result3 ? "Yes" : "No");
printf("result1 == result3: %s\n\n", result1 == result3 ? "Yes" : "No");
printf("result1: %30.20f\n", result1);
printf("result2: %30.20f\n", result2);
printf("result3: %30.20f\n\n", result3);
printf("a + b: %30.20f\n", a + b);
printf("a + b + c: %30.20f\n", a + b + c);
printf("a + b + c + d: %30.20f\n", a + b + c + d);
printf("d - c: %30.20f\n", d - c);
printf("a + b + c + d - c: %30.20f\n", a + b + c + d - c);
printf("a + b + c + (d - c): %30.20f\n", a + b + c + (d - c));
printf("a + b + d: %30.20f\n", a + b + d);
return 0;
}
我得到以下输出,显示主要问题的答案是否:
result1 == result2: No
result2 == result3: Yes
result1 == result3: No
result1: 0.69999998807907104492
result2: 0.70000004768371582031
result3: 0.70000004768371582031
a + b: 0.30000001192092895508
a + b + c: 0.60000002384185791016
a + b + c + d: 1.00000000000000000000
d - c: 0.09999999403953552246
a + b + c + d - c: 0.69999998807907104492
a + b + c + (d - c): 0.70000004768371582031
a + b + d: 0.70000004768371582031
编译器:Apple LLVM 5.1(clang)。
我得到了相同的结果,但没有使用我试过的另一个编译器。最后一个使用32位代码的x86 FPU。另外两个以64位模式运行并使用SSE2,AFAIK。