This topic created in 1399 days ago, the information mentioned may be changed or developed.
说明
- float64 == 8 字节 == 64bit == 只能精确表达 18446744073709552000(2^64) 个数字
- float32 == 4 字节 == 32bit == 只能精确表达 4294967296(2^32) 个数字
取值范围
- float64 最大值大约是 1.8e308 ( 18 后面 307 个 0 )
- float32 最大值大约是 3.4e38 ( 34 后面 37 个 0 )
- 即使忽略小数,负数 从 0 到这个最大值都已经远远超出其能精确表达的数字了
- 所以它们只能取接近的数字
- 或者说他们的表达不是连续的 例如 1 4 8 15 当值是 7 时就会取最接近的值 8
14 replies 2022-07-13 11:01:26 +08:00  | | 1 yayiji Jul 13, 2022 via Android 3 用范围容易理解,但我总喜欢另一个角度,就是数制
比如,十进制的 0.1 在二进制中是个无限循环小数,所以使用有限的二进制无论如何也无法精确表示 0.1
也即是说,即便不考虑范围问题,对于很多确定十进制小数二进制也无能为力,比如说,麻烦用二进制精确存储 0.1 0.2 0.3 0.4 0.5 这五个数吧 |
 | | 2 8520ccc Jul 13, 2022 via iPhone @ yayiji 这种说法比较绕,直接用范围不用考虑那么多,明白原理就行 |
 | | 4 yayiji Jul 13, 2022 via Android @ 8520ccc 因为还有数制本身的问题,比如说,我只想存十进制的 0.1 ,其他数不考虑了,这时仍然无法精确存储 |
 | | 5 yungo8 Jul 13, 2022 via Android 用的了这么复杂么,精度缺失不就是一句话: 因为算出来的都是近似值。只是 float 定的规则,长度固定的情况下,小数点前面越长,小数点后面位数就越短,偏差就会越来越大。
你算出来是 2^64 也是不对的,肯定不止这么点的。用的科学表示法,能表达的数值的数量你以为跟整形能算的出来? |
 | | 6 yungo8 Jul 13, 2022 via Android 额,我看错了,你说的二进制的个数呀,那是我说错了 |
 | | 8 Jooooooooo Jul 13, 2022 真的不如 "一个有限十进制小数无法用有限二进制小数" 表达来的简单
按照你这个说法, 很难解释出 0.1+0.2 怎么不等于 0.3 呢 |
 | | 9 hsfzxjy Jul 13, 2022 via Android 感觉不同人的盲点还是不一样的。有的人就是知道了浮点数不能表示所有实数,但还是迷惑「哎呀 0.1 这么简单的数怎么就不能表示」。这时就要和他用进制解释。 |
 | | 10 haolongsun Jul 13, 2022 复习一下 IEEE754 标准,不知道肯定大学计组不过关,推荐 csapp 。 |
 | | 12 AV1 Jul 13, 2022 我感觉大家把两件事混在一起谈了。
一是,一个数在十进制下是有限小数,但在二进制下是无限小数,导致浮点数无法精确表示对应的十进制数。
二是,浮点数所表达的数字,它的绝对值越大,精度越低。以至于当它要表达的数字超过 MAX_SAFE_INTEGER 或 MIN_SAFE_INTEGER 之后,连整数都不能精确表达了。 |
 | | 13 momocraft Jul 13, 2022 显然可以有一种格式存储在二进制下无限循环的有理数
ieee754 无能为力 不是"二进制无能为力" |
 | | 14 zmal Jul 13, 2022 不简单不明了,解释还是错的。 |