【问题标题】:Binary Floats Represented as Decimal Numbers以十进制数表示的二进制浮点数
【发布时间】:2016-01-01 08:39:39
【问题描述】:

并非所有十进制数都可以使用二进制浮点数精确表示。

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html

实数可能不准确的原因有两个 可表示为浮点数。最常见的情况是 用十进制数 0.1 表示。虽然它有一个有限的 十进制表示,二进制表示无限重复 表示。

反过来呢?如果使用了足够的数字,每个 IEEE 754 浮点数是否可以用十进制数字精确表示?

【问题讨论】:

  • @harold 一些双精度数需要大约 750 个十进制数字(或多或少 52 + 1022 * (1 - log10(2)))
  • @harold 当我说 52 + 1022 * (1 - log10(2)) 时,我没有计算它们,但如果我想计算它们,它将是 52 + 1022。不计算前导零很简单:有效数字中的每个二进制数字和负指数的每个单位都需要一个十进制数字。
  • @harold 这个人说 767。“1 - log10(2)”是一个粗略的近似值,而不是精确的科学。 stackoverflow.com/a/17245451/139746

标签: binary floating-point numbers decimal ieee-754


【解决方案1】:

是的,如果使用了足够的数字,每个有限的 IEEE 754 浮点数都可以使用十进制数精确表示。

每个额外的二进制精度数字最多需要一个额外的精度十进制数字才能准确表示。

例如:

0.1b   -> 0.5
0.01b  -> 0.25
0.11b  -> 0.75
0.001b -> 0.125

1 到 2 之间的双精度 (binary64) 数字只需要在点后 52 位十进制数字即可准确表示:

#include <stdio.h>

int main(void) {
  printf("%.55f\n", 1.1);
}

结果:

1.1000000000000000888178419700125232338905334472656250000

在上面表示的末尾显示的四个之后都是零。 1.100000000000000088817841970012523233890533447265625 是最接近 11/10 的双精度值。

正如下面的 cmets 所指出的,负指数的每个额外的量级单位还需要一个额外的十进制数字才能准确表示。但是大的负指数在其十进制表示中具有前导零。最小的次正规数将在点后有 1022 + 52 个十进制数字,但这些数字的前近 1022*log10(2) 位将为零。

【讨论】:

  • @Jongware 负指数的每个额外的量级单位还需要一个额外的十进制数字才能准确表示。我将把数学作为 1/(2^24) 的练习留给读者,但如果它非常接近 24,我不会感到惊讶。除非你的意思是不计算前导零,否则你需要减去 24 * log10(2) 或类似的东西。
  • @Jongware 1/(2^24) 为 0.000000059604644775390625,小数点后 24 位,其中 7 位为前导零。
猜你喜欢
  • 2014-08-14
  • 2017-06-16
  • 1970-01-01
  • 2013-05-02
  • 2012-08-10
相关资源
最近更新 更多