作者 | Parul Malhotra
译者 | Raku
出品 | AI科技大本营(ID:rgznai100)

我们从小就被教导说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

(*本文为 AI科技大本营翻译文章,载请微信联系 1092722531

精彩推荐

2019 中国大数据技术大会(BDTC)再度来袭!豪华主席阵容及百位技术专家齐聚,15 场精选专题技术和行业论坛,超强干货+技术剖析+行业实践立体解读,深入解析热门技术在行业中的实践落地。
即日起,限量 5 折票开售,数量有限,扫码购买,先到先得!

推荐阅读

  • 人体姿态估计的过去、现在和未来

  • 图灵奖得主Bengio再次警示:可解释因果关系是深度学习发展的当务之急

  • 技术领域有哪些接地气又好玩的应用?

  • Python新工具:用三行代码提取PDF表格数据

  • 国产嵌入式操作系统发展思考

  • 2019 年诺贝尔物理学奖揭晓!三得主让宇宙“彻底改观”!

  • 公链故事难再续?

  • 使用Vue.js开发微信小程序:开源框架mpvue解析

你点的每个“在看”,我都认真当成了喜欢

多数编程语言里的0.1+0.2≠0.3?相关推荐

  1. 有小数点是什么类型_为什么0.1+0.2不等于0.3?原来编程语言是这么算的……

    打开你的 Python,输入「0.1+0.2=」,结果是多少?0.30000000000000004 对不对?为什么结果不是 0.3?本文作者给出了详细的解释. 选自Medium,作者:Parul M ...

  2. codeTyphon7.0里面的cef版本是79.0.10,貌似79.xxx都可以用

    codeTyphon7.0里面的cef版本是79.0.10,貌似79.xxx都可以用,81.XXX,实测不能用,提示版本不对.3.XXX的也不行. 下载的时候要注意. 下载地址在pas提示里面 // ...

  3. android 7彩蛋,在你的Android手机里吸猫——挖挖Android7.0彩蛋

    在你的Android手机里吸猫--挖挖Android7.0彩蛋 2017-10-28 15:14:23 23点赞 26收藏 30评论 值友们是不是被双十一精彩纷呈的预热活动刺激得开心无比啊, 对我这智 ...

  4. 从 C# 1.0 到 C# 9.0,历代 C# 语言特性一览

    作者 | 雪轻鸿     责编 | 张红月 来源 | https://qinyuanpei.blog.csdn.net/article/details/113720157 C# 版本历史记录 说明:因 ...

  5. C# 语言历史版本特性(C# 1.0到C# 8.0汇总

    C# 语言历史版本特性(C# 1.0到C# 8.0汇总) 历史版本 C#作为微软2000年以后.NET平台开发的当家语言,发展至今具有17年的历史,语言本身具有丰富的特性,微软对其更新支持也十分支持. ...

  6. RedHat 7.0及CentOS 7.0禁止Ping的三种方法

    作者:荒原之梦 原文链接:http://zhaokaifeng.com/?p=538 前言: "Ping"属于ICMP协议(即"Internet控制报文协议") ...

  7. 漫话:如何给女朋友解释为什么计算机中 0.2 + 0.1 不等于 0.3 ?

    作者 | 漫话编程 来源 | 漫话编程(ID:mhcoding) 为什么当我们使用电脑浏览器计算0.2+0.1的时候,解决却是0.30000000000000004,而 0.1+0.6 的结果却是 0 ...

  8. C#6.0,C#7.0新特性

    C#6.0,C#7.0新特性 C#6.0新特性 Auto-Property enhancements(自动属性增强) Read-only auto-properties (真正的只读属性) Auto- ...

  9. android 6.0 自定义application,Android6.0之App中的资源管理对象创建

    Android与资源管理相关的类Resouces和AssetManager很有必要清楚他们的创建过程. 与资源查找与加载操作相关的类 资源查找与加载主要是靠Android资源管理框架来完成的,而And ...

最新文章

  1. 【js】实现分页查询操作的步骤
  2. 大快搜索城市运河大数据政务管理平台案例解读
  3. android获取string.xml的值(转)
  4. 【攻防世界001】Guess-the-Number
  5. Java队列 Queue
  6. go 异常捕获处理 panic defer recover
  7. ps作业素材和成品_没有用过PS的画框工具,你还敢说你是设计大佬?
  8. [Vue]组件——通过$emit为组件自定义事件
  9. Android多个音频源采集,android音频采集
  10. 中剪取一种颜色的板块_不知道UI设计中APP界面版式如何排版?来看这个!
  11. 软件设计师12-数据库(范式)
  12. hadoop工作流引擎azkaban
  13. 2022年京东新百货七夕礼遇季活动有什么亮点?
  14. 王给月度BOSS队伍带来什么变化?
  15. 95年有g510台式计算机吗,台式电脑太老了换cpu能行吗?
  16. 10 ,对称矩阵,对角矩阵,相似矩阵,对角化 :
  17. 发明计算机作文300字,四年级我的发明作文300字
  18. 后台利用aop注解的方式防止重复提交
  19. 【Linux】进程概念 —— 进程状态
  20. 我心中的程序设计新时代

热门文章

  1. IntelliJ IDEA 12详细开发教程(四) 搭建Android应用开发环境与Android项目创建
  2. linux 内核 出错-HP 方案
  3. disk boot failure,insert system disk and press enter
  4. linux下查看nginx,apache,mysql,php的编译参数
  5. 循环for语句 if语句
  6. 分享下自己写的一个微信小程序请求远程数据加载到页面的代码
  7. 详细记录python的range()函数用法
  8. 开始使用博客了,改变从这里开始。
  9. 概率统计 —— 常犯错误
  10. 【组队学习】【32期】算法的应用