为什么JavaScript中0.1 + 0.2 ≠ 0.3
JavaScript中的浮点数运算有时候会出现一点偏差。下面解释为什么0.1 + 0.2 ≠ 0.3,以及如果你需要精确运算应该怎么做。
如果1 + 2 = 3,那么为什么在JavaScript中0.1 + 0.2 ≠ 0.3?这个原因与计算机科学和浮点数运算有关。
我建议你打开浏览器的控制台,输入0.1 + 0.2
来查看结果。
不,你不需要调整浏览器–这就是它应该的工作方式,根据定义JavaScript语言的ECMAScript标准:
“Number类型正好有18437736874454810627(即 2^64 - 2^53 + 3)个值,表示双精度64位格式IEEE 754标准中规定的值”——ECMAScript语言规范
JavaScript使用number基本类型表示数值,所有JavaScript数字实际上都是浮点数 —— 即使是整数。
这里的关键是JavaScript实现了IEEE浮点算术标准。让我们看看这意味着什么。
这里发生了什么?
“你的语言没有出错,它在做浮点运算。计算机只能本地存储整数,所以它们需要某种方法来表示十进制数。这种表示法不是完全准确的。这就是为什么‘0.1 + 0.2 != 0.3’的情况经常发生。” —— Erik Wiffin 在 0.30000000000000004.com
你可能已经知道所有数字在计算机中都是二进制的。
在二进制中,值以2进制的形式表示为0和1的序列,而不是我们通常使用的10进制。
我们得到浮点舍入误差的原因令人着迷,这与循环小数的概念有关。
只有当分母是基数的质因数时,分数才能“整洁地”(意思是作为没有循环小数的精确值)存储。
10进制的质因数是2和5,所以1/2、1/4、1/5、1/8和1/10可以整洁地表达,但是1/3、1/6、1/7和1/9是循环小数。
2进制的惟一质因数是2,所以只有1/2可以整洁地表示 —— 任何其他值都成为循环小数。
这意味着当我们使用0.1这样的10进制小数(1/10)时,它可以用一个十进制数字表示,但在二进制中却不行。
可以在二进制中整洁地表达的唯一分数是0.5(1/2)。可以自己尝试使用 IEEE-754浮点转换器。
浮点数也更慢
JavaScript中的浮点数与整数相比,通常情况下的表现也不同。例如,它们在for
循环中更慢。
我们用jsPerf来测试两个微性能案例:
在jsPerf.com上查看这些测试案例
虽然差异不大,但浮点运算的平均速度确实比只使用整数值的基本for循环稍微慢一点。
这发生的原因是上一节中解释的那些二进制中浮点数的额外复杂性。
当然,代码库中这个差异还不足以造成影响,但是这是JavaScript的一个有趣的特性。
如果需要精确计算该怎么办?
如果你需要精确的JavaScript计算,例如处理金融交易,那么最好使用整数。
虽然所有的JavaScript数字在内部都表示为浮点值,但是在处理整数值时,你不会遇到不精确的问题,至少在低于 MAX_SAFE_INTEGER(2^53 - 1
)的范围内:
一个方法是只以分工作——例如,通过将19.99美元的值表示为整数1999来代表。
在GitHub Gist上查看原始代码
另一种方法是创建一个对象来表示货币,并在内部使用整数值。例如:
在GitHub Gist上查看原始代码
许多库已经以更强大的方式解决了这个问题,包括accounting.js、currency.js、money.js和Numeral.js。
最后,你可以考虑使用BigInt基本类型,它可以表示任意大的整数(但不能表示浮点值):
在GitHub Gist上查看原始代码
TypeScript也支持BigInt,所以在TypeScript中使用BigInt可能是一个避免意外使用浮点数据的好选择。
结论
我对0.1 + 0.2实际上应该等于0.30000000000000004感到非常惊讶,因为浮点数运算。
这看起来像一个等待发生的错误,但是没有明确的解决方法,因为ECMAScript规范要求0.1 + 0.2 ≠ 0.3。
幸运的是,整数运算避免了讨厌的舍入误差,所以通过使用JavaScript数字(如果坚持整数)可以实现精确计算。
对于任意精度或确保永远不会有十进制值,你可以考虑使用JavaScript更新的BigInt基本类型。
你也可能会发现exact-math或math.js库很有帮助。它们都是用于使用JavaScript执行精确计算的。
编码快乐!📏🖥️📐⌨️😄
相关文章:

为什么JavaScript中0.1 + 0.2 ≠ 0.3
JavaScript中的浮点数运算有时候会出现一点偏差。下面解释为什么0.1 0.2 ≠ 0.3,以及如果你需要精确运算应该怎么做。 如果1 2 3,那么为什么在JavaScript中0.1 0.2 ≠ 0.3?这个原因与计算机科学和浮点数运算有关。 我建议你打开浏览器的控制台,输入0.1 0.2来查看结果。…...

Unity关于纹理图片格式带来的内存问题和对预制体批量格式和大小减半处理
我们经常会遇到内存问题,这次就是遇到很多图片的默认格式被改成了RGB32,导致Android打包后运行内存明显增加。 发生了什么 打包Android后,发现经常崩溃,明显内存可能除了问题,看了内存后发现了问题。 见下图…...

2024美赛数学建模思路 - 案例:ID3-决策树分类算法
文章目录 0 赛题思路1 算法介绍2 FP树表示法3 构建FP树4 实现代码 建模资料 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法,就是频繁模…...

GitHub图床搭建
1 准备Github账号 如果没有Github账号需要先在官网注册一个账号 2 创建仓库 在github上创建一个仓库,随便一个普通的仓库就行,选择公共仓库 并且配置github仓库的pages,选择默认访问的分支及默认路径 3 github token获取 github token创…...

DQN、Double DQN、Dueling DQN、Per DQN、NoisyDQN 学习笔记
文章目录 DQN (Deep Q-Network)说明伪代码应用范围 Double DQN说明伪代码应用范围 Dueling DQN实现原理应用范围伪代码 Per DQN (Prioritized Experience Replay DQN)应用范围伪代码 NoisyDQN伪代码应用范围 部分内容与图片摘自:JoyRL 、 EasyRL DQN (Deep Q-Networ…...

C++ 编程需要什么样的开发环境?
C 编程需要什么样的开发环境? 在开始前我有一些资料,是我根据网友给的问题精心整理了一份「C的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!&#…...
Unity文字游戏开发日志(1)—— 打字机效果
作者是一名OIer,因为兴趣,想在寒假期间开发一款文字游戏的demo。 本博客仅用作记录,马蜂极度不符合规范。 但是,可以用来避坑。 1.等待功能——使用的是协程函数,且调用与常规调用函数不同。 private IEnumerator Sco(){isScoe…...

从0开始python学习-48.pytest框架之断言
目录 1. 响应进行断言 1.1 在yaml用例中写入断言内容 1.2 封装断言方法 1.3 在执行流程中加入断言判断内容 2. 数据库数据断言 2.1 在yaml用例中写入断言内容 2.2 连接数据库并封装执行sql的方法 2.3 封装后校验方法是否可执行 2.4 使用之前封装的断言方法,…...

学习JavaEE的日子 day13补 深入类加载机制及底层
深入类加载机制 初识类加载过程 使用某个类时,如果该类的class文件没有加载到内存时,则系统会通过以下三个步骤来对该类进行初始化 1.类的加载(Load) → 2.类的连接(Link) → 3.类的初始化(In…...

C# WebApi传参及Postman调试
概述 欢迎来到本文,本篇文章将会探讨C# WebApi中传递参数的方法。在WebApi中,参数传递是一个非常重要的概念,因为它使得我们能够从客户端获取数据,并将数据传递到服务器端进行处理。WebApi是一种使用HTTP协议进行通信的RESTful服…...
npm install 卡住不动的六种解决方法
1.重装 检查网络设置,删除node_modules重新npm install 2. 配置npm代理 // 配置nmp代理来提高速度,如设置淘宝镜像 npm config set registry https://registry.npm.taobao.org// 查看配置是否成功 npm config get registry// 成功后重新npm install安…...

Vue高级(二)
3.搭建vuex环境 创建文件:src/store/index.js //引入Vue核心库import Vue from vue//引入Vueximport Vuex from vuex//应用Vuex插件Vue.use(Vuex)//准备actions对象——响应组件中用户的动作const actions {}//准备mutations对象——修改state中的数据const mutat…...
MongoDB面试系列-02
1. MongoDB 中必须调用 getLastError 来确保写操作生效吗? MongoDB中不管有没有调用getLastError(又称为Safe Mode),服务器执行的操作都会一样。 而调用getLastError只是为了确认写操作是否成功提交,但是写操作的安全…...
2024.1.17
今天我已经回家了,感觉家就像我的温柔乡一样,一到了家,就不想学习了,这是很不对的事情,不该如此堕落,还是要像在学校一样该干什么干什么,所以说还是复习和写了一下曾经写过的代码。 #define _C…...
openssl3.2 - 官方demo学习 - encrypt - rsa_encrypt.c
文章目录 openssl3.2 - 官方demo学习 - encrypt - rsa_encrypt.c概述笔记END openssl3.2 - 官方demo学习 - encrypt - rsa_encrypt.c 概述 从内存中的DER共钥数据构造pub_key, 用公钥加密明文, 输出密文. 非对称加密 从内存中的DER私钥数据构造priv_key, 用私钥解密密文, 输出…...
ARCGIS PRO SDK Annotation 概念及操作
使用Annotation的API功能。Annotation 的API功能位于ArcGIS.Core.dll中。Annotation API通常与地理数据库、地图创作和编辑结合使用。ArcGIS.Core.dll ArcGIS.Core.Data.map API中的几乎所有方法都应该在MCT上调用。 一、Annotation featureclass 1、从GeodatabaseGeodatabase数…...

dp专题13 零钱兑换II
本题链接:. - 力扣(LeetCode) 题目: 思路: 根据题意,这是一道很裸的背包问题,其中这里是返回 背包方案数 的。 我们可以直接推出公式 : dp [ j ] dp[ j - coins[ i ] ] 在我之前…...

el-dialog嵌套使用,只显示遮罩层的问题
直接上解决方法 <!-- 错误写法 --><el-dialog><el-dialog></el-dialog></el-dialog><!-- 正确写法 --><el-dialog></el-dialog><el-dialog></el-dialog>我是不建议嵌套使用的,平级也能调用,…...
响应式Web开发项目教程(HTML5+CSS3+Bootstrap)第2版 例3-5 CSS3 动画
代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>CSS3 动画</title> <style> .img {width: 150px; } keyframes rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg);} } img…...

一款实用的.NET Core加密解密工具类库
前言 在我们日常开发工作中,为了数据安全问题对数据加密、解密是必不可少的。加密方式有很多种如常见的AES,RSA,MD5,SAH1,SAH256,DES等,这时候假如我们有一个封装的对应加密解密工具类可以直接…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...

给网站添加live2d看板娘
给网站添加live2d看板娘 参考文献: stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下,文章也主…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...