【问题标题】:Density of floating point number - Magnitude of the number浮点数的密度 - 数字的大小
【发布时间】:2011-10-23 19:20:09
【问题描述】:

浮点数越大(正数或负数)是否越少,我们对十进制数字进行编码的位就越少?

我们能否在 21 和 22 之间编码比在 216 和 232 之间更多的十进制数字?

这两个范围之间的值计数是否相同?

【问题讨论】:

  • 我认为位数或有效位数是一样的。

标签: c++ floating-point


【解决方案1】:

IEEE 754,二进制 32 数字指定如下:

基本上它包含三个部分:

  • 1 位 float32_sign 代表符号
  • 23 位 float32_fraction[] 表示二进制分数系数
  • 8 位 float32_exp 表示 2 的整数指数

详情请见wikipedia/Single-precision_floating-point_format

得到实际数字的公式是:

忘记指数,小数部分可以准确地表示pow(2, 23) = 8388608 值。此范围内的最大值和最小值为:

    ( 1 + 0, 1 + sum(pow(2, -i)) )  # All co-efficients being 0 and 1 resp. in the above formula
=>  ( 1, 2 - pow(2, -23) )          # By geometric progression
~>  ( 1, 2 )                        # Approximation by upper-bound

所以对于指数为 1 (float32_exp = 128),我们将在 (1,2)(-1,-2) 之间有 8388608 个数字。

但是对于较大的数字,例如当指数为 126 (float32_exp = 253),我们仍然只有 8388608 个数字来表示 (2^126), 2^127)(-2^126, -2^127) 之间的差距。

1 到 128 之间的分布图如下所示:

图表在 0 处是如此陡峭,以至于绘制它会使它看起来像一个仅在 0 处的单个值。请注意,该图是双曲线。

获取两个值之间的浮点数个数的公式是:

def num_floats(begin, end):
    # pow(2, 23) * (log(end, 2) - log(start, 2)) == pow(2, 23) * log(end/start, 2)
    return 8388608 * math.log(float(end)/float(begin), 2)

【讨论】:

  • 您能告诉我您是如何得出分布图的吗?我无法解释它。 x轴是什么意思? y 轴似乎是区间 [2^x, 2^x+1) 中的浮点数的数量。任何帮助都非常感谢!
  • @MaxMaier 我很久以前就写过这篇文章,所以我不记得我是如何绘制它的了。但是我确实理解您的困惑, x 不能代表瞬时值。这里的 x 代表一个起始值。下一个值也需要一个增量。对于不同的 delta 值,我们将得到不同的图表。经过一些实验,我认为我用于此图的 delta 为 0.1。所以这绝对不是理想的图表。我的极限和微分理论有点生疏,所以我无法在 delta 趋于 0 的那一刻想出理想的公式。如果有人可以,我会更新这个。
  • @MaxMaier 我算出了衰减函数:区间上的 num_floats 函数实际上是区间上连续函数的积分。设,alpha = 2^23 * log(e, 2),然后,积分(f(x)) = alpha * ln(x) => f(x) = alpha * 1/x
【解决方案2】:

是的,可以用浮点数精确表示的数字的密度会随着数字变大而变小。

换句话说,浮点数只有固定位数的 尾数,随着数字变大,小数点后的尾数会越来越少(这就是我想你是在问)。

替代方案是定点数,其中小数点后的位数是恒定的。但是没有多少系统使用定点数,所以如果你想要这样,你必须自己滚动,或者使用第三方库。

【讨论】:

    【解决方案3】:

    来自What Every Computer Scientist Should Know About Floating-Point Arithmetic

    一般来说,一个浮点数会被表示为±d.dd...d × e,其中 d.dd... d 称为有效数,有 p 个数字。更多的 精确 ± d0 。 d1 d2 ... dp-1 × e 代表数字。

    因此,答案是肯定的,因为尾数(表示有效位的旧字)具有固定的位数。

    【讨论】:

    • 请,该链接很有用,但不应仅称为“this”。任何想认真计算的人都应该认真阅读它,但是如果您想阅读全部内容,它会很长而且很密集。
    【解决方案4】:

    浮点数是尾数和指数的二进制表示。对于最流行的 32 位表示形式 IEEE 754 short real,有一个符号位,尾数为 23+1 位,指数范围为 -126 到 +127 的 2 次幂。

    所以,为了解决你的观点:

    1. 对数字进行编码的位数是恒定的。 32 位浮点数约为 7 个十进制数字,64 位浮点数约为 16 个。

    2. 见 1。

    3. 是的。

    【讨论】:

    • by 1 et 2 我想知道如果数字很大,两个相邻值之间的差距是否更重要?
    • 32 位浮点数是 7 个十进制数字(23 位 + 隐式 1 给出的范围是 2^24,大约是 1.6*10^7),但对于 64 位它只有 15 个一(双),因为它有 51 位 + 隐式 1,它给出的范围是 2^52,而这只是大约 4*10^15。
    • @Guillaume07:浮点用于相对间隙很重要并且保持不变的情况。如果绝对差距很重要,您应该使用整数。
    • 你可以通过计算n * ln(2) / ln(10)来查看小数位数有多少,其中n是位数。那是大约。 n * 0.3.
    猜你喜欢
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 2018-07-09
    • 2011-05-17
    • 1970-01-01
    • 2013-01-10
    • 2019-04-30
    相关资源
    最近更新 更多