【转】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 ...
随机推荐
- PHP-FPM参数详情
pid = run/php-fpm.pid #pid设置,默认在安装目录中的var/run/php-fpm.pid,建议开启 error_log = log/php-fpm.log #错误日志,默认在 ...
- 42、JDBC数据源案例
一.JDBC数据源案例 1.概述 Spark SQL支持使用JDBC从关系型数据库(比如MySQL)中读取数据.读取的数据,依然由DataFrame表示,可以很方便地使用Spark Core提供的各种 ...
- Comet OJ Contest #13 简要题解
C2 首先用并查集维护\(1\)的连通块,然后用另外一个并查集维护第\(i\)行中,第\(j\)列之后的第一个\(0\)的位置,就是如果当前位置是\(1\)那么它的父亲是它右边的格子,否则是它自己. ...
- Day11:Flex布局
参考: 来源:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html 网页布局是css的一个重点. 盒子模型 display属性 positi ...
- Mybatis 通用Mapper增强
1.确保是个Maven项目,确保Spring与Mybatis正确配置. 2.新建一个自定义通用Mapper. /** * BaseMapper接口:使mapper包含完整的CRUD方法<br&g ...
- archlinux安装nvidia-1050ti闭源驱动教程,亲测
link:https://blog.csdn.net/u014025444/article/details/91454059
- RabbitMQ入门学习系列(二),单生产者消费者
友情提示 我对我的文章负责,发现好多网上的文章 没有实践,都发出来的,让人走很多弯路,如果你在我的文章中遇到无法实现,或者无法走通的问题.可以直接在公众号<爱码农爱生活 >留言.必定会再次 ...
- 2018-2019-2 网络对抗技术 20165322 Exp8 Web基础
2018-2019-2 网络对抗技术 20165322 Exp8 Web基础 目录 实验原理 实验内容与步骤 Web前端HTML Web前端javascipt Web后端:MySQL基础:正常安装.启 ...
- Leet Code 771.宝石与石头
Leet Code编程题 希望能从现在开始,有空就做一些题,自己的编程能力太差了. 771 宝石与石头 简单题 应该用集合来做 给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S ...
- NoSql数据库Redis系列(1)——Redis简介
一.redis介绍 (一).Redis 简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点 ...