如何解决0.1 +0.2===0.30000000000000004类问题

解决JavaScript中0.1+0.2不等于0.3问题 主要介绍了解决JavaScript中0.1+0.2不等于0.3问题,需要的朋友可以参考下 立即下载

在这里插入图片描述

上篇博客深度剖析了0.1+0.2 === 0.30000000000000004的原因。
这篇博客将主要提供几种解决小数精度丢失问题的Javascript类库的代码示例,以及简单的原生EcmaScript方法的代码示例。

一.类库部分

math.js

math.js是JavaScript和Node.js的一个广泛的数学库。支持数字,大数,复数,分数,单位和矩阵等数据类型的运算。

官网:http://mathjs.org/
GitHub:https://github.com/josdejong/mathjs

0.1+0.2 ===0.3实现代码:

var math = require('mathjs')
console.log(math.add(0.1,0.2))//0.30000000000000004
console.log(math.format((math.add(math.bignumber(0.1),math.bignumber(0.2)))))//'0.3'
decimal.js

为 JavaScript 提供十进制类型的任意精度数值。

官网:http://mikemcl.github.io/decimal.js/

GitHub:https://github.com/MikeMcl/decimal.js

var Decimal = require('decimal.js')
x = new  Decimal(0.1)
y = 0.2
console.log(x.plus(y).toString())//'0.3'
bignumber.js

用于任意精度算术的JavaScript库。

官网:http://mikemcl.github.io/bignumber.js/

Github:https://github.com/MikeMcl/bignumber.js

var BigNumber = require("bignumber.js")
x = new BigNumber(0.1)
y = 0.2
console.log(x.plus(y).toString())//'0.3'
big.js

用于任意精度十进制算术的小型快速JavaScript库。
官网:http://mikemcl.github.io/big.js/
Github:https://github.com/MikeMcl/big.js/

var Big = require("big.js")
x = new Big(0.1)
y = 0.2
console.log(x.plus(y).toString())//'0.3'

有一个需要注意的点,使用类库此时输出的0.3是String类型,因此若想保持为Number类型,可使用parseFloat()方法。

还有一个注意点,在本地install测试的时候,npm i mathjs -g ,require是也要require(‘mathjs’),而不是带点的math.js,因为josdejong这哥们在创建项目的时候就命名为mathjs,而同时拥有上述decimal.js, bignumber.js和big.js的MikeMcl,项目名字就带了dot,因此安装和引入时,都是xxx.js的形式。

如何在这三个类库之间做选择,还需要大家自己根据具体情况具体分析,我在这里就不赘述了。

最后,教大家一个线上直接测试的网站,https://npm.runkit.com,子路径输入想要测试的Node.js package名,就可以实现在线测试包中的api了。
例如:
math.js:https://npm.runkit.com/mathjs
big.js:https://npm.runkit.com/big.js

二、原生方法

类库其实很强大,我们计算0.1+0.2其实只是用到了冰山一角,那么我们如何使用原生的EcmaScript代码来应用于简单的问题场景呢?

这就要用到Number.prototype.toFixed()这个方法了。

浮点数运算

toFixed() 方法

浮点数运算的解决方案有很多,这里给出一种目前常用的解决方案, 在判断浮点数运算结果前对计算结果进行精度缩小,因为在精度缩小的过程总会自动四舍五入。

toFixed() 方法使用定点表示法来格式化一个数,会对结果进行四舍五入。语法为:

JavaScript 代码:
numObj.toFixed(digits)
参数 digits 表示小数点后数字的个数;介于 0 到 20 (包括)之间,实现环境可能支持更大范围。如果忽略该参数,则默认为 0。

返回一个数值的字符串表现形式,不使用指数记数法,而是在小数点后有 digits 位数字。该数值在必要时进行四舍五入,另外在必要时会用 0 来填充小数部分,以便小数部分有指定的位数。 如果数值大于 1e+21,该方法会简单调用 Number.prototype.toString()并返回一个指数记数法格式的字符串。

特别注意:toFixed() 返回一个数值的字符串表现形式。

具体可以查看 MDN中的说明,那么我们可以这样解决精度问题:

JavaScript 代码:

parseFloat((数学表达式).toFixed(digits)); // toFixed() 精度参数须在 0 与20 之间,建议传2。2是为了处理5/9这样的无限循环小数。
// 运行
parseFloat((0.1 + 0.2).toFixed(10))//结果为0.3
parseFloat((0.3 / 0.1).toFixed(10)) // 结果为 3  
parseFloat((0.7 * 180).toFixed(10))//结果为126
parseFloat((1.0 - 0.9).toFixed(10)) // 结果为 0.1   
parseFloat((9.7 * 100).toFixed(10)) // 结果为 970 
parseFloat((2.22 + 0.1).toFixed(10)) // 结果为 2.32

在Browser环境精度参数允许0~100位之间(包括100),测试版本为Chrome62(64位)和Firefox56 (32 位)。
在Nodejs环境中,只能是0~20之间,测试版本为v6.9.5。

其次就是toFixed()的浏览器兼容性讨论,MDN给出的结果全部是YES,无论desktop端还是mobile端,也就是说不用担心toFixed()的兼容性问题(ie8- 我们不做讨论)。

desktop端:

mobile端:

Thanks:
http://www.css88.com/archives/7340#more-7340
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed


2019.7.28更新:

parseFloat((5/9).toFixed(10))返回0.5555555556。所以更为建议的做法是parseFloat((5/9).toFixed(2)),把小数控制在2位。

钱的计算是最复杂的,例如人民币的计算,其实最终精确到分就很可以了,元角。厘这个单位很小,生活中已经很少见了。

期待和大家交流,共同进步,欢迎大家加入我创建的与前端开发密切相关的技术讨论小组:

努力成为优秀前端工程师!

生信分析实战指南:Linux环境下EMBOSS的安装与核心功能详解 本文详细介绍了在Linux环境下安装和使用EMBOSS工具包的实战指南,涵盖源码编译、包管理器安装和Conda安装三种方法,并演示了序列比对、序列特征提取和引物设计等核心功能。EMBOSS作为生物信息学领域的开源工具集,适用于序列分析、蛋白质结构预测等多种任务,帮助研究人员高效完成生信分析工作。 阅读详情

相关推荐

Unity工业数据可视化:基于ModbusTCP的实时数据通信实战

本文详细介绍了在Unity中实现工业数据可视化的核心方法,重点讲解了基于ModbusTCP协议与PLC等工业设备进行实时数据通信的实战流程。内容涵盖NModbus库的集成、Modbus Slave模拟器的使用、TCP连接的建立与多线程安全通信、数据读写与解析,以及如何将实时数据驱动3D场景,为构建工业数字孪生与监控系统提供完整解决方案。

ol7890123的博客 554

0.1 + 0.2 不等于0.3 问题,精度的丢失和解决办法

10个0.1相加不等于1; 这是因为浮点数精度丢失的问题,首先知道在计算机中数字是以二进制的方式存在的,那么在CPU中计算0.1+0.1时实际上是0.1的二进制的相加; ( 0.1 => 0.0001 1001 1001 1001…无限循环) 如上,因为是无限循环,所以CPU计算时不会存储太多位,因此会在某位初截断。 根据IEEE-754标准,最大保留0.1后小数点后17位也就是这样: 所以也就有在编程环境中把1分成三份,再加起来就不再是1了。同样0.1+0.2也就不等于0.3了。 IEEE-75

Lazy_Goat的博客 3070

mpu6050原理图_STM32控制 MPU6050 六轴陀螺仪资料汇总

一般使用MPU6050的步骤是先驱动I2C总线,然后初始化MPU6050,从MPU6050读取数据,最后是数据的处理。本文档详细介绍有关MPU6050 三维角度传感器电子陀螺仪使用说明。附件内容提供该 MPU6050模块原理图,配套STM32代码,相关数据手册及参考文档。实物连接图:MPU6050 六轴陀螺仪特点:使用芯片:MPU-6050供电电源:3-5v(内部低压差稳压)通信方式:标...

weixin_39911056的博客 4758

为什么 0.1 + 0.2 != 0.3?如何解决这个问题?

因为在 0.1 +0.2 进行计算的时候,实际上计算的是这两个数字在计算机里所存储的二进制 0.1 和 0.2 在进行二进制转换的时候会出现无限循环的情况. 解决方案一:可以将其转换为整数后在进行运算,运算后再转为对应的小数 (例一) 解决方案二:可以利用ES6中的极小数Number.EPSILON来进行判断 判断 0.1 + 0.2 是否等于 0.3,可以将两个数字相加的结...

qq_43525996的博客 3087

flowable表中文注释-表结构-主要表结构字段注释-sql脚本

flowable表结构中文注释,主要表结构字段注释,sql执行脚本,包含MySQL版和Oracle版sql脚本。

bushinakeshu的博客 1069

串行通信原理及实验仿真

1. 处理器与外部设备通信的两种方式: 并行通信和串行通信 并行通信是指数据的各个位用多条数据线同时进行传输 优点:传输速度快 缺点:占用引脚资源多 串行通信是将数据分成一位一位的形式在一条传输线上逐个传输 优点:通信线路简单,占用引脚资源少 缺点:传输速度慢 2. 串行通信的通信方式: 同步通信和异步通信 同步通信:带有时钟同步信号的数据传输;发送方和接收方在同一时钟的控制下,同步传输数据。 异步通信:不同时钟同步信号的数据传输。发送方和接收方使用各自的时钟控制数据的发送和接收过程。 3. 串行通

gemengxia的博客 4322

为什么 0.1 + 0.2 不等于0.3?如何解决这个问题?

一、开头 我们都知道0.1 + 0.2 !== 0.3,而是0.30000000000000004,那么是为什么?我们都知道计算机在内部实现中使用的是二进制,0.1也是不例外的,此时我们将0.1转换为二进制数据表示可以表示为:0.0001100110011001100...(1100无限循环),0.2转换为二进制数据可以表示为0.00110011001100...(1100循环),此时这两个数均为无限循环小数,那么该如何去存储呢? 二、如何存储二进制小数 不同的语言可能会有不同的存储标准,javascrip

weixin_47450807的博客 9108

ComfyUI安装包运行前准备:增加虚拟内存

在Windows系统中,虚拟内存是一种重要的系统资源管理机制,它主要通过将硬盘空间用作内存来扩展系统的可用内存容量。以下是虚拟内存的主要作用: 1. 扩展物理内存容量 当物理内存(RAM)不足时,系统会将一部分数据从内存转移到硬盘上的虚拟内存区域(也称为“分页文件”或“交换文件”)。这样可以为正在运行的程序提供额外的“内存空间”,确保系统能够继续运行,而不会因为内存不足而崩溃。 2. 提高系统稳定性 虚拟内存为系统提供了一个缓冲区。如果没有虚拟内存...

聚梦小课堂 1万+

为什么0.1+0.2=0.30000000000000004?怎么解决这个问题?

为什么0.1+0.2=0.30000000000000004?怎么解决这个问题?     在我们平时写代码的时候,可能会出现和我们的认知不符的情况。比如在我们的认知里0.1+0.2=0.3,但代码运行的结果却是0.30000000000000004。float类型和double类型的数在运算时有可能会有误差,也有可能不会出现误差。代码示例如下: public class Demo { public static void main(String[] args) { double a=

weixin_46305401的博客 1478

ZY1-02D (ZY1E)多光谱数据预处理

资源一号02D卫星(5米光学卫星)于2019年9月12日成功发射,卫星搭载的两台相机,可有效获取115公里幅宽的9谱段多光谱数据以及60公里幅宽的166谱段高光谱数据,其中全色谱段分辨率可达2.5米、 多光谱为10米、高光谱优于30米,高光谱载荷可见近红外和短波红外光谱分辨率分别达到10纳米和20纳米。

热爱分享,热爱记录 4829

YOLO26改进策略【YOLO和Mamba】| 2024 VM-UNet,高效的特征提取模块VSS block 二次创新提高精度

VM-UNet模型设计的出发点是解决现有CNN-based和模型在医学图像分割中的局限性,利用(SSMs)的优势,提出一种更有效的医学图像分割模型。具体来说,CNN-based模型在捕捉长距离信息方面存在不足,而模型由于自注意力机制的二次复杂度导致计算负担较重。SSMs模型如Mamba不仅在建模长距离依赖方面表现出色,还具有线性计算复杂度,这为VM-UNet的设计提供了理论基础。

Limiiiing的博客 214

解决js 0.1 + 0.2 = 0.30000000000000004 的位数精度问题

解决js 0.1 + 0.2 = 0.30000000000000004 的位数精度问题 parseFloat((0.1 + 0.2).toFixed(10))

qq_36571836的博客 377

2024年厦门市第31届小学生C++信息学竞赛试题与解析(第一部分选择题1-10)

2024年厦门市第31届小学生C++信息学竞赛试题与解析(第一部分选择题1-10)

汉克老师的博客 106

解决java中0.1+0.2=0.30000000000000004的问题

这是由于计算机采用二进制存储浮点数,而二进制无法准确地表示十进制小数0.1和0.2,会发生精度误差。在计算0.1+0.2时,计算机实际上是计算这两个数的近似值的和,因此得到的结果也是一个近似值,其末尾的小数位可能会有误差。

淅沥的博客 819

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

彻底搞懂0.1+0.2≠0.3:从0.30000000000000004项目看穿浮点数陷阱

你是否也曾在调试时遇到这样的诡异现象:明明0.1加0.2的数学结果应该是0.3,可程序却返回0.30000000000000004?这个看似简单的计算错误,实则暴露了计算机世界最基础的数值表示陷阱。本文将通过解析03/0.30000000000000004项目(GitHub加速计划浮点数数学示例库),系统讲解浮点数原理、跨语言表现及工程化解决方案,让你彻底掌握如何规避这类隐藏的数值风险。 ## ...

gitblog_00972的博客 709

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

解决0.1+0.2问题的7种方法:0.30000000000000004.com实用教程

在开发过程中,你是否遇到过 `0.1 + 0.2 = 0.30000000000000004` 这样令人困惑的计算结果?这是由于计算机采用二进制浮点数存储导致的精度误差问题。本文将介绍7种简单有效的方法,帮助你在不同编程语言中解决这一经典问题,让你的数值计算更加准确可靠! ### 1. 使用Decimal类型(Python/Java/C#) 许多编程语言提供了专门的高精度 decimal 类型来

gitblog_00935的博客 1120

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

为什么 0.1 + 0.2 !== 0.3?如何解决这个问题?

众所周知,JavaScript在某些浮点数的运算时会出现精度丢失的问题,比如在控制台中输入0.1+0.2,得到的是0.30000000000000004,而不是精确的0.3,这是什么原因呢? 在计算机基础中我们应该学过,计算机中所有的数据最终都是以二进制的形式存储的,当然数字的存储也不例外。 当计算0.1+0.2的时候,实际上计算的是这两个数字在计算机里所存储的二进制,0.1 和 0.2 在转换为二进制表示的时候会出现位数无限循环的情况。当然计算机不会用无限的空间去存储这些无限循环的二进制数...

mubo970901的博客 6432

0.1 + 0.2 === 0.3为什么是false,如何解决

看如下代码,最后执行的结果为 false,但在数学角度来说,他们应该是相等的console.log(0.1 + 0.2 === 0.3); // false 为什么会出现上述的问题我们在浏览器上执行会发现 0.1 + 0.2 是等于 0.30000000000000004问题的原因在于,二进制浮点数中的 0.1 和 0.2 并不是十分精确,它们相加的结果并非刚好等于0.3,而是一个比较接近的数字 0.300000000

wfly blog 4057

在js中0.1+0.2=0.30000000000000004的原因及解决的方法

// 所有遵循IEEE754规范的语言都会出现这么一个问题0.1+0.2=0.30000000000000004,出现这个原因是二进制浮点数中的0.1和0.2并不十分精确 我在解决此问题的时候用的是保留两位数的方法 例: var a=0.1 b=0.2 sum=a+b console.log(a+b) console.log(sum.toFixed(2)== ...

weixin_34199405的博客 2029

关于JavaScript中0.1+0.2=0.30000000000000004的问题

不只是JavaScript,所有遵循IEEE754规范的语言都会出现这么一个问题 0.1+0.2=0.30000000000000004 简单来说,出现这种问题的原因是二进制浮点数中的0.1和0.2并不十分精确 所以最常见的方法是设定一个误差值来判断0.1+0.2是否和0.3相等 而这个误差值通常是2^-52(2.220446049250313e-16) 从ES6开始,该值定义在Numb...

Aproducer的博客 1067

深入探讨:为什么会出现 0.30000000000000004 以及如何避免浮点数精度问题

在编程和数据分析中,处理浮点数是常见的任务。然而,浮点数的精度问题常常困扰着开发者。一个典型的例子是,当你尝试在 Python 中生成从 0.1 到 0.9 的浮点数序列时,你可能会意外地得到像 0.30000000000000004 这样的值。本文将探讨这种现象的原因,并提供一些解决方案。

weixin_44212848的博客 1134

JavaScript中为什么 0.1 + 0.2 != 0.3

涉及面试题:为什么 0.1 + 0.2 != 0.3?如何解决这个问题? 原因,因为 JS 采用 IEEE 754双精度版本(64位),并且只要采用 IEEE 754的语言都有该问题 我们都知道计算机是通过二进制来存储东西的,那么 0.1 在二进制中会表示为 // (0011) 表示循环 0.1 = 2^-4 * 1.10011(0011) 我们可以发现,0.1 在二进制中是无限循环的一些数字,其实不只是 0.1,其实很多十进制小数用二进制表示都是无限循环的。这样其实没什么问题,但是 JS采用.

LuckXinXin的博客 5090

为什么 0.1 + 0.2 不等于 0.3?开源项目 0.30000000000000004 深度解析与解决方案

你是否曾在代码中遇到 `0.1 + 0.2 = 0.30000000000000004` 这样匪夷所思的结果?作为开发者,浮点数(Floating Point)精度问题就像一颗隐藏的炸弹,可能在金融计算、科学模拟等关键场景中造成灾难性后果。本文将从底层原理到实战解决方案,全面解析这一经典问题,助你彻底摆脱浮点数陷阱。 ## 一、浮点数精度问题的本质:为什么简单加法会出错? ### 1.1 计算...

gitblog_00203的博客 953
上一篇: 实用webpack插件之DefinePlugin
下一篇: PostCSS真的太好用了!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

趁你还年轻233

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值