Eri*_*hil 9 c floating-point language-lawyer
C 2011 [N1570] 5.2.4.2.2 9说:
除了赋值和转换...之外,由具有浮动操作数的运算符产生的值以及通常的算术转换和浮动常量的值将被评估为其范围和精度可能大于该类型所需的格式.
这是否意味着可以使用一种格式评估实现中的所有浮点运算,或者可以使用更大范围和精度的格式评估每个运算?
后者将允许A*B == A*B
评估为假,如果A*B
评估的额外精度A*B
与标称精度评估不同.
这是值得一读的标准的相关部分的约瑟夫·迈尔斯的解释在GCC的C编译器的情况下,和定义的FLT_EVAL_METHOD
在C11 5.2.4.2.2:9:
评估格式的使用以FLT_EVAL_METHOD的实现定义值为特征:
-1不确定;
0仅根据类型的范围和精度评估所有操作和常量;
1计算float类型的操作和常量以及double类型的范围和精度,将long double操作和常量计算为long double类型的范围和精度;
2评估long double类型的范围和精度的所有操作和常量.
定义FLT_EVAL_METHOD
为as的AC编译器-1
不需要对浮点计算的精度做任何具体的事情,但是根据上面的定义,定义它的1
应该只计算精度的float
表达式double
,定义它的表达式2
应该只计算float
和double
表达式在long double
精度.
该标准没有明确允许其他精度,也没有明确允许在编译器方便时舍入到标称精度.(GCC在Joseph S. Myers的补丁之前做了后者,并且clang -mno-sse2 -std=c99
x86在我最后一次尝试时做了同样的事情,同时错误地定义FLT_EVAL_METHOD
为0).
根据这个含义的严格解释FLT_EVAL_METHOD
,a * b
应该只有一个值,如果这个值不是NaN,a * b == a * b
应该总是保存在一个用编译器编译的C程序中,该编译器定义FLT_EVAL_METHOD
为0,1或2.