【发布时间】:2011-10-23 19:20:09
【问题描述】:
浮点数越大(正数或负数)是否越少,我们对十进制数字进行编码的位就越少?
我们能否在 21 和 22 之间编码比在 216 和 232 之间更多的十进制数字?
这两个范围之间的值计数是否相同?
【问题讨论】:
-
我认为位数或有效位数是一样的。
标签: c++ floating-point
浮点数越大(正数或负数)是否越少,我们对十进制数字进行编码的位就越少?
我们能否在 21 和 22 之间编码比在 216 和 232 之间更多的十进制数字?
这两个范围之间的值计数是否相同?
【问题讨论】:
标签: c++ floating-point
IEEE 754,二进制 32 数字指定如下:
基本上它包含三个部分:
float32_sign 代表符号float32_fraction[] 表示二进制分数系数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)
【讨论】:
是的,可以用浮点数精确表示的数字的密度会随着数字变大而变小。
换句话说,浮点数只有固定位数的 尾数,随着数字变大,小数点后的尾数会越来越少(这就是我想你是在问)。
替代方案是定点数,其中小数点后的位数是恒定的。但是没有多少系统使用定点数,所以如果你想要这样,你必须自己滚动,或者使用第三方库。
【讨论】:
来自What Every Computer Scientist Should Know About Floating-Point Arithmetic:
一般来说,一个浮点数会被表示为±d.dd...d × e,其中 d.dd... d 称为有效数,有 p 个数字。更多的 精确 ± d0 。 d1 d2 ... dp-1 × e 代表数字。
因此,答案是肯定的,因为尾数(表示有效位的旧字)具有固定的位数。
【讨论】:
浮点数是尾数和指数的二进制表示。对于最流行的 32 位表示形式 IEEE 754 short real,有一个符号位,尾数为 23+1 位,指数范围为 -126 到 +127 的 2 次幂。
所以,为了解决你的观点:
对数字进行编码的位数是恒定的。 32 位浮点数约为 7 个十进制数字,64 位浮点数约为 16 个。
见 1。
是的。
【讨论】: