您知道JavaScript中的0.1 + 0.2 ≠ 0.3吗?

凯特林
• 阅读 1457

嘿👋

自从我使用JavaScript已有一段时间了。昨天,我经历了一个非常奇怪的行为。

您知道JavaScript中的0.1 + 0.2 ≠ 0.3吗?

同时我真的很困惑和惊讶😕。最初我以为,我发现了一个论点再次诅咒JavaScript。

但是,经过一些研究,我发现这不是错误。这是数学,也是计算机处理数字的方式。

好吧,还有其他一些怪异的东西-

您知道JavaScript中的0.1 + 0.2 ≠ 0.3吗?

幕后发生了什么?

它背后的简单逻辑是计算机使用以2基的(二进制)浮点数系统

让我们用一个非常简单的类比来详细了解它。

我们人类使用10进制(十进制)的数字系统来读取,写入和理解日常生活中的数字。

当有人告诉我们1/10时,我们理解并认为它是0.1,但是对于1/3,我们没有确切的值。它是0.333333…..(永无止境),因此,根据我们的理解,我们将其视为0.3(最近的可能的完整数)。

电脑也是如此。当使用JavaScript时,我们写-

let a = 0.1; 

众所周知,计算机以二进制格式存储,因此该数字将转换为二进制,但是每个可能的实数都无法转换为二进制。如我们所见,0.1不可能有确切的二进制表示形式,因此JavaScript会将0.1解释为十进制中最接近的二进制数,即-

0.1000000000000000055511151231257827021181583404541015625 

以二进制格式-

0.0001100110011001100110011001100110011001100110011001101 

同样地,0.2被解释为-

0.200000000000000011102230246251565404236316680908203125 

所以当我们做0.1 + 0.2时

0.1000000000000000055511151231257827021181583404541015625
+
0.200000000000000011102230246251565404236316680908203125
=
0.3000000000000000166533453693773481063544750213623046875 

真正有趣的是,即使此输出也被转换为最接近的二进制数,因为JavaScript数字也不能表示此精确结果,并且以十进制表示-

0.3000000000000000444089209850062616169452667236328125 

现在,我们需要了解在控制台记录该值时会发生什么。

JavaScript不会记录数字的最后一个小数位。取而代之的是,JavaScript仅注销从其附近的其他JavaScript编号中唯一标识该JavaScript编号所需的最小位数。

因此,例如,我们记录值-

console.log(0.1000000000000000055511151231257827021181583404541015625)
// 0.1 

输出为0.1

因此,我们尝试记录0.1 + 0.2的结果,

正如我们已经得出的结论是-

0.3000000000000000444089209850062616169452667236328125 

因此,JavaScript注销了最小位数以唯一标识该数字,即-

0.30000000000000004 

所以这就是为什么0.1 + 0.2的答案是0.30000000000000004

这里要注意的非常重要的一点是,JavaScript数字数据类型实际上不是数字,它是 IEEE 754双精度(64位)浮点数或“双精度”。

此行为不仅限于JavaScript。也已经用其他语言看到过它。有关更多详细信息 -https://0.30000000000000004.com/

我希望,现在您对有人问为什么0.1 + 0.2不是0.3时要说的话有了一个清晰的认识

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
2年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
2年前
35岁是技术人的天花板吗?
35岁是技术人的天花板吗?我非常不认同“35岁现象”,人类没有那么脆弱,人类的智力不会说是35岁之后就停止发展,更不是说35岁之后就没有机会了。马云35岁还在教书,任正非35岁还在工厂上班。为什么技术人员到35岁就应该退役了呢?所以35岁根本就不是一个问题,我今年已经37岁了,我发现我才刚刚找到自己的节奏,刚刚上路。
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
2个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这