符号是否影响浮点数精度与准确性?相关断言是否恒成立?
浮点数符号与运算一致性问题
x86/x64平台上的C/C++默认采用IEEE 754双精度浮点数标准(对应double类型),以下分析均基于该标准展开:
第一个代码片段的断言是否成立?
代码示例:
double a = 1.0/3.0; double b = -1.0/3.0; double x = a*a/Math::Pi; double y = -(-b*b/Math::Pi); assert(x==y);
断言始终成立。原因如下:
- 浮点数平方运算会完全消除符号:
b*b是(-1.0/3.0)*(-1.0/3.0),其结果与a*a的二进制表示完全一致(IEEE 754规范中,负数的平方运算会精确得到对应正数的平方结果)。 - 后续计算中,
-(-b*b/Math::Pi)等价于b*b/Math::Pi,和x的计算逻辑完全相同,最终x与y的二进制存储值完全一致,==比较必然返回真。
第二个代码片段的断言是否成立?
代码示例:
double a = 1.0/3.0; double b = 1.0/7.0; double x = a-b; double y = -(b-a); assert(x==y);
断言始终成立。原因如下:
- IEEE 754标准中,浮点数的取负操作是精确执行的:仅翻转符号位,不会修改尾数和指数部分,不存在精度损失。
- 从运算逻辑看,
-(b-a)本质就是数学上的a-b,在IEEE 754的精确取负规则下,二者的二进制存储值完全相同,==比较必然返回真。
内容的提问来源于stack exchange,提问作者zmz
相关产品推荐
相关产品推荐

