【问题标题】:Determining decimal precision of a floating point number确定浮点数的十进制精度
【发布时间】:2018-07-05 17:40:25
【问题描述】:

我已经在互联网上搜索了几天,似乎无法找到一个普遍接受的公式来确定我们可以以浮点格式存储的十进制位数而不会出现截断错误。我最常遇到的答案是:

十进制精度 = log₁₀(2ⁿ),其中 n = 尾数中的位数。

现在,这与我在我的 CS 书中讨论的单点和双点格式所见的一切一致。

但是,当我对照我的 CS 书中的示例检查这一点时,数字并没有对齐。

示例使用 8 位格式和 4 位尾数。鉴于上面的公式,我应该只能存储精度高达 1.2 位的十进制值。但是,根据本书(并通过尝试其他十进制值确认),我可以将诸如 2.25 的值存储在 4 位尾数中而不会截断。 0.0625 也可以无误地存储。在这两种情况下,十进制数字都超过了上面等式给出的 1.2。

我不禁想知道我是否缺少某些东西。给定任何大小的尾数,有没有办法确定小数精度?上述公式是否与一定大小以下的尾数字段冲突?

我们将不胜感激。

丹尼 D.

【问题讨论】:

  • 您可能是指 单精度双精度 格式,即 IEEE-754 单精度和双精度类型。没有“双点”格式。如果你打印出 0.1,你会发现它在单精度格式中正好是 0.100000001490116119384765625,尽管据说该格式只存储 6-7 位数字(进行对数计算,你会明白为什么)。这意味着它可以可靠地存储该位数,而不是对于某些值,存储的数字不能有更多的十进制数字(如果以数字格式表示)。一些完全可表示的值可以有更多的数字。
  • 将 log10(2^n) 作为十进制数字只是对 n 位中传达的信息的度量。它不是可以存储的十进制数字的文字数量。具有二进制基数的浮点格式表示整数乘以 2 的幂(可能是 2 的正或负幂)。一般来说,二进制浮点数不太适合十进制数字,您不应该将它们视为十进制数字。我们可以描述有多少十进制数字可以转换为浮点数并以足够的精度转换为原始数字的界限......
  • ……恢复了。但是,当您第一次学习浮点数时,这不是您应该关心的事情。您应该从侧重于浮点数本身属性的文本中学习,而不是将它们与十进制数字相关联。
  • Eric,这本书是我的计算机科学课程介绍,所以是为我选择的。我已经告诉自己,我对这个特定问题思考得太认真了,但我倾向于完全理解一个主题,而不仅仅是一点点(呵呵)。
  • 承认令人沮丧,但我仍然不确定我是否听懂了您和 Rudy 所说的话。例如,如果要使用单精度存储某个 9 位值,它仍然可以无误地存储吗? (抱歉文字太长,电话评论)

标签: floating-point decimal precision


【解决方案1】:

一个公认的公式,用于确定我们可以以浮点格式存储的十进制位数而不会出现截断错误。

研究FLT_DIG, DBL_DIG, LDBL_DIG。它们是有效小数位数(如 text 中的),可以四舍五入为浮点类型并再次返回为 float, double, long double

使用二进制基并泛化为 OP,使用

floor((significant_bits - 1) log10(base))

使用base == 2significant_bits == 5 位符号(4 个显式编码,1 个隐含),这是floor(1.204...)1

这意味着 w.000 * 10power 形式的十进制数,w (1-9) 和 @987654332 的 所有 组合@(在最小/最大范围内)将成功地从十进制文本“往返”到 OP_s_Floating_point_type 到十进制文本。

如果尝试对 w.y00 * 10power 形式的十进制文本进行往返,对于 w,y 的某种组合,将发生故障。这并不意味着该形式的所有组合都会失败,只是一些。

考虑尝试采用十进制文本“9.0”、“9.1”、“9.2”、...“9.9”并将这 10 个转换为 OP 的 FP 格式。在 9 范围内,该格式仅支持编码 9.0 和 9.5。所以映射这 10 个数字会产生 2 个不同的 FP 数字。当然,将这 2 个转换回十进制形式只会导致 2 个不同的答案。这 10 次中的 8 次往返失败。

如果有我遗漏的东西。
给定任何大小的尾数,有没有办法确定小数精度?

从上述公式得出的值 1 是最坏情况最坏情况是通常报告的十进制精度的数字。

【讨论】:

  • 我想我正在捡起你放下的东西。因此,即使最坏的情况是 1.204(或 1),仍然有可能某些 2 位或什至 3 位十进制数字可以与该 4 位尾数往返?因此,按照相同的逻辑,最坏情况为 7.225 的单精度浮点数可以支持某些数字包含超过 8 个十进制数字的往返行程?
  • @DannyD 是的,你在正确的轨道上。甚至您的小 FP 也可能成功地往返 select 十进制值,例如 0.0078125(5 位数字)。注意:binary32 的最坏情况不是 7.225,而是 6.92...试试printf("%d\n", FLT_DIG);
  • 太棒了,感谢您的解释!
猜你喜欢
  • 2014-08-14
  • 2014-02-07
  • 2016-08-17
  • 2015-02-08
  • 2013-12-16
  • 2016-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多