当前位置: 首页 > news >正文

为什么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后,发现经常崩溃,明显内存可能除了问题,看了内存后发现了问题。 见下图&#xf…...

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 使用之前封装的断言方法&#xff0c…...

学习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>我是不建议嵌套使用的&#xff0c;平级也能调用&#xff0c…...

响应式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加密解密工具类库

前言 在我们日常开发工作中&#xff0c;为了数据安全问题对数据加密、解密是必不可少的。加密方式有很多种如常见的AES&#xff0c;RSA&#xff0c;MD5&#xff0c;SAH1&#xff0c;SAH256&#xff0c;DES等&#xff0c;这时候假如我们有一个封装的对应加密解密工具类可以直接…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)

推荐 github 项目:GeminiImageApp(图片生成方向&#xff0c;可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...