Wikipedia about "guard bits"提供了一个代码示例:
#include <stdio.h>
int main(){
double a;
int i;
a = 0.2;
a += 0.1;
a -= 0.3;
for (i = 0; a < 1.0; i++)
a += a;
printf("i=%d, a=%f\n", i, a);
return 0;
}
使用我的zen2R7 4800hCPU,我用gcc Guard_digit.c -std=c17 -march=znver2 -pedantic -O0 -o With_Guard_digit.o
编译了上面的源代码.然后,它的输出结果与维基百科i=54, a=1.000000
相同.
正如这个note所说,IEEE标准已经实现了保护数字:
IEEE标准要求使用3个额外的较低有效位 比单精度中隐含的24位(尾数) 代表权.
尾数格式加上额外的位:
1.XXXXXXXXXXXXXXXXXXXXXXX 0 0 0 ^ ^ ^ ^ ^ | | | | | | | | | - sticky bit (s) | | | - round bit (r) | | - guard bit (g) | - 23 bit mantissa from a representation - hidden bit
问:有没有一种方法可以通过更改源代码或其他代码来解决这个精度和舍入问题(即误差偏移量可以达到一定程度,以便输出类似i=108, a=1.000000
的结果)?
查看Eric Postpischil的答案后编辑:
很抱歉没有清楚地描述这个问题.我想知道如何通过保留原始计算来解决舍入问题,这样直接a = 0;
就不考虑在内了.
我想解决这个具体的问题,但不是一般的问题.正如comment说的那样,这超出了我目前的范围.