关于C++标准中<float.h>相关浮点要求及表示的技术问询
相关标准条款摘要
[basic.fundamental] 浮点类型基础
存在三种浮点类型:
float、double和long double。double类型的精度至少不低于float,long double类型的精度至少不低于double。float类型的值集合是double类型值集合的子集;double类型的值集合是long double类型值集合的子集。浮点类型的值表示由实现定义。[注:本文档不对浮点运算的准确性提出要求;另见[support.limits]。——结束注]
整数类型和浮点类型统称为算术类型。标准库模板
std::numeric_limits的特化应指定实现中每种算术类型的最大值和最小值。
[support.limits] 算术类型特性支持
头文件
<limits>([limits.syn])、<climits>([climits.syn])和<cfloat>([cfloat.syn])提供依赖于实现的算术类型特性([basic.fundamental])。
[cfloat.syn] <cfloat>头文件概要
头文件
<cfloat>定义的所有宏与C标准库头文件<float.h>中的宏相同。另见:ISO C 5.2.4.2.2
ISO C 5.2.4.2.2 浮点类型特性
以下列表中的值应替换为实现定义的常量表达式,其大小(绝对值)应大于或等于所示值,且符号相同:……
FLT_DIG6、DBL_DIG10、LDBL_DIG10……
从上述条款能看出,C++标准本身没有直接对float、double、long double的最低精度/范围作出规定,但通过引用C标准的<float.h>,间接关联了相关要求。
技术问题解答
问题1:[cfloat.syn]中的声明是否仅意味着定义了相同的宏且含义一致,还是更进一步要求遵循C标准中定义的最低要求?
答案是后者——不仅仅是宏的定义和含义一致,C++要求这些宏必须遵守C标准中规定的最低值要求。
理由很明确:[cfloat.syn]明确指向了ISO C 5.2.4.2.2条款,而该条款清晰规定了FLT_DIG、DBL_DIG等宏的最低取值要求。C标准通过这种引用方式,把C标准里的浮点最低要求纳入了自己的规范范畴。也就是说,任何符合标准的C实现,其<cfloat>中的宏不仅要和C的<float.h>同名同含义,还必须满足C标准设定的那些最小值门槛。
问题2:C++标准是否对浮点数的表示作出了任何规定?
C++标准只做了部分框架性的规定,具体的表示细节大多交给实现定义,但有几个关键约束:
- 三种浮点类型的精度和值集合存在层级关系:
float的精度≤double≤long double,且前者的值集合是后者的子集; - 要求
std::numeric_limits特化必须明确每种算术类型的最值; - 通过引用C标准的
<float.h>相关条款,间接要求浮点数的精度、范围等特性必须满足C标准设定的最低要求(比如FLT_DIG至少为6,DBL_DIG至少为10等); - 至于浮点数的具体存储格式(比如是否用IEEE 754)、超出最低要求的额外精度等,完全由实现决定,C++标准不做强制规定。
内容的提问来源于stack exchange,提问作者kvantour

