抛硬币模拟

免费的抛硬币模拟,可自定义数量与规则,结果一键复制。所有生成都在浏览器本地完成,隐私更安全。

—

使用方法

  1. 在「投掷次数 n」填 1 ~ 10000 之间的整数。示例值 1000——这是本页能给出有意义卡方结论的最小实用规模。
  2. 在「每组投掷次数」填 10 ~ 200 的整数,示例值 50。分组是为了观察"局部是否偏斜",不分组只看总频率会掩盖前半段和后半段的差异。
  3. 在「随机源」二选一。默认 crypto.getRandomValues;换成 Math.random 是为了让你亲眼看到两者在本测试下分布没有区别,但它们的可预测性完全不同。
  4. 点「开始投掷」。页面会一次性取回 n 个 uint32,逐个取最高位当作正反面,然后给出频率、标准差、z 值和卡方结论。
  5. 下方分组对照表默认只显示 12 行,点「加载更多分组」逐步展开;需要离线核对时用「导出 CSV」,文件带 BOM,Excel 直接双击不乱码。

这个抛硬币模拟能解决什么问题

抛硬币模拟的真正用途不是"替你决定",而是回答一个具体问题:看到一堆正反结果,能不能说它偏向某一面。生活里这类判断天天出现——群里讨论午饭选哪家、投票前估一下票数、实验记录里判断一批样品有没有系统偏差、一个"随机"排序是不是其实有倾向。凭感觉看会出错:1000 次里出现 530 次正面,直觉上像"硬币偏了",但统计上完全正常。

它也能当反面教材。同一批数据在 n=10 和 n=10000 下结论完全相反,这正是统计推断的核心:样本量决定了你有多大概率说真话。抛硬币模拟把这个过程做成可重复的实验,你能亲眼看着频率从 0.70 收敛到 0.50,也能看着某个分组跳出 95% 区间后又回归。

本页不做的事:不模拟物理硬币的转动与碰撞(不涉及任何力学方程),也不提供多面币、骰子或带权重的不公平硬币——那些是别的工具负责的。这里只做一件事:标准二项分布 B(n, 0.5) 的抽样与检验。

随机比特的取法与统计口径

页面调用的是 Web Crypto API 的 crypto.getRandomValues(new Uint32Array(n)),然后对每个元素取 (v >>> 31) & 1——uint32 的最高位,取 0 记反面、取 1 记正面。

统计量按二项分布 B(n, 0.5) 计算。因为 p(1−p) = 0.25,所以标准差是 σ = 0.5 × √n 而不是 √n。z 分数 = (H − n/2) / σ,H 为正面次数。

卡方拟合优度检验用 df=1 的形式 χ² = 2(H − n/2)² / (n/2),判断它是否超过临界值。实测临界值:α=0.05 → 3.8415,α=0.01 → 6.6349,α=0.001 → 10.8276。1.96σ 的近似区间是给不需要做检验时快速看的,两者在 n 大时几乎重合。

分组卡方是同一个公式作用在每组的 G 次上:G=50 时期望频数 E=25,落在卡方检验要求的 E ≥ 5 之上;单组正面数 ≤18 或 ≥32 时 χ² 才越过 3.8415。这条阈值是算出来的,不是拍的。

完整示例(数值仅作演示)

示例条件:n = 1000,每组 50 次(拆成 20 组),随机源 crypto.getRandomValues。

以上数字用于演示检验逻辑。每次点「开始投掷」得到的具体序列都会不同,页面显示的是当次实测值,不预置任何固定结果。

投掷次数与 95% 区间对照表

同一枚公平硬币,样本量直接决定你能测出多小的偏差。半宽 = 0.98 / √n:

投掷次数 n期望正面数 n/2标准差 σ95% 正面数区间95% 频率区间半宽
1051.581.9 ~ 8.119.01% ~ 80.99%±30.99%
20102.245.6 ~ 14.428.09% ~ 71.91%±21.91%
50253.5418.1 ~ 31.936.14% ~ 63.86%±13.86%
100505.0040.2 ~ 59.840.20% ~ 59.80%±9.80%
2001007.0786.1 ~ 113.943.07% ~ 56.93%±6.93%
50025011.18228.1 ~ 271.945.62% ~ 54.38%±4.38%
100050015.81469.0 ~ 531.046.90% ~ 53.10%±3.10%
2000100022.36956.2 ~ 1043.847.81% ~ 52.19%±2.19%
5000250035.362430.7 ~ 2569.348.61% ~ 51.39%±1.39%
10000500050.004902.0 ~ 5098.049.02% ~ 50.98%±0.98%

读法:n=10 时 7 正 3 反和 3 正 7 反都在正常范围内,连"80% 正面"都碰得到;n=10000 时 51% 正面就已经越界。半宽与 √n 成反比——想把误差压到 1% 以内,样本量得从 1000 涨到 10000,成本是 10 倍。

边界与精度

常见问题

连出 5 次正面之后,下一次该出反面了吧?

不会,而且这是最有名的一个错误。上一次结果不影响下一次,概率永远是 0.5。容易产生错觉是因为"5 连正"本身不算罕见——它的事前概率是 0.55 = 3.125%,也就是每 32 次里就会遇到一次。在 n=100 的序列里,至少出现一次 5 连正的概率高达 95.3%。所以"该出反面了"是对随机性的误读,不是对概率的计算。

我这 1000 次里出现 530 次正面,硬币是不是有问题?

不是。n=1000 的 95% 区间是 469.0 ~ 531.0,530 落在区间内;χ²=3.6000 也小于临界值 3.8415。正确的说法是"在 α=0.05 下没有证据拒绝公平性",而不是"证明了绝对公平"——统计检验永远无法证明零偏差,只能给出证据不足或证据充分这两个结论。

分组表里有几行标红了,是不是程序算错了?

不是。每组 G=50 时,单组正面数 ≤18 或 ≥32 就越过 5% 临界值(18 正的 χ²=3.9200)。但你是同时看 20 个组,α=0.05 × 20 = 1.0,意味着平均本来就有 1 组标红。逐个组做检验再汇总,家族错误率会远高于 5%。要正式检验整体偏差,请只看顶部的总卡方,不要数有几行标红。

把随机源换成 Math.random,结果会不一样吗?

在 n=1000 这种样本量下,看不出区别。两者都是等概率的,分布检验都会通过。区别在可预测性:V8 的 Math.random 走 xorshift128+ 生成器,连续取到 624 个 32 位输出后可以还原其内部状态,从而预测之后所有结果。抛硬币模拟默认给 crypto 源就是为了让这个页面的输出不可被反推。

n=10 时能不能用这个页面做判断?

能看,不能判。n=10 的 95% 区间是 1.9 ~ 8.1,也就是 80% 正面、20% 正面都在正常范围。卡方检验的可靠性要求期望频数 E ≥ 5,n=10 刚好压线;n=20 时 E=10 才开始稳。要检测"硬币是否偏向某面"这种量级的差异,最低建议 n=1000——对应 ±3.10% 的分辨率。

页面里那条"最长连正约等于 log2(n)"是怎么来的?

几何分布的经典结论:长度 k 的正面段在 n 次里出现一次的概率约 n/2k+1,令它等于 1 解出 k ≈ log2(n)。代入可得 n=100 → 6.64、n=1000 → 9.97、n=10000 → 13.29。所以 n=10000 时看到 13 连正属于常态,不说明任何异常;判断异常仍然要看总卡方。

CSV 导出为什么开头有一段看不见的字符?

那是 UTF-8 BOM(U+FEFF),长度为 3 字节。Excel 打开不带 BOM 的 UTF-8 CSV 会把中文识别成乱码,加上 BOM 就能正确识别编码。它只影响 Excel 这类按 BOM 猜编码的软件,pandas.read_csv 默认也会跳过它,awk 则不会——这是刻意的取舍,不是 bug。

这个工具免费吗?数据安全吗?

免费,无需注册即可使用。随机源是浏览器内置的 crypto 熵池,不上传任何内容;页面上唯一的输入是次数和分组参数,你可以断网后刷新验证,开发者的 Network 面板会是空的。

相关工具