JAVA 中的浮点数与二进制
先来看一段简单的代码
打印结果如下:
为什么会出现这种诡异的答案呢?
这还得从浮点数的二进制表示方法说起
这年头儿,连过马路的老奶奶估计都知道,计算机是采用二进制计数的
来,简单的考你一下:请把数字 15 写成二进制的形式
相信你对整数的二进制已经比较熟悉
但如果我换成小数呢?3.14159265359 该怎么表示?
其实,如果不搞底层设计,一般人还真的不太知道这个答案
但你只有理解小数在二进制中是如何表示的
才能够明白文章开头的案例【为什么 0.1+0.2 不等于 0.3?】
我们以小数 0.1 为例,看看它是如何使用二进制存储的
下图展示了计算的过程 ↓
最终的二进制,就是整数部分的合集
写出来大概是这样:
可以看到,1001 的部分,是无限循环的
我们用二进制的小数把它写出来大概是这样
它相当于
你会发现,它并不等于 0.1
它只是一个近似值
所以,二进制保留的位数越多,精度也就越高
早期的计算机其实是不能处理浮点数的
直到 IEEE 754 标准出现后,计算机才能处理浮点数
根据 IEEE 754 标准,float 类型,共 4 个字节,32 个 bit 位
其中指数部分占 8 位,小数部分占 23 位
那么 指数部分 和 小数部分 分别用来保存什么呢?
我们依然以 数字 0.1 为例,我们刚才已经得到了它的二进制
按照 IEEE 754 标准,我们需要把它的小数点,向右移动
直到整数部分是 1 为止
最终变成
float 小数部分只能保存 23 位
-4 就是 指数部分
1001......就是 小数部分
小数点的位置不是固定的,而是浮动的,故名:浮点数
了解到这一点,你就能够接受更多看起来奇怪而有趣的现象
比如
f1 还原为 10 进制,结果为 0.40000000596046450000
d1 还原为 10 进制,结果为 0.40000000000000000000
关于二进制的底层,还有很多问题,有待我们探索
多了解一点,就少一些困惑
版权声明: 本文为 InfoQ 作者【加百利】的原创文章。
原文链接:【http://xie.infoq.cn/article/4d29e9120a55862ec88d61ee7】。文章转载请联系作者。
评论