UNPKG

haw-utils

Version:

一个基于业务场景的工具方法库

149 lines (139 loc) 4.64 kB
(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; } });