多数编程语言里的0.1+0.2≠0.3?
我们从小就被教导说0.1+0.2=0.3,但是在奇妙的计算机编程世界里面,事情变得不一样了。
我最近在用JavaScript编程,正在阅读数据类型的时候,我注意到0.1+0.2不等于0.3的奇怪现象。我求助于Stack Overflow并找到了几条有帮助的信息,让我们来看一下:
经过大量的调查与数学研究,我得出结论:这并不是一个错误,而是数学——浮点运算。让我们进一步探索,去了解这个现象后面到底发生了什么。
现象描述:0.1 + 0.2 = 0.30000000000000004 是怎么发生的?
当你使用Java或者C编程的时候,你一定会意识到不同的数据类型用来存储不同的值,我们在前面的讨论中考虑的两种数据类型是整型与浮点型。
整形存储整数,浮点型存储小数。
在我们继续探索之前,让来理解一个小概念:以计算为目的,数字是如何被表示的?非常小与非常大的数字经常使用科学计数法表示,它的公式是:
而且,当一个数字在使用科学计数法表示的时候,它会被归一化成小数点前一个非零的十进制数字的形式,例如,0.0005606在用科学计数法表示并归一化后,它被表示为:
Significant 是不包含零的有效数字的数目,base表示所使用的进制——在这里是十进制,exponent 表示小数点需要向左或向右移动才能正确表示的位置数。
现在,有两种显示浮点数的方法:单精度与双精度。单精度使用32位,而双精度使用64位进行浮点运算。
不像其它编程语言,JavaScript没有定义不同类型的数字数据类型,而且始终遵循国际IEEE 754标准将数字存储为双精度浮点数。
这种格式以64位存储数字,其中数字(小数)存储在第0到51位,指数存储在第52到62位,符号存储在第63位中。
让我们以IEEE754标准表示64位中的0.1。
第一步是将十进制的0.1转换成等价的二进制数。为此,我们先将0.1乘以2,然后将小数点前的数字分开,以得到二进制等价值。
对于64位重复此操作,我们将按升序排列它们以获取尾数,根据双精度标准,我们将把其四舍五入为52位。
用科学计数法表示它并将其四舍五入到前52位将产生:
尾数部分已准备就绪,现在,对于指数使用以下计算:
在这里,11表示将用于指数的64位表示的位数,而-4表示科学计数法的指数。
数字0.1最终表示为:
相似地,0.2被表示为:
在使两者的指数相同之后将两者相加会得到:
当以浮点表示时,它将变为:
这就是0.1+0.2在计算机二进制中的表示。
把该二进制数转换回十进制小数,就得到了0.30000000000000004。
这就是隐藏在0.1 + 0.2 = 0.30000000000000004背后的原因。
原文链接:
https://medium.com/better-programming/why-is-0-1-0-2-not-equal-to-0-3-in-most-programming-languages-99432310d476
◆
精彩推荐
◆
推荐阅读
人体姿态估计的过去、现在和未来
图灵奖得主Bengio再次警示:可解释因果关系是深度学习发展的当务之急
技术领域有哪些接地气又好玩的应用?
Python新工具:用三行代码提取PDF表格数据
国产嵌入式操作系统发展思考
2019 年诺贝尔物理学奖揭晓!三得主让宇宙“彻底改观”!
公链故事难再续?
使用Vue.js开发微信小程序:开源框架mpvue解析
你点的每个“在看”,我都认真当成了喜欢
多数编程语言里的0.1+0.2≠0.3?相关推荐
- 有小数点是什么类型_为什么0.1+0.2不等于0.3?原来编程语言是这么算的……
打开你的 Python,输入「0.1+0.2=」,结果是多少?0.30000000000000004 对不对?为什么结果不是 0.3?本文作者给出了详细的解释. 选自Medium,作者:Parul M ...
- codeTyphon7.0里面的cef版本是79.0.10,貌似79.xxx都可以用
codeTyphon7.0里面的cef版本是79.0.10,貌似79.xxx都可以用,81.XXX,实测不能用,提示版本不对.3.XXX的也不行. 下载的时候要注意. 下载地址在pas提示里面 // ...
- android 7彩蛋,在你的Android手机里吸猫——挖挖Android7.0彩蛋
在你的Android手机里吸猫--挖挖Android7.0彩蛋 2017-10-28 15:14:23 23点赞 26收藏 30评论 值友们是不是被双十一精彩纷呈的预热活动刺激得开心无比啊, 对我这智 ...
- 从 C# 1.0 到 C# 9.0,历代 C# 语言特性一览
作者 | 雪轻鸿 责编 | 张红月 来源 | https://qinyuanpei.blog.csdn.net/article/details/113720157 C# 版本历史记录 说明:因 ...
- C# 语言历史版本特性(C# 1.0到C# 8.0汇总
C# 语言历史版本特性(C# 1.0到C# 8.0汇总) 历史版本 C#作为微软2000年以后.NET平台开发的当家语言,发展至今具有17年的历史,语言本身具有丰富的特性,微软对其更新支持也十分支持. ...
- RedHat 7.0及CentOS 7.0禁止Ping的三种方法
作者:荒原之梦 原文链接:http://zhaokaifeng.com/?p=538 前言: "Ping"属于ICMP协议(即"Internet控制报文协议") ...
- 漫话:如何给女朋友解释为什么计算机中 0.2 + 0.1 不等于 0.3 ?
作者 | 漫话编程 来源 | 漫话编程(ID:mhcoding) 为什么当我们使用电脑浏览器计算0.2+0.1的时候,解决却是0.30000000000000004,而 0.1+0.6 的结果却是 0 ...
- C#6.0,C#7.0新特性
C#6.0,C#7.0新特性 C#6.0新特性 Auto-Property enhancements(自动属性增强) Read-only auto-properties (真正的只读属性) Auto- ...
- android 6.0 自定义application,Android6.0之App中的资源管理对象创建
Android与资源管理相关的类Resouces和AssetManager很有必要清楚他们的创建过程. 与资源查找与加载操作相关的类 资源查找与加载主要是靠Android资源管理框架来完成的,而And ...
最新文章
- 【js】实现分页查询操作的步骤
- 大快搜索城市运河大数据政务管理平台案例解读
- android获取string.xml的值(转)
- 【攻防世界001】Guess-the-Number
- Java队列 Queue
- go 异常捕获处理 panic defer recover
- ps作业素材和成品_没有用过PS的画框工具,你还敢说你是设计大佬?
- [Vue]组件——通过$emit为组件自定义事件
- Android多个音频源采集,android音频采集
- 中剪取一种颜色的板块_不知道UI设计中APP界面版式如何排版?来看这个!
- 软件设计师12-数据库(范式)
- hadoop工作流引擎azkaban
- 2022年京东新百货七夕礼遇季活动有什么亮点?
- 王给月度BOSS队伍带来什么变化?
- 95年有g510台式计算机吗,台式电脑太老了换cpu能行吗?
- 10 ,对称矩阵,对角矩阵,相似矩阵,对角化 :
- 发明计算机作文300字,四年级我的发明作文300字
- 后台利用aop注解的方式防止重复提交
- 【Linux】进程概念 —— 进程状态
- 我心中的程序设计新时代