在C

时间:2019-12-09 13:46:32

标签: c floating-point

我在一次考试中遇到了以下考试问题,如果有人可以帮助解释以下问题,我将不胜感激。

请考虑以下代码:

double a = 1.0, b = 1.0, c = 1.0e-16;
a += c;
a -= c;
b -= c;
b += c;

a和b的值是什么?

A:a和b都等于1:0。

B:a等于1:0,b小于1:0。

C:a小于1:0,b等于1:0。

D:a小于1:0,b小于1:0。

1 个答案:

答案 0 :(得分:5)

首先,C标准未定义浮点数的确切行为和准确性。如果我们假设IEEE-754双精度浮点数,则可以这样说:

DBL_EPSILON(约2.2e-16)定义为1与下一个更大的可表示数字之间的差。这意味着,如果您至少将DBL_EPSILON / 2添加到1.0,则结果将更接近1.0 + DBL_EPSILON,而不是添加到1.0,因此结果将不是1.0。对于您的代码,c小于DBL_EPSILON / 2,因此1.0 + c给出1.0

(注意:我在这里假设舍入模式是四舍五入到最接近的数字,这是大多数实现中的默认值。其他舍入模式可以给出不同的结果)。

当您低于2的幂(例如1.0)时,浮点数的密度加倍。这意味着ε的有效值下降到其值的一半。因此,DBL_EPSILON / 4是从1.0减去后得出不同结果的最小值。由于c > DBL_EPSILON / 41.0 - c给出了不同的结果。

这样做的结果是,a的第一个加法将无效,但减法会改变它,因此最终的值小于1。b将受到以下因素的影响两种操作都等于1.0。

这已由trying it out验证,并给出:

  

a = 0.99999999999999988898 b = 1.00000000000000000000