「质因子」在说什么:为什么 0.1 换进制就写不完
订单簿里不能用 float64 表示价格,常被一句话打发:「0.1 在二进制里写不完。」再往下追,就会撞上另一句:看分母的质因子,是不是都是这个进制基数也有的质因子。
这句话不绕。拆开只有三块:什么是质因子、进制的基数有哪些质因子、多出来的那个质因子会把小数变成无限循环。
质因子是什么
质数只能被 1 和自己整除:2、3、5、7、11……
质因子就是把整数拆成质数相乘后,那些质数。
1 | 10 = 2 × 5 → 10 的质因子是 2 和 5 |
同一个质数出现几次没关系,关心的是「拆完还剩哪些不同的质数」。
进制的基数,质因子又是哪个
基数就是逢几进一。
- 十进制基数是 10,
10 = 2 × 5,质因子是 2 和 5 - 二进制基数是 2,质因子只有 2
小数点后每一位,都是「1 / 基数的某次方」:
1 | 十进制 0.1 = 1 / 10 |
所以二进制小数只能精确表示「分母是 2 的幂」的分数:1/2、3/4、7/8。分母里一旦多出别的质数,就写不完。
只需记这一句: 1/n 在某进制里能不能写完,看 n 拆完以后,是不是只剩下「这个进制也有的」质因子。多出来的质因子,就会变成无限循环。
十进制:有 2 和 5
| 分数 | n 的质因子 | 是不是只有 2、5 | 结果 |
|---|---|---|---|
1/2 |
2 | 是 | 0.5 写得完 |
1/5 |
5 | 是 | 0.2 写得完 |
1/10 |
2、5 | 是 | 0.1 写得完 |
1/4 |
2、2 | 是 | 0.25 写得完 |
1/3 |
3 | 否,多了个 3 | 0.333... 写不完 |
1/7 |
7 | 否 | 0.142857 循环 |
1/3 人人都见过:十进制里 3 这个质因子「进制没有」,于是永远除不尽。
二进制:只有 2
| 分数 | n 的质因子 | 去掉 2 以后还剩什么 | 结果 |
|---|---|---|---|
1/2 |
2 | 空 | 0.1₂ 写得完 |
1/4 |
2、2 | 空 | 0.01₂ 写得完 |
1/8 |
2、2、2 | 空 | 0.001₂ 写得完 |
1/5 |
5 | 还剩 5 | 循环,写不完 |
1/10 |
2、5 | 还剩 5 | 循环,写不完 |
0.1 在十进制刚好写得完,因为分母 10 只有 2 和 5。换到二进制,5 这个质因子「进制里没有」,所以变成:
1 | 0.1₁₀ = 0.00011001100110011...₂ (0011 一直重复) |
机器只能存有限位,只好截断。打印时常显示成 0.1,那是显示时又圆了一下,内存里其实是:
1 | 0.1000000000000000055511151231257827021181583404541015625 |
钱和价格按十进制(分、厘)计价,0.1、0.01 在十进制里刚好有限。丢进 float64(二进制)就变成无限循环,再截断就错。先写成 float64 再转 decimal,转的是已经错了的近似,回不去你写下的那个十分之一。
用长除法想也行:十进制下 1÷3 永远余 1,所以一直是 3;二进制下 1÷10 同样余数循环,所以一直是 0011。
和「位权」对上
任何进制都是「每位乘以基数的幂,再相加」。
十进制 13.25:
1 | 1×10¹ + 3×10⁰ + 2×10⁻¹ + 5×10⁻² |
二进制小数点后第 1 位是 1/2,第 2 位是 1/4,第 3 位是 1/8。没有一位等于 1/10,所以 1/10 只能用无限个 1/2^k 去凑,永远凑不精确。
十进制写不准 1/3,二进制写不准 1/10,是同一类限制,只是我们更熟悉十进制。
对照
| 人熟悉的类比 | 机器里实际发生的事 | |
|---|---|---|
| 进制 | 十进制有 2、5 | 二进制只有 2 |
| 写得完 | 1/2、1/5、1/10 |
只有 1/2、1/4、1/8…… |
| 写不完 | 1/3、1/7 |
1/5、1/10(也就是 0.1、0.01) |
「n 的质因子」是分母拆出来的质数。「该进制基数的质因子」是 10 拆出来的 2、5,或 2 拆出来的 2。两者一比,多出来的那个,就是循环的来源。
- Title: 「质因子」在说什么:为什么 0.1 换进制就写不完
- Author: Jeffery
- Created at : 2026-09-05 15:40:00
- Updated at : 2026-09-06 07:11:38
- Link: https://redefine.ohevan.com/2026/09/05/质因子与进制小数/
- License: This work is licensed under CC BY-NC-SA 4.0.