提问人:Neo Anderson 提问时间:1/29/2022 更新时间:1/29/2022 访问量:99
numpy 如何设法将 float32 除以 2**63?
How does numpy manage to divide float32 by 2**63?
问:
这里丹尼尔提到
...在 [0, 2²⁴) 中选取任何整数,并将其除以 2²⁴,然后可以通过将结果再次乘以 2²⁴ 来恢复原始整数。这适用于 2²⁴,但不适用于 2²⁵ 或任何其他更大的数字。
但是当我尝试时
>>> b = np.divide(1, 2**63, dtype=np.float32)
>>> b*2**63
1.0
虽然它不适用于 2⁶⁴,但我想知道为什么它适用于 24 到 63 的所有指数。而且,如果它只对numpy独有。
答:
在这段话所处的上下文中,并不是说整数值不能除以 225 或 263,然后乘以恢复原始值。这是说,这无助于创建无偏见的数字分布。
该文本留下了一些没有明确说明的内容,但我怀疑它正在讨论采用整数类型的值,将其转换为 IEEE-754 单精度,然后对其进行除法。这不适用于大于 224 的因子,因为从整数类型到 IEEE-754 单精度的转换必须对数字进行舍入。
例如,对于 232,从 0 到 16,777,215 的所有数字都将无误地转换为自身,然后除以 232 将为每个数字生成一个唯一的浮点数。但是 16,777,216 和 16,777,217 都将转换为 16,777,216,然后除以 232 将得到相同的数字 (1/256)。从 2,147,483,520 到 2,147,483,776 的所有数字都将映射到 2,147,483,648,然后生成 1/2,即 257 个数字映射到一个浮点数。但是从 2,147,483,777 到 2,147,484,031 的所有数字都映射到 2,147,483,904。所以这个有 255 个数字映射到它。(差异是由于舍入到最接近的平数规则。在高端,从 4,294,967,168 到 4,294,967,296 的 129 个数字映射到 4,294,967,296,其中除法产生 1,这超出了所需的半开区间 [0, 1]。
另一方面,如果我们使用从 0 到 16,777,215 (224−1) 的整数,则没有舍入,并且每个结果都恰好从一个起始数字映射并保持在区间内。
请注意,“有效”是浮点表示的分数部分的首选术语。“尾数”是一个古老的词,表示对数的小数部分。有效是线性的。尾数是对数的。IEEE-754 单精度格式的有效位是 24 位,而不是 23 位。用于对有效数进行编码的主字段有 23 位,但指数字段提供另一个位。
上一个:解决多项式乘法和除法“溢出”问题
评论