网站首页 > 技术文章 正文
先来看一段简单的代码
public static void main(String[] args) {
System.out.println(0.1+0.2);
}
打印结果如下:
0.30000000000000004 //为什么0.1+0.2不等于0.3?
为什么会出现这种诡异的答案呢?
这还得从浮点数的二进制表示方法说起
这年头儿,连过马路的老奶奶估计都知道,计算机是采用二进制计数的
来,简单的考你一下:请把数字15写成二进制的形式
//答案应该比较简单0000 1111
相信你对整数的二进制已经比较熟悉
但如果我换成小数呢?3.14159265359该怎么表示?
其实,如果不搞底层设计,一般人还真的不太知道这个答案
但你只有理解小数在二进制中是如何表示的
才能够明白文章开头的案例【为什么0.1+0.2不等于0.3?】
我们以小数0.1为例,看看它是如何使用二进制存储的
第一步,把0.1 乘以 2, 得到的结果0.2, 整数部分 0 取走
第二步,把上一步留下的小数部分0.2,乘以2,得到的结果0.4, 整数部分 0 取走
第三步,把上一步留下的小数部分0.4,乘以2,得到的结果0.8, 整数部分 0 取走
第四步,把上一步留下的小数部分0.8,乘以2,得到的结果1.6, 整数部分 1 取走......直到,小数部分为0
下图展示了计算的过程 ↓
最终的二进制,就是整数部分的合集
写出来大概是这样:
0001 1001 1001 1001 1001 ...
可以看到,1001 的部分,是无限循环的
我们用二进制的小数把它写出来大概是这样
0.0001 1001 1001 1001 1001 ...
它相当于
你会发现,它并不等于0.1
它只是一个近似值
所以,二进制保留的位数越多,精度也就越高
早期的计算机其实是不能处理浮点数的
直到IEEE 754 标准出现后,计算机才能处理浮点数
根据IEEE 754 标准,float类型,共4个字节,32个bit位
其中指数部分占8位,小数部分占23位
那么 指数部分 和 小数部分 分别用来保存什么呢?
我们依然以 数字 0.1 为例,我们刚才已经得到了它的二进制
0.0001 1001 1001 1001 1001 ...
按照IEEE 754标准,我们需要把它的小数点,向右移动
直到整数部分是1为止
0.0001 1001 1001 1001 1001 ...
//小数点向右移动4位
//相当于乘以2的4次方
0001.1001 1001 1001 1001 ...
//也就是
1.1001 1001 1001 1001 ...
//为了维持数字大小不变
//再乘以2的-4次方
最终变成
float小数部分只能保存23位
-4 就是 指数部分
1001......就是 小数部分
小数点的位置不是固定的,而是浮动的,故名:浮点数
了解到这一点,你就能够接受更多看起来奇怪而有趣的现象
比如
float f1=0.4f;
double d1=0.4;
System.out.println(f1==d1);//false
System.out.println(f1>d1); //true
f1还原为10进制,结果为0.40000000596046450000
d1还原为10进制,结果为0.40000000000000000000
关于二进制的底层,还有很多问题,有待我们探索
多了解一点,就少一些困惑
猜你喜欢
- 2025-01-18 FX3U小数运算
- 2025-01-18 「创新班」007. float()函数 -- 把数字字符串(或整数)转为浮点数
- 2025-01-18 谈谈小数的表示方法之定点数
- 2025-01-18 浮点数/小数 的6种舍入方式
- 2025-01-18 NOI / 1.1编程基础之输入输出
- 2025-01-18 S7-200 SMART 数据类型(上)
- 2025-01-18 西门子PLC数据类型——浮点数
- 2025-01-18 畅谈计算机整数,浮点数存储和运算
- 2025-01-18 C|整数、浮点数的向上、向下溢出
- 2025-01-18 格式串详解中你不知道的知识
- 1507℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 519℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 489℃MySQL service启动脚本浅析(r12笔记第59天)
- 468℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 466℃启用MySQL查询缓存(mysql8.0查询缓存)
- 446℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 426℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 423℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)