0.1 + 0.2 != 0.3背后的原理

news/2025/1/20 9:01:11

初学JavaScript,在进行小数(浮点数)运算时,经常会碰到这样的情况:0.1 + 0.2=0.30000000000000004,记得当时,教程告诉我们说,0.1 + 0.2在JavaScript运算中,它的值是不固定的,可以在后面学习和试验中,渐渐发现,这个值似乎每次都是0.30000000000000004,于是渐渐怀疑当时学习过程中关于它的和值是不固定的说法。


其实有一定编程基础的同学们应该都知道,计算机是采用二进制来表示十进制的,规则是:整数除以2,商继续除以2,得到0为止,将余数逆序排列;小数乘以2,取整,小数部分继续乘以2,取整,得到小数部分0为止,将整数顺序排列。例如:
整数转二进制小数转二进制

其实不管是十进制转二进制还是八进制、十六进制,原理都是一样的,即,基数连连除(整数)或者连乘(小数)进制转换

再回到我们最初的问题, JS 采用 IEEE 754 双精度版本(64位),并且只要采用 IEEE 754 的语言都有前面的问题。

IEEE 754 标准是IEEE浮点数算术标准(IEEE Standard for Floating-Point Arithmetic)的标准编号 ,等同于国际标准ISO/IEC/IEEE 60559 。IEEE 754 标准规定了计算机程序设计环境中的二进制和十进制的浮点数之间的交换、算术格式以及方法 。

根据前面介绍的知识,0.1 的二进制表示为:

0.1 = 2^-4 * 1.10011(0011)// (0011) 表示循环

0.2 的二进制表示为:

0.2 = 2^-3 * 1.10011(0011)// (0011) 表示循环

前面说了,JS 采用 IEEE 754 双精度版本(64位),六十四位中符号位占一位,整数位占十一位,其余五十二位都为小数位。因为 0.1 和 0.2 都是无限循环的二进制,所以在小数位末尾处需要判断是否进位(规则和十进制里的四舍五入一样)。
所以 0.1的二进制表示(0.1 = 2^-4 * 1.10011(0011)) 进位后就变成了 2^-4 * 1.10011(0011 * 12次)010,同理可得0.2的二进制表示 。把这两个二进制加起来得到 2^-2 * 1.0011(0011 * 11次)0100 , 这个值再换算成十进制就是 0.30000000000000004


所以说,0.1 + 0.2=0.30000000000000004,在JavaScript中,它的结果并非不固定的。

那么,如果需要比较0.1 + 0.20.3的关系,我们又该如何进行呢?
其实对于在大学学过数学分析、数值逼近或者高中课程代数方面证明知识的同学来说,自然可以想到让0.1 + 0.2的和减去0.3小于一个任意小的数,比如说我们可以通过他们差值是否小于0.0000000001来判断他们是否相等。JavaScript也提供了一些原生的方法,比如toFixed() 方法可把 Number 四舍五入为指定小数位数的数字,语法:NumberObject.toFixed(num)

参数描述:num,必需。规定小数的位数,是 0 ~ 20 之间的值,包括 0 和 20,有些实现可以支持更大的数值范围。如果省略了该参数,将用 0 代替。

参考内容:JavaScript toFixed() 方法
几道高级前端面试题解析

文章来源:https://blog.csdn.net/weixin_34018202/article/details/88827987
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:https://dhexx.cn/news/show-3021939.html

相关文章

项目经验总结之技术与业务之间的沟通注意事项

1. 公司的业务一般负责与客户对接,主要的任务是与客户谈需求、制定开发方案、对接技术等。 2. 技术主要负责接收开发任务,按照开发进度表来开发任务,定期与业务项目经理沟通开发的进展和遇到的问题等。 3. 业务与技术有时候好比一对冤家&am…

ActiveMQ Artemis-发布/订阅模式

点对点模式可以理解1对1,发布/订阅模式则可以理解为类似报纸订阅,你先提前通知我要订阅这份报纸,然后我发出去之后,你就可以到指定位置获取。如果在我发出去之后,你才通知我要订阅,那你就会错过之前发出去的报纸。 我们还是参考点对点模式,先创建Producers(生产者)类。…

一位高手整理的IIS FAQ

下面是一位高手整理的问题精华,大家好好看看吧,收获肯定很大的!  1.如何让asp脚本以system权限运行? 修改你asp脚本所对应的虚拟目录,把"应用程序保护"修改为"低".... 2.如何防止asp木马? 基于FileSystemObject组…

华为交换机端口限速

2000_EI系列以上的交换机都可以限速!限速不同的交换机限速的方式不一样!2000_EI直接在端口视图下面输入LINE-RATE (4 )参数可选!端口限速配置1功能需求及组网说明端口限速配置『配置环境参数』1. PC1和PC2的IP地址分别为10.10.1.1/24、10.10.1.2/24『组网需求』1. 在SwitchA上配…

linux删除不了文件, 修改文件属性也删除不了的一个解决思路

场景: 公司要求卸载软件时, 也包含卸载一个目录下的所有文件. 于是去修改删除文件的shell脚本, 添加了删除文件及文件夹的命令(当然是在root权限下的) 如: rm -rf /home/vito/**** 但发现运行shell脚本时, 死活删除不了那个目录下的文件, 当然也就删除不了目录, 同时提示----rm…

生活种种

说话 说话要用脑子,做事慎言,话多无益,嘴只是一个扬声器而已,平时一定要注意控制好调频旋钮和音控开关,否则,会给自己带来很多麻烦。讲话不要只顾一时痛快,以为人家给你笑脸就是欣赏&#xff0c…

SpringBoot 全局统一记录日志

1.记录日志 使用aop来记录controller中的请求返回日志 pom.xml引入&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency> 在完成了引入AOP依赖包后&…

RabbitMQ消息队列下载安装(Windows版本)

官网&网盘下载 RabbitMQ官网下载址&#xff1a;Installing on Windows — RabbitMQ RabbitMQ是用Erlang编程语言进行开发&#xff0c;所以先要安装Erlang语言开发包 Erlang官网下载地址&#xff1a;Downloads - Erlang/OTP 百度网盘下载链接&#xff1a;百度网盘 请输入提…

SpringBoot正常启动后,却无法访问

今天真的被这个问题搞死了,出于迷之自信,掉在坑里了。 今天写了一个ActiveMQ与SpringBoot的整合,写好之后,想用POSTMAN测试一下,直接测接口,发现一点反应也没有,代码后台也不报错。POSTMAN提示的信息就是没有连接成功,是一个错误的链接。(Could not get any response)…

《Java编程思想》读书笔记(9)

一些listene接口中只定义了一个方法&#xff0c;因此要实现这种接口的工作量并不大&#xff0c;因为只要写完这一个方法&#xff0c;接口也就实现了。但是如果要使用有多个方法的listener的话&#xff0c;就会比较麻烦了&#xff0c;因为必须要实现接口中定义的所有方法&#x…