try 使用MAX_SAFE_INTEGER生成一个数字我注意到一些奇怪的事情,我确信这与数字在JavaScript中的存储方式有关,但我不明白它到底是什么.

Math.floor(Math.random() * Number.MAX_SAFE_INTEGER) // Always returns an odd number
Math.floor(Math.random() * (Number.MAX_SAFE_INTEGER - 1)) // Returns an odd number 75% of the time
Math.ceil(Math.random() * Number.MAX_SAFE_INTEGER) // Has a 50/50 chance to return odd or even

如何解释这种行为?在Math.floor中可以使用的最大积分是多少?

class RandomNumberCounter {
    constructor() {
        this.evenCount = 0;
        this.oddCount = 0;
    }

    generateNumbersAndCount() {
        for (let i = 0; i < 10000; i++) {
            const randomNumber = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
            if (randomNumber % 2 === 0) {
                this.evenCount++;
            } else {
                this.oddCount++;
            }
        }
    }

    printCounts() {
        console.log("Number of even numbers:", this.evenCount);
        console.log("Number of odd numbers:", this.oddCount);
    }
}

const randomNumberCounter = new RandomNumberCounter();
randomNumberCounter.generateNumbersAndCount();
randomNumberCounter.printCounts();

推荐答案

首先,您应该乘以253253 - 1如果产生任何不同的结果,可能不会造成太大伤害,但我不想进行必要的浮点分析- Select 明显正确的解决方案要容易得多.

但问题是什么?好吧,您的原始代码在Firefox和Safari上运行良好!只是V8(即Chrome和衍生产品)使用52位而不是53位.

let mostBits = 0;

for (let i = 0; i < 10000; i++) {
    const bits = Math.random().toString(2).slice(2).length;
    if (bits > mostBits) {
        mostBits = bits;
    }
}

console.log("Most bits:", mostBits);

(Firefox、Safari)

最多位数:53

(Chrome)

最多位数:52

(可以用52位存储的有效数准确存储53位的原因是,整部分隐式地是1,可以通过指数zoom 到正确的位置,就像为什么Number.MAX_SAFE_INTEGER是它一样.)

看看the relevant part of V8’s implementation,我假设它这样做的唯一原因是为了性能-通过固定指数以使范围[1,2),它可以将随机位直接插入到双进制中,而不必执行相乘.

static inline double ToDouble(uint64_t state0) {
  // Exponent for double values for [1.0 .. 2.0)
  static const uint64_t kExponentBits = uint64_t{0x3FF0000000000000};
  uint64_t random = (state0 >> 12) | kExponentBits;
  return base::bit_cast<double>(random) - 1;
}

所以为了回答你的问题,

Math.floor中,您可以使用的最大积分是多少才能获得50/50的比率?

最多252,但我不会对Math.random进行count,具有超过32位的随机性,除非您仅针对一个引擎(例如,V8更改为52 in 2015),或者甚至基于它对于特定目的来说足够好的随机性-这些东西都不在the spec中.

此函数返回一个带正值的Number值,大于或等于+0但严格小于1,随机或伪随机 Select ,在该范围using an implementation-defined algorithm or strategy上分布大致均匀.

您可能需要考虑在JavaScript中实现已知的PRNG,并以crypto.getRandomValues的强随机性对其进行种子 seeder .

Javascript相关问答推荐

使用脚本标签时的JSDoc智能感知

ChartJS:分组堆叠条形图渲染错误

文件阅读器未读取一个文件

访客柜台的风格React.js

Fastify错误:CORS策略已阻止从起源api-dev.example.com上的MLhttp请求

橡皮擦完全让画布变成白色

使用useParams路由失败

使用redux-toolet DelivercThunks刷新访问令牌

没有输出到带有chrome.Devtools扩展的控制台

如何用显示网格平滑地将元素从一个地方移动到另一个地方?

从Node JS将对象数组中的数据插入Postgres表

在react JS中映射数组对象的嵌套数据

使用POST请求时,Req.Body为空

material UI按钮组样式props 不反射

IF语句的计算结果与实际情况相反

WP Bootstrap NavWaker:下拉菜单一次打开所有下拉菜单

如何在Node.js中排除导出的JS文件

当代码另有说明时,随机放置的圆圈有时会从画布上消失

AddEventListner,按键事件不工作

Jexl to LowerCase()和Replace()