在 C 中如何确定 FLT_DIG、DBL_DIG 和 LDBL_DIG

use*_*390 5 c floating-point precision floating-accuracy

FLT_DIG、DBL_DIG、LDBL_DIG分别是float、double、long double类型可以准确表示的十进制位数。

#include <stdio.h>
#include <float.h>

int main(void)
{
  printf("%d, %d, %d\n", FLT_DIG, DBL_DIG, LDBL_DIG);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

打印61518。该标准在第 5.2.4.2.2 节中给出了准确的公式——例如对于浮点数,p = 24 和 b = 2:

在此处输入图片说明

但我不清楚上述公式(“否则”)是如何推导出来的。有人可以解释一下吗?

以下是我遵循的推理,但没有回答问题。考虑在有效数中有 23 位的 float 类型(IEEE-754 标准)。可以准确表示的最大二进制整数为:

  100...00 (25 digits total, because we have an implicit 1)
  = 2^24
  = 10^(24*log(2)) 
Run Code Online (Sandbox Code Playgroud)

因此 # 十进制数字:

= floor(24*log(2)) = 7
Run Code Online (Sandbox Code Playgroud)

而且不像floor(23 * log(2)) = 6标准规定的那样。

chu*_*ica 5

FLT_DIG、DBL_DIG 和 LDBL_DIG 是如何确定的(?)

粗略地说,用p二进制数字,可以编码p*(log 10 2) 个十进制数字。每个二进制数字大约占十进制数字的 0.3 位。

回想一下浮点值和数字,作为具有n含义数字和指数的 十进制文本,在较大的对数分布中线性分布。

下面的 -1 来自最坏情况的对齐问题,其中十进制值的分布相对于二进制值最密集。如果基数为 10,则不存在 -1 float,因为分布是对齐的。

在此输入图像描述

以下是我遵循的推理,但不能回答问题。...

OP 的推理路线按照此处的#6失败。十进制值与二进制值的对齐并不总是“有效”。

Afloat作为binary32示例。

  1. 在范围 [2 33或 8,589,934,592 ... 2 34或 17,179,869,184) 中,再次对 2 23 (8,388,608) 个值进行线性编码:彼此间隔 1024.0。在子范围 [9,000,000,000 和 10,000,000,000) 中,大约有 976,562 个不同的值。

  2. 作为文本,范围 [9,000,000*10 3和 10,000,000*10 3 ),使用 1 个前导数字和 6 个尾随数字,有 1,000,000 个不同的值。根据 #1,在同一范围内,有不到 1,000,000 个不同的float值。因此,一些十进制文本值将转换为相同的float. 在此范围内,我们可以使用 6 位数字而不是 7 位数字进行特殊转换。