首页 > 解决方案 > 将 Number.MAX_SAFE_INTEGER 乘以 Math.random() 时,我可能会丢失任何十进制数字(精度)吗?

问题描述

在 JavaScript 中Number.MAX_SAFE_INTEGER乘以时,我可能会丢失任何小数位(精度)吗?Math.random()

我想我不会,但最好能对为什么有一个可信的解释

编辑,通俗地说,我们正在处理两个IEEE 754双精度浮点数,一个是最大整数(用于双精度),另一个是小数点后有很多位的小数。如果(比如说)我首先将它们转换为四精度格式,然后相乘,然后将乘积转换回双精度,结果会有所不同吗?

const max = Number.MAX_SAFE_INTEGER;
const random = Math.random();
console.log(`\
MAX_SAFE_INTEGER: ${max}, \
random: ${random}, \
product: ${max * random}`);

对于更详细的示例,我使用它来生成BigInt随机数

标签: javascriptmathrandomnumbers

解决方案


您的实现应该是安全的——理论上,如果引擎实现Math.random使用完全无偏的算法,0 到 MAX_SAFE_INTEGER 之间的所有数字都应该有出现的可能性。

但是规范不能保证绝对无偏的算法 - 选择的数字是随机的,而不是真正的完全随机的。(这样的事情甚至存在吗?这是值得商榷的......)现代版本 V8 和其他一些实现使用周期为 2 ** 128 的算法,大于 MAX_SAFE_INTEGER (2 ** 53 - 1) - 但它对于其他实现(尤其是较旧的实现)来说,具有更小的周期是完全合理的,从而导致该范围内的某些整数比其他实现更频繁地被选择。

如果这对您的脚本很重要(我认为在大多数情况下这不太可能),您可能会考虑使用质量更高的随机生成器Math.random- 但几乎可以肯定不值得担心。


推荐阅读