https://github.com/dt-fe/number-precision

~(function(root, factory) {
if (typeof define === "function" && define.amd) {
define([], factory);
} else if (typeof module === "object" && module.exports) {
module.exports = factory();
} else {
root.NP = factory();
}
}(this, function() {
'use strict';
/**
* @ file 解决浮动运算问题,避免小数点后产生多位数和计算精度损失。
* 问题示例:2.3 + 2.4 = 4.699999999999999,1.0 - 0.9 = 0.09999999999999998
*/
return {
/**
* 把错误的数据转正
* strip(0.09999999999999998)=0.1
*/
strip: function (num, precision = 12) {
return +parseFloat(num.toPrecision(precision));
},
/**
* Return digits length of a number
* @ param {*number} num Input number
*/
digitLength: function (num) {
// Get digit length of e
const eSplit = num.toString().split(/[eE]/);
const len = (eSplit[0].split('.')[1] || '').length - (+(eSplit[1] || 0));
return len > 0 ? len : 0;
},
/**
* 精确加法
*/
plus: function (num1, num2) {
const baseNum = Math.pow(10, Math.max(this.digitLength(num1), this.digitLength(num2)));
return (num1 * baseNum + num2 * baseNum) / baseNum;
},
/**
* 精确减法
*/
minus: function (num1, num2) {
const baseNum = Math.pow(10, Math.max(this.digitLength(num1), this.digitLength(num2)));
return (num1 * baseNum - num2 * baseNum) / baseNum;
},
/**
* 精确乘法
*/
times: function (num1, num2) {
const num1Changed = Number(num1.toString().replace('.', ''));
const num2Changed = Number(num2.toString().replace('.', ''));
const baseNum = this.digitLength(num1) + this.digitLength(num2);
return num1Changed * num2Changed / Math.pow(10, baseNum);
},
/**
* 精确除法
*/
divide: function (num1, num2) {
const num1Changed = Number(num1.toString().replace('.', ''));
const num2Changed = Number(num2.toString().replace('.', ''));
return this.times((num1Changed / num2Changed), Math.pow(10, this.digitLength(num2) - this.digitLength(num1)));
},
/**
* 四舍五入
*/
round: function (num, ratio) {
const base = Math.pow(10, ratio);
return this.divide(Math.round(this.times(num, base)), base);
}
};
}));
方法:
NP.strip(num) // strip a number to nearest right number
NP.plus(num1, num2) // addition, num + num2
NP.minus(num1, num2) // subtraction, num1 - num2
NP.times(num1, num2) // multiplication, num1 * num2
NP.divide(num1, num2) // division, num1 / num2
NP.round(num, ratio) // round a number based on ratio 使用:
NP.strip(0.09999999999999998); // =0.1
NP.plus(0.1, 0.2); // =0.3 not 0.30000000000000004
NP.plus(2.3, 2.4); // =4.7 not 4.699999999999999
NP.minus(1.0, 0.9); // =0.1 not 0.09999999999999998
NP.times(3, 0.3); // =0.9 not 0.8999999999999999
NP.times(0.362, 100); // = 36.2, not 36.199999999999996
NP.divide(1.21, 1.1); // =1.1 not 1.0999999999999999
NP.round(0.105, 2); // =0.11 not 0.1

【转】JS中处理Number浮点数精度问题的更多相关文章

  1. js 中的 number 为何很怪异

    js 中的 number 为何很怪异 声明:需要读者对二进制有一定的了解 对于 JavaScript 开发者来说,或多或少都遇到过 js 在处理数字上的奇怪现象,比如: > 0.1 + 0.2 ...

  2. js中声明Number的五种方式

    转载自:http://www.jb51.net/article/34191.htm <!DOCTYPE html> <html> <head> <meta c ...

  3. JS中如何理解浮点数?

    本文由云+社区发表 相信大家在平常的 JavaScript 开发中,都有遇到过浮点数运算精度误差的问题,比如 console.log(0.1+0.2===0.3)// false.在 JavaScri ...

  4. JS中的Number数据类型详解

    Number数据类型 Number类型使用IEEE754格式来表示整数和浮点值,这也是0.2 + 0.3不等于0.5的原因, 最基本的数值类型字面量格式是十进制整数 var a = 10; 1. 浮点 ...

  5. js中的Number方法

    1.Number.toExponential(fractionDigits) 把number转换成一个指数形式的字符串.可选参数控制其小数点后的数字位数.它必须在0~20之间. 例如: documen ...

  6. Number浮点数运算详解

    文章来自我的 github 博客,包括技术输出和学习笔记,欢迎star. 一道题 0.1 + 0.2 = ? 在浏览器中测试下计算结果,得到的结果是 0.30000000000000004,并不是理想 ...

  7. js浮点数精度丢失问题及如何解决js中浮点数计算不精准

    js中进行数字计算时候,会出现精度误差的问题.先来看一个实例: console.log(0.1+0.2===0.3);//false console.log(0.1+0.1===0.2);//true ...

  8. js中精度问题以及解决方案

    js中的数字按照IEEE 754的标准,使用64位双精度浮点型来表示.其中符号位S,指数位E,尾数位M分别占了1,11,52位,并且在ES5规范中指出了指数位E的取值范围是[-1074, 971]. ...

  9. js中如何取精度

    js中如何取精度 一.总结 一句话总结:其实round()函数去经度会有误差,直接用num.toFixed(2)简单方便. toFixed()方法会按照指定的小数返回数值的字符串表示.var num ...

随机推荐

  1. ROS里程计

    gmapping导航建图包里建图需要里程计信息,且导航也需要. 整个移动机器人的控制结构如下图所示,其中base_controller节点将订阅的cmd_vel信息通过串口或其它通信接口发送给下位机( ...

  2. C# 常用日期取得

    列举一下常用的日期取得方法 static class DateTimeDemo { public static DateTime FirstDayOfMonth(this DateTime value ...

  3. [loj 6496]「雅礼集训 2018 Day1」仙人掌

    传送门 Description 给出一张 \(n\)个点 \(m\)条边的无向连通图,其中每条边至多属于一个简单环,保证没有自环,可能有重边.你需要为其中每条边定向,其中第 \(i\)个点的出度不能超 ...

  4. mysql忘记密码恢复

    MySQL忘记密码恢复密码的实现方法 作者:mdxy-dxy 流传较广的方法,mysql中文参考手册上的,各位vps主机租用客户和服务器托管用户忘记mysql5.1管理员密码时,可以使用这种方法破解下 ...

  5. fluent-动网格-动态层

    模型算例来源:http://blog.sina.com.cn/s/blog_599d8faa0100w4uj.html ​原视频下载地址:http://yunpan.cn/cujM2FxLuGdLK ...

  6. css,js 学习记录

    记录一些自己曾经阅读,值得收藏的网址 --(css3新特性) https://segmentfault.com/a/1190000010780991#articleHeader41 --CSS3 3D ...

  7. ubuntu之路——day6(今天对数据集的建立有了更深的体会)

    两个重点: 一.举个例子,如果建立一个图像识别的数据集,你的训练集和你的训练验证集是从网上爬下来的(也就是说这些图片的大小.像素.后期制作都可能很精美),你真正的测试集是用户的手机上传(不同的手机.环 ...

  8. DELPHI开发LINUX插件架构的程序

    DELPHI开发LINUX插件架构的程序 DELPHI可以开发LINUX配置型插件架构的程序,并且这一套插件架构,同样适用于MSWINDOWS和MAC. 配置插件: 根据配置,动态加载插件:

  9. 用variant的数据来推导基因表达 | Imputation of Expression Using PrediXcan

    一个工具的逻辑得足够完善.意义足够重大,才有资格发在NG上. A gene-based association method for mapping traits using reference tr ...

  10. MYSQL Packet for query is too large (12054240 > 4194304). You can change this value on the server by setting the max_allowed_packet' variable.

    MYSQL Packet for query is too large (12054240 > 4194304). You can change this value on the server ...