2011年[N1570] 5.2.4.2.2 9说:
除了赋值和转换...之外,具有浮动操作数的运算符产生的值以及通常算术转换和浮动常量的值将被评估为其范围和精度可能大于该类型所需的格式。
这是否意味着实施中的所有浮点操作可以使用一个格式进行评估,或者每个操作可以使用格式进行评估更大的范围和精度?
后者允许A*B == A*B
评估为假,如果A*B
评估的额外精度与A*B
评估的名义精度不同。
答案 0 :(得分:6)
对于GCC的C编译器,以及C11中的FLT_EVAL_METHOD
的{{3}},请阅读the interpretation of Joseph S. Myers of the relevant parts of the standard:5.2.4.2.2:9:
使用评估格式的特点是 实现定义的FLT_EVAL_METHOD值:
-1 indeterminable;
0只评估所有操作和常量的范围和精度 类型;
1计算float和double类型的操作和常量 double类型的范围和精度,评估long double 操作和常量到long double的范围和精度 类型;
2评估所有操作和常数的范围和精度 长双人型。
将FLT_EVAL_METHOD
定义为-1
的AC编译器不需要对浮点计算的精度做任何具体的操作,但根据上述内容,将其定义为1
应仅评估float
精度中的double
个表达式,而将其定义为2
的表达式应仅评估float
精度中的double
和long double
个表达式
标准没有明确允许其他精度,也没有明确允许在编译器方便时舍入到标称精度。 (GCC在Joseph S. Myers的补丁之前做了后者,x86上的clang -mno-sse2 -std=c99
正在做同样的事情definition,同时错误地将FLT_EVAL_METHOD
定义为0)。
根据对FLT_EVAL_METHOD
含义的严格解释,a * b
应该只有一个值,如果这个值不是NaN,a * b == a * b
应该始终保存在编译的C程序中使用将FLT_EVAL_METHOD
定义为0,1或2的编译器。