浮点数、双精度浮点数和长双精度浮点数是否有保证的最小精度?

6
从我之前的问题“浮点数精度是可变还是不变?”中,我收到了一个回答,其中说道:
C提供了DBL_DIG、DBL_DECIMAL_DIG以及它们的float和long double对应项。DBL_DIG表示最小相对十进制精度。DBL_DECIMAL_DIG可以被视为最大相对十进制精度。
我查找了这些宏。它们在头文件<cfloat>中找到。从cplusplus reference page上,它们列出了floatdoublelong double的宏。
下面是最小精度值的宏: FLT_DIG 6或更高 DBL_DIG 10或更高 LDBL_DIG 10或更高 如果我只看宏定义的话,我会认为float具有至少6位小数精度,而doublelong double则具有至少10位小数精度。然而,作为一个成年人,我知道有些事情可能过于美好而不切实际。
因此,我想知道,floatdoublelong double是否具有保证的最小十进制精度,而这个最小十进制精度是否是上述宏定义的值?
如果不是,是什么原因?
注意:假设我们正在使用编程语言C ++。

“十进制精度”是什么意思? - tmyklebu
@tmyklebu 参考上面问题中的第一个链接。 - Wandering Fool
我也无法理解您第一个链接中的问题。您想要包含FLT_DIG的哪个语句?此外,您知道这些通常是基数2而不是基数10的格式,对吗? - tmyklebu
1
“小数精度”是什么?任何讨论都需要从该术语的定义开始,而您尚未给出一个在十进制浮点系统之外有意义的定义。 - tmyklebu
没错。我相信根据我的特定编译器实现,我在下面正确回答了自己的问题。如果我错了,请纠正我。 - Wandering Fool
显示剩余8条评论
4个回答

5
如果std::numeric_limits<F>::is_iec559为真,则IEEE 754标准的保证适用于浮点类型F
否则(无论如何),C标准规定了符号的最小允许值,例如DBL_DIG。对于库来说,“C++国际标准通过引用将其并入[C++]国际标准”,正如在C++11 §17.5.1.5/1中引用的那样。
编辑: 正如TC在这里的评论中指出的那样,

<climits>和<cfloat>通过§18.3.3[c.limits]被规范地纳入;最小值依次在C标准的§5.2.4.2.2中指定。

不幸的是,首先需要注意的是,C++11中的17.5节只是“信息性”的,而不是“规范性”的。其次,C标准中指定的值是最小值,也在一个信息性的部分(C99标准的附录E)中。因此,虽然它可以被视为实践中的保证,但它不是正式的保证。
一个强有力的迹象表明,在实践中,float的最小精度为6个小数位,没有任何实现会给出更少:
输出操作默认精度为6,这是规范性文本。
免责声明:可能有额外的措辞提供了我没有注意到的保证。这不太可能,但有可能。

<climits><cfloat>是通过§18.3.3 [c.limits]规范合并的;最小值在C标准的§5.2.4.2.2中依次指定。 - T.C.
@T.C.:谢谢!已更新并删除免责声明(不再需要)。 :) - Cheers and hth. - Alf

0
浮点数、双精度浮点数和长双精度浮点数是否有保证的最小十进制精度,这个最小十进制精度是否是上述宏的值?
我找不到标准中保证任何最小十进制精度值的地方。
以下引用可能会有所帮助:http://en.cppreference.com/w/cpp/types/numeric_limits/digits10
一个8位二进制类型可以精确表示任何两位十进制数,但是不能表示3位十进制数256..999。8位类型的digits10值为2(8 * std::log10(2)为2.41)。
标准32位IEEE 754浮点型具有24位小数部分(写入23位,一个隐含),这可能表明它可以表示7位十进制数(24 * std::log10(2)为7.22),但相对舍入误差是非均匀的,并且一些具有7个小数位的浮点值无法在转换为32位浮点数后恢复:最小正例子是8.589973e9,在往返后变成8.589974e9。这些舍入误差不能超过表示中的1位,digits10计算为(24-1)*std::log10(2),为6.92。向下取整结果为6。
然而,C标准指定需要支持的最小值。
来源: C标准
5.2.4.2.2 浮点类型的特征
...
9 在以下列表中给出的值应该被替换为常量表达式,其实现定义的值要大于或等于所示的值的绝对值(magnitude),并带有相同的符号。
...
-- 十进制数位数 q,使得任何具有 q 个小数位的浮点数都可以舍入成具有 p 个基数 b 数字的浮点数,并且再次返回,而不会改变 q 个小数位。
... FLT_DIG 6
DBL_DIG 10
LDBL_DIG 10

关于“标准可以保证8位浮点数表示的精度为2”,那会与C标准要求的限制(非正式)以及输出所需的默认精度6(规范)产生冲突。 - Cheers and hth. - Alf
@RSahu:所需的最小6位小数精度(通过FLT_DIG)意味着需要至少10^6个不同的值。这大约是2^20。因此,仅用于尾数就需要20位。然后您需要一个指数,它似乎至少有74个值左右,需要7位。然后是一个符号位,然后我们总共至少需要28位。我会说是32位,是的。 - Cheers and hth. - Alf
@Cheersandhth.-Alf不是2^20 21位,因为2^0是二进制中的第一位吗? - Wandering Fool
@WanderingFool:20位二进制数可以有2^20种可能的比特值模式。当每个模式代表一个唯一的值时,那就是2^20个值。如果这些值被编号为0、1、2等等,那么整数值2^20不在这些值中,但会紧随最后一个值之后出现。 - Cheers and hth. - Alf
我的错误。我把值和位混淆了。 - Wandering Fool
显示剩余2条评论

0

-1

C++标准没有具体规定浮点类型的限制。您可以将C标准的"引用"解释为您希望的方式,但如果您将其视为指定限制的规范(N1570),请参考5.2.4.2.2小节15:

示例1
以下描述了一种人工浮点表示法,它满足本国际标准的最低要求,并提供了一个类型float的适当值头文件:
FLT_RADIX 16
FLT_MANT_DIG 6
FLT_EPSILON 9.53674316E-07F
FLT_DECIMAL_DIG 9
FLT_DIG 6
FLT_MIN_EXP -31
FLT_MIN 2.93873588E-39F
FLT_MIN_10_EXP -38
FLT_MAX_EXP +32
FLT_MAX 3.40282347E+38F
FLT_MAX_10_EXP +38

通过这个部分,floatdoublelong double至少具有以下属性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接