haw-utils
Version:
一个基于业务场景的工具方法库
149 lines (139 loc) • 4.64 kB
JavaScript
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(["exports", "./constants"], factory);
} else if (typeof exports !== "undefined") {
factory(exports, require("./constants"));
} else {
var mod = {
exports: {}
};
factory(mod.exports, global.constants);
global.mathUtil = mod.exports;
}
})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _constants) {
"use strict";
Object.defineProperty(_exports, "__esModule", {
value: true
});
_exports.checkBoundary = checkBoundary;
_exports.digitLength = digitLength;
_exports.float2Fixed = float2Fixed;
_exports.isScientificNumber = isScientificNumber;
_exports.scientificToNumber = scientificToNumber;
_exports.strip = strip;
/**
* 参考: https://github.com/nefe/number-precision/blob/master/src/index.ts
*
* 解决浮动运算问题,避免小数点后产生多位数和计算精度损失。
* 问题示例:2.3 + 2.4 = 4.699999999999999,1.0 - 0.9 = 0.09999999999999998
*/
/**
* 是否为科学计数法数字
*
* @param {String} num 检查值
* @returns {Boolean}
*/
function isScientificNumber(num) {
return /\d+\.?\d*e[\+\-]*\d+/i.test(num);
}
/**
* 把错误的数据转正
*
* @param {Number} num 输入数
* @param {Number} [precision=12] 小数点的精度
* @returns {Number}
* @example
*
* strip(0.09999999999999998)=0.1
*/
function strip(num) {
var precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 12;
return +parseFloat(num.toPrecision(precision));
}
/**
* 计算数字的小数点长度,支持科学记数法
*
* @param {Number} num 输入数
* @returns {Number} 小数点长度
*/
function digitLength(num) {
// Get digit length of e
var eSplit = num.toString().split(/e/i);
var len = (eSplit[0].split('.')[1] || '').length - +(eSplit[1] || 0);
return len > 0 ? len : 0;
}
/**
* 把小数转成整数,支持科学计数法。如果是小数则放大成整数
*
* @param {Number} num 输入数
* @returns {Number}
*/
function float2Fixed(num) {
if (!isScientificNumber(num.toString())) {
return Number(num.toString().replace('.', ''));
}
var dLen = digitLength(num);
return dLen > 0 ? strip(num * Math.pow(10, dLen)) : num;
}
/**
* 检测数字是否越界,如果越界给出提示
* @param {Number} num 输入数
* @returns {Boolean}
*/
function checkBoundary(num) {
if (+num > _constants.MAX_SAFE_INTEGER || +num < _constants.MIN_SAFE_INTEGER) {
console.warn("".concat(num, " is beyond boundary when transfer to integer, the results may not be accurate"));
}
}
/**
* 去掉左边数字0
*
* @param {String} num 数字字符串
* @returns {String}
*/
function trimLeftZero(num) {
var reg = /^([+-])?(0+)([1-9\.]+)$/;
var result = reg.exec(num);
var sign;
if (result) {
sign = result[1] || '';
return sign + result[3];
}
return num;
}
/**
* 科学计数法转换成普通数字
*
* JavaScript在以下情景会自动将数值转换为科学计数法:
* 1.小数点前的数字个数大于等于22位
* 2.小数点前边是0,小数点后十分位(包含十分位)之后连续零的个数大于等于6个
*
* @param {String|Number} num 科学计数法数字
* @returns {String} 转换后的数字字符串
*/
function scientificToNumber(num) {
if (isScientificNumber(num)) {
var zero = '0';
var parts = String(num).toLowerCase().split('e');
var e = parts.pop(); // 存储指数
var l = Math.abs(e); // 取绝对值,l-1就是0的个数
var sign = e / l; //判断正负
var coeff_array = parts[0].split('.'); // 将系数按照小数点拆分
//如果是小数
if (sign === -1) {
//拼接字符串,如果是小数,拼接0和小数点
num = zero + '.' + new Array(l).join(zero) + coeff_array.join('');
} else {
var dec = coeff_array[1];
//如果是整数,将整数除第一位之外的非零数字计入位数,相应的减少0的个数
if (l - dec.length < 0) {
num = trimLeftZero(coeff_array[0] + dec.substr(0, l)) + '.' + dec.substr(l);
} else {
//拼接字符串,如果是整数,不需要拼接小数点
num = coeff_array.join('') + new Array(l - dec.length + 1).join(zero);
}
}
}
return num;
}
});