【转】JS中处理Number浮点数精度问题
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浮点数精度问题的更多相关文章
- js 中的 number 为何很怪异
js 中的 number 为何很怪异 声明:需要读者对二进制有一定的了解 对于 JavaScript 开发者来说,或多或少都遇到过 js 在处理数字上的奇怪现象,比如: > 0.1 + 0.2 ...
- js中声明Number的五种方式
转载自:http://www.jb51.net/article/34191.htm <!DOCTYPE html> <html> <head> <meta c ...
- JS中如何理解浮点数?
本文由云+社区发表 相信大家在平常的 JavaScript 开发中,都有遇到过浮点数运算精度误差的问题,比如 console.log(0.1+0.2===0.3)// false.在 JavaScri ...
- JS中的Number数据类型详解
Number数据类型 Number类型使用IEEE754格式来表示整数和浮点值,这也是0.2 + 0.3不等于0.5的原因, 最基本的数值类型字面量格式是十进制整数 var a = 10; 1. 浮点 ...
- js中的Number方法
1.Number.toExponential(fractionDigits) 把number转换成一个指数形式的字符串.可选参数控制其小数点后的数字位数.它必须在0~20之间. 例如: documen ...
- Number浮点数运算详解
文章来自我的 github 博客,包括技术输出和学习笔记,欢迎star. 一道题 0.1 + 0.2 = ? 在浏览器中测试下计算结果,得到的结果是 0.30000000000000004,并不是理想 ...
- js浮点数精度丢失问题及如何解决js中浮点数计算不精准
js中进行数字计算时候,会出现精度误差的问题.先来看一个实例: console.log(0.1+0.2===0.3);//false console.log(0.1+0.1===0.2);//true ...
- js中精度问题以及解决方案
js中的数字按照IEEE 754的标准,使用64位双精度浮点型来表示.其中符号位S,指数位E,尾数位M分别占了1,11,52位,并且在ES5规范中指出了指数位E的取值范围是[-1074, 971]. ...
- js中如何取精度
js中如何取精度 一.总结 一句话总结:其实round()函数去经度会有误差,直接用num.toFixed(2)简单方便. toFixed()方法会按照指定的小数返回数值的字符串表示.var num ...
随机推荐
- linux线程操作
初始化条件变量 int pthread_cond_init(pthread_cond_t *cv,pthread_cond_attr *cattr); 函数返回值:返回0表示成功,返回其他表示失败. ...
- PIT 编辑器编辑及协同架构说明
pit 项目使用 quill-delta 作为数据层存储文档内容数据,quill-delta 是一个基于 OT 算法的库,用 quill-delta 作为数据层,不仅能很好的保存文档数据,还可以方便的 ...
- Percona,MariaDB,MySQL衍生版如何取舍
缘起 自从甲骨文公司收购了MySQL后,有将MySQL闭源的潜在风险.而且Oracle对培养MySQL这个免费的儿子并不太用心,漏洞修补和版本升级的速度一段时间非常缓慢,所以业界对MySQL的未来普遍 ...
- Chapter Four
JSON数据 默认情况下,当开发者新创建一个SpringBoot项目时,会添加Web依赖,在这个依赖中会默认加入jackson-databind作为Json处理器. @RestController 组 ...
- mysql删除大表
在mysql中遇到一个大表,大概有17G左右,在对这个表进行查询.修改时均遇到了很大的困难,于是想着删除这张表.通常的删除操作可以通过delete.drop.truncate操作,试了这三个命令,但是 ...
- ajax上传图片报错TypeError: 'append' called on an object that does not implement interface Fo
使用FormData时报错:TypeError: 'append' called on an object that does not implement interface FormData 解决办 ...
- vbs msgbox提示信息最前面显示
msgbox strContent, vbOKOnly or vbExclamation or vbSystemModal,strTitle 提示框类型列表: 常数 值 描述 vbOKOnly 0 只 ...
- Maltego更新到4.2.4.12374
Maltego更新到4.2.4.12374 这次更新修改多个bug,并增加一些的特性和功能.主要变化如下: (1)允许用户直接复制实例的属性,以粘贴方式创建新实体. (2)右击网址类实体,右键菜单 ...
- Leetcode: Campus Bikes II
On a campus represented as a 2D grid, there are N workers and M bikes, with N <= M. Each worker a ...
- vue 日历组件
Github 上很多点击弹出日历选择某个时间的组件,却没有找到单纯展示日历并且能点击获取时间的组件 npm i vue-calendar-component --save cnpm i vue-cal ...