首页 > 编程语言 >js精度计算问题解决,Jsutil库源码

js精度计算问题解决,Jsutil库源码

时间:2022-09-20 12:45:03浏览次数:99  
标签:const Jsutil symbol Number js 源码 result Math 升幂

为什么会存在浮点数计算精度丢失问题,这个原因不再过多赘述;   JS中如何解决精度计算问题,大不部分人都知道升幂再降幂的解决方案;   但是如果直接升幂也会出现精度问题,且需要指定死小数位数。如:

var m = 100;
//0.28 * 100 升幂时就会出现精度问题
var res = ((0.28 * m) + (0.03*m)) / m ; // 0.31000000000000005
//需要再对结果进行一次Math.toFixed处理,且需要指定小数位数
res.Math.toFixed(2) //0.31

 

  本文为大家重新整理了一个_Calc JS高精度计算方法,并放在了博主的开源库Jsutil;   *采用的是replace+数字补0 实现升幂;   方法测试结果,以excel计算做为参照:     1、支持加,减,乘,除 2、支持连续数字计算;   方法源码:
const _Calc = (symbol:string, number1:number, number2:number, ...args:number[]):number =>{
    if(!['+','-','*','/'].includes(symbol)){
        throw new Error('第一个参数请传+ - * /计算符');
    }
    const num1 = Number(number1);
    const num2 = Number(number2);
    if(isNaN(num1) || isNaN(num2)){
        throw new Error('第二,三个参数必须传入可计算数字或字符');
    }
    let result = 0;
    // 把浮点数跟整数部分拆解
    const [num1BeforeInt, num1Float] = num1.toString().split('.');
    const [num2BeforeInt, num2Float] = num2.toString().split('.');

    const num1FloatLen = num1Float?.length || 0;
    const num2FloatLen = num2Float?.length || 0;

    // 乘除法直接去掉浮点
    const num1Int = Number(num1.toString().replace('.',''));
    const num2Int = Number(num2.toString().replace('.',''));

    if(symbol === '+' || symbol === '-'){
        // 以最长浮点数长度补0
        let m = Math.max(num1FloatLen, num2FloatLen);
        // 使用字符串补0方式得到最后计算数值(不能直接数字升幂,部分数字升幂就会缺精度)
        const resNum1 = Number(`${num1BeforeInt}${num1Float.padEnd(m,'0')}`);
        const resNum2 = Number(`${num2BeforeInt}${num2Float.padEnd(m,'0')}`);
        if(symbol === '+'){
            result = (resNum1 + resNum2) / Math.pow(10, m);
        }else{
            result = (resNum1 - resNum2) / Math.pow(10, m);
        }

    }else if(symbol === '*'){
        // 两个数的浮点长度加和为幂值
        let m = Math.pow(10, num1FloatLen + num2FloatLen);
        result = (num1Int * num2Int ) / m;
    }else if(symbol === '/'){
        // 被除数的浮点长度减除数浮点长为幂值
        let m = Math.pow(10, num2FloatLen - num1FloatLen)
        result = (num1Int  / num2Int ) * m;
    }
    // 有第三位计算数字
    const nextNum = args[0];
    if(nextNum){
        args.shift()
        result =  _Calc(symbol, result, nextNum, ...args);
    }
    
    return result;
}

 

  

 

标签:const,Jsutil,symbol,Number,js,源码,result,Math,升幂
From: https://www.cnblogs.com/hrw3c/p/16710644.html

相关文章

  • js同一接口返回不同的类型之Edge的兼容
    前提:js同一接口返回不同的类型,但是这个链接上面的内容的缺点是没有加Edge浏览器的兼容:今天我们就说说如何加兼容:1.没有兼容内容的巩固,Chrome浏览器中获取blob的接口返......
  • 使用 Amplication 缩短 Node.js 应用程序的上线时间
    使用Amplication缩短Node.js应用程序的上线时间AmplicationStack使用任何技术开发任何应用程序都是一个复杂的过程。我们必须考虑很多事情,比如架构、使用哪些技术......
  • 前端Nodejs-Day34
    Node.js:基于ChromeV8引擎的Javascript运行环境浏览器中js的运行环境:前端运行环境Nodejs中js的运行环境:后端运行环境(无法调用DOM和BOM等浏览器内置API)  ......
  • Three-js入门3-插件stats和dat-GUI.md
    title:Three.js入门3-插件stats和dat.GUIcopyright:truepermalink:8top:0date:2019-01-2702:42:55tags:['three']categories:techpassword:翻译自官方文......
  • JS使用策略模式优化条件选择结构
    这段代码是采用if-else的方式判断多个不同的条件。functionpermission(role){if(role==="operations"){getOperationPermission()}elseif(role=......
  • SpringBoot Xml转Json对象
    一、导入需要的依赖<dependency><groupId>maven</groupId><artifactId>dom4j</artifactId><version>1.7-20060614</version></dependency>二、xml......
  • FastJson 的一些配置
    主要提到:关闭循环引用的配置"$ref":"$.data[0].detail.wmsInboundorder.details[1]"如下:importcom.alibaba.fastjson.serializer.SerializeConfig;importcom.alib......
  • node.js 使用教程-3.gulp-file-include 详细教程
    前言gulp-file-include是gulp插件,它提供了一个include方法让我们可以像后端模板那样把公共部分的页面导入进来,实现html复用。环境准备gulp-file-include是gulp的......
  • spring源码解析(一)
    beanFactory是application的父接口是spring的关键容器,主要的applicationContext都组合了他的功能,关系如图beanFactory功能只有getBeanioc,依赖注入,bean......
  • Java:Json与List对象的相互转换
    谷歌的Gson.jar://list转换为jsonGsongson=newGson();List<Person>persons=newArrayList<Person>();Stringstr=gson.toJson(persons);//json转换为listGs......