W72crm_web-master/node_modules/number-precision/build/index.iife.js

168 lines
4.7 KiB
JavaScript
Raw Normal View History

2025-05-27 11:25:53 +08:00
var NP = (function (exports) {
'use strict';
/**
* @desc 解决浮动运算问题避免小数点后产生多位数和计算精度损失
*
* 问题示例2.3 + 2.4 = 4.6999999999999991.0 - 0.9 = 0.09999999999999998
*/
/**
* Correct the given number to specifying significant digits.
*
* @param num The input number
* @param precision An integer specifying the number of significant digits
*
* @example strip(0.09999999999999998) === 0.1 // true
*/
function strip(num, precision) {
if (precision === void 0) { precision = 15; }
return +parseFloat(Number(num).toPrecision(precision));
}
/**
* Return digits length of a number.
*
* @param num The input number
*/
function digitLength(num) {
// Get digit length of e
var eSplit = num.toString().split(/[eE]/);
var len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0);
return len > 0 ? len : 0;
}
/**
* Convert the given number to integer, support scientific notation.
* The number will be scale up if it is decimal.
*
* @param num The input number
*/
function float2Fixed(num) {
if (num.toString().indexOf('e') === -1) {
return Number(num.toString().replace('.', ''));
}
var dLen = digitLength(num);
return dLen > 0 ? strip(Number(num) * Math.pow(10, dLen)) : Number(num);
}
/**
* Log a warning if the given number is out of bounds.
*
* @param num The input number
*/
function checkBoundary(num) {
if (_boundaryCheckingState) {
if (num > Number.MAX_SAFE_INTEGER || num < Number.MIN_SAFE_INTEGER) {
console.warn(num + " is beyond boundary when transfer to integer, the results may not be accurate");
}
}
}
/**
* Create an operation to support rest params.
*
* @param operation The original operation
*/
function createOperation(operation) {
return function () {
var nums = [];
for (var _i = 0; _i < arguments.length; _i++) {
nums[_i] = arguments[_i];
}
var first = nums[0], others = nums.slice(1);
return others.reduce(function (prev, next) { return operation(prev, next); }, first);
};
}
/**
* Accurate multiplication.
*
* @param nums The numbers to multiply
*/
var times = createOperation(function (num1, num2) {
var num1Changed = float2Fixed(num1);
var num2Changed = float2Fixed(num2);
var baseNum = digitLength(num1) + digitLength(num2);
var leftValue = num1Changed * num2Changed;
checkBoundary(leftValue);
return leftValue / Math.pow(10, baseNum);
});
/**
* Accurate addition.
*
* @param nums The numbers to add
*/
var plus = createOperation(function (num1, num2) {
// 取最大的小数位
var baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
// 把小数都转为整数然后再计算
return (times(num1, baseNum) + times(num2, baseNum)) / baseNum;
});
/**
* Accurate subtraction.
*
* @param nums The numbers to subtract
*/
var minus = createOperation(function (num1, num2) {
var baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
return (times(num1, baseNum) - times(num2, baseNum)) / baseNum;
});
/**
* Accurate division.
*
* @param nums The numbers to divide
*/
var divide = createOperation(function (num1, num2) {
var num1Changed = float2Fixed(num1);
var num2Changed = float2Fixed(num2);
checkBoundary(num1Changed);
checkBoundary(num2Changed);
// fix: 类似 10 ** -4 为 0.00009999999999999999strip 修正
return times(num1Changed / num2Changed, strip(Math.pow(10, digitLength(num2) - digitLength(num1))));
});
/**
* Accurate rounding method.
*
* @param num The number to round
* @param decimal An integer specifying the decimal digits
*/
function round(num, decimal) {
var base = Math.pow(10, decimal);
var result = divide(Math.round(Math.abs(times(num, base))), base);
if (num < 0 && result !== 0) {
result = times(result, -1);
}
return result;
}
var _boundaryCheckingState = true;
/**
* Whether to check the bounds of number, default is enabled.
*
* @param flag The value to indicate whether is enabled
*/
function enableBoundaryChecking(flag) {
if (flag === void 0) { flag = true; }
_boundaryCheckingState = flag;
}
var index = {
strip: strip,
plus: plus,
minus: minus,
times: times,
divide: divide,
round: round,
digitLength: digitLength,
float2Fixed: float2Fixed,
enableBoundaryChecking: enableBoundaryChecking,
};
exports.strip = strip;
exports.plus = plus;
exports.minus = minus;
exports.times = times;
exports.divide = divide;
exports.round = round;
exports.digitLength = digitLength;
exports.float2Fixed = float2Fixed;
exports.enableBoundaryChecking = enableBoundaryChecking;
exports['default'] = index;
return exports;
}({}));