js小数计算丢失精度问题

2023-10-27

问题描述

js在计算小数计算如 1-0.2 的时候会丢失精度,即 1-0.2 = 0.19999999999999996;

例如:


			console.log( 1 - 0.8 );  //输出 0.19999999999999996 
			console.log( 6 * 0.7 );  //输出 4.199999999999999 
			console.log( 0.1 + 0.2 );  //输出 0.30000000000000004 
			console.log( 0.1 + 0.7 );  //输出 0.7999999999999999 
			console.log( 1.2 / 0.2 );  //输出 5.999999999999999 

产生原因

计算机能读懂的是二进制,进行运算的时候,实际上是把数字转换为了二进制进行的 这个过程 丢失了精度

通常的解决办法

  1. 例如: console.log(1-0.8); 变为 console.log((1 * 10 - 0.8 * 10) / 10)

  2. 但是: 9033742.2*100 ----->903374219 (还是有一些特殊情况 不能直接*10的n次方)

通用解决办法

根据上述原理 做一下修改小数点截取转数字在计算,可以封装一些方法出来解决此类问题。如下所示(Math.pow(x, y);表示求x的y次方):


		function floatAdd(arg1,arg2){    
		    var r1,r2,m;    
		    try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}    
		    try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}    
		    m=Math.pow(10,Math.max(r1,r2));    
		    return (arg1*m+arg2*m)/m;    
		}    
		      
		//减    
		function floatSub(arg1,arg2){    
		    var r1,r2,m,n;    
		    try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0}    
		    try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0}    
		    m=Math.pow(10,Math.max(r1,r2));    
		    //动态控制精度长度    
		    n=(r1>=r2)?r1:r2;    
		    return ((arg1*m-arg2*m)/m).toFixed(n);    
		}    
		       
		//乘    
		function floatMul(arg1,arg2)   {     
		    var m=0,s1=arg1.toString(),s2=arg2.toString();     
		    try{m+=s1.split(".")[1].length}catch(e){}     
		    try{m+=s2.split(".")[1].length}catch(e){}     
		    return Number(s1.replace(".","")) * Number(s2.replace(".","")) /Math.pow(10,m);     
		}     
		      
		      
		//除   
		function floatDiv(arg1,arg2){     
		    var t1=0,t2=0,r1,r2;     
		    try{t1=arg1.toString().split(".")[1].length}catch(e){}     
		    try{t2=arg2.toString().split(".")[1].length}catch(e){}     
		        
		    r1=Number(arg1.toString().replace(".",""));  
		   
		    r2=Number(arg2.toString().replace(".",""));     
		    return (r1/r2)*Math.pow(10,t2-t1);     
		}

补充解决方案

使用toFixed(),假如丢失精度之前是三位小数,就a.toFixed(3),表示保留三位小数,toFixed()函数会四舍五入(保留三位小数的话假如第四位大于等于5,第三位会加一)。

在特定情况下会存在问题,(105.1 * 10000)/ 12 = 12511.905,但是丢失精度会变成12511.9049999,如果保留两位小数会错误

最有效方案

const $math = require('mathjs') 

function comp (_func, args) {
  let t = $math.chain($math.bignumber(args[0])) 
  for (let i = 1; i < args.length; i++) { 
    t = t[_func]($math.bignumber(args[i])) 
  } 
  // 防止超过6位使用科学计数法
  return parseFloat(t.done())
}

// 处理精度丢失问题
export const math = {
  // 加法运算
  add () {
    return comp('add', arguments) 
  },
  // 减法运算
  subtract () {
    return comp('subtract', arguments) 
  },
  // 乘法运算
  multiply () {
    return comp('multiply', arguments) 
  },
  // 除法运算
  divide () {
    return comp('divide', arguments) 
  }
}

参考文章

js小数计算丢失精度问题解决方法_心郎的博客-CSDN博客_js小数精度缺失

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

js小数计算丢失精度问题 的相关文章

随机推荐

  • 欧科云链:2023年5月链上安全事件盘点

    一 基本信息 2023年5月安全事件约造成1800万美元损失 相比上月有显著下降 但安全事件发生频率并未减少 其中针对Jimbos Protocol的攻击造成了约750万美元损失 Arbitrum链的Swaprum项目Rug Pull造成了
  • C++继承-基本语法--继承方式--继承同名成员处理方式--多继承语法--菱形继承

    1 基本语法 继承 减少重复代码 语法 class 子类 继承方式 父类 子类也叫派生类 父类也叫基类 派生类中的成员包括两大部分 一类是从基类继承过来的 一类是自己增加的成员 从基类继承过来的表现其共性 而新增的成员体现了其个性 incl
  • GBASE 8s 并行机制之 PDQ 的基本概念

    Parallel database query PDQ 即并行数据库查询 当处理决策支持类 或数据仓库类查询 查询时 PDQ 特性可以用来极大地提高数据库查询处理的性能 启用PDQ后 GBase 8s 可以将查询操作分布到多个不同的处理器上
  • Kali之MSF的MS08-067漏洞复现详解

    1 MSF初识 MSF即Metasploit Framework 是一个综合性的渗透测试工具 集成信息收集 漏洞扫描 漏洞利用以及提权等功能的工具 目前安装的kali都自带MSF 可以直接在图形界面打开 也可以在kali的终端通过使用命令m
  • 假设检验之T检验、方差检验

    假设检验 spss 差异分析 一 假设检验 1 假设检验的假设 2 原假设与研究假设的关系 3 区分两种假设 4 假设检验统计决策的原理 5 假设检验的步骤 二 t检验 1 单样本T检验 2 独立样本T检验 3 配对样本T检验 三 方差分析
  • 【数据挖掘】从“文本”到“知识”:信息抽取(Information Extraction)

    从 文本 到 知识 信息抽取 这是一个大数据的时代 随着太阳东升西落 每一天都在产生大量的数据信息 人们通常更擅长处理诸如数字之类的结构化数据 但实际情况是 非结构化数据往往比结构化的数据多 当我们从互联网上获取了大量的如文本之类的非结构化
  • 【10天基于STM32F401RET6智能锁项目实战第4天】什么是中断,中断服务函数,系统滴答定时器

    什么是中断 中断服务函数 系统滴答定时器 一 中断的概述 二 外部中断 三 系统滴答定时器 一 中断的概述 二 外部中断 三 系统滴答定时器 如果这篇博文对你有帮助赶紧关注 点赞 收藏吧 感谢你的支持 后面还会有关于中断和系统滴答定时器的相
  • 客户端负载均衡Feign之四:Feign配置

    Ribbon配置 在Feign中配置Ribbon非常简单 直接在application properties中配置即可 如 设置连接超时时间 ribbon ConnectTimeout 500 设置读取超时时间 ribbon ReadTim
  • 涨知识了!这9个鲜为人知的 Python 第三方库真棒!

    欢迎关注 专注 Python 数据分析 数据挖掘 好玩工具 Python 编程充满了机会 它简单明了 拥有许多很酷的库和特色功能 可以使任务变得简单得多 每个 Python 开发人员都必须与热门的第三方库合作 如 NumPy pandas
  • 解决pandas左上角的数据索引、替换

    对于一个dataframe 左上角可以通过如下方式索引到 dataframe columns name 示例代码 import pandas as pd import numpy as np df pd DataFrame np rando
  • Unbuntu20.04(linux)离线安装seata

    一 解压 首先下载seata的安装包 cd usr local目录下执行以下命令 tar zxvf seata server 1 4 0 tar gz 二 修改配置文件 1 修改配置文件registry conf 修改自己的nacos信息
  • CSS更改默认滚动条的样式

    简介 默认滚动条样式又宽又粗 不太美观 一般在网页布局时会将滚动条优化 加一些圆角 改颜色 改宽高等等 此时就需要更改默认滚动条的样式 使用 将下面CSS代码放在全局CSS文件 全局滚动条的样式都会改为自定义设置的样式 只想修改局部某个页面
  • Python异常重试解决方案 Python中异常重试的解决方案详解

    想了解Python中异常重试的解决方案详解的相关内容吗 标点符在本文为您仔细讲解Python异常重试解决方案的相关知识和一些Code实例 欢迎阅读和指正 我们先划重点 python 重试 python 重试机制 python 出错重试 下面
  • ctf-web入门-文件上传

    Web 151 考点 后端无验证 前端校验 查看源码可以发现只能上传png图片 修改为php 写一个php文件上传一句话木马 可以发现已经成功上传 查看上级目录发现可疑文件 查看flag php文件内容得出flag 得到flag Web 1
  • 【python】leetcode中常用函数(持续更新)

    文章目录 1 1 Counter 计数器 1 2 enumerate 索引数组 1 3 defaultdict 缺省字典 1 4 deque 队列 1 5 heapq 堆 1 6 reduce 1 7 map 2 1 数组操作 2 3 字符
  • MATLAB深度学习之LSTM

    MATLAB深度学习之LSTM 深度学习工具箱 net trainNetwork sequences Y layers options clc clear 训练深度学习 LSTM 网络 进行序列到标签的分类 XTrain 是一个包含 270
  • Virtuoso工具基础讲解

    画图基础工具分为 Ic51 启动命令 icfb 渐淘汱 Ic61 启动命令 virtuoso 目前主流 建立电路 建立INV电路 操作指令 Tools library maneger 跳出新窗口 File New cell view 出现n
  • 右击 未出现 vscode打开

    右击 未出现 vscode打开 https blog csdn net Leo zjk article details 120883156 改动三处才有效 一是command要小写 然后Icon是 字符串值 三是最后不是 1 是 v don
  • (JS逆向专栏三)某玩游戏平台网站登入MD5加密

    声明 本文章中所有内容仅供学习交流 严禁用于商业用途和非法用途 否则由此产生的一切后果均与作者无关 若有侵权 请联系我立即删除 名称 365玩游戏平台 目标 登入参数 加密类型 MD5 目标网址 http minilogin sgty co
  • js小数计算丢失精度问题

    问题描述 js在计算小数计算如 1 0 2 的时候会丢失精度 即 1 0 2 0 19999999999999996 例如 console log 1 0 8 输出 0 19999999999999996 console log 6 0 7