UNPKG

mofang-mopai-utils

Version:

Use it in Mopai system

186 lines (185 loc) 7.47 kB
"use strict"; exports.__esModule = true; /** * A class for performing mathematical calculations on a given formula. * 魔方魔派前端计算器 */ var MofangMopaiCalculator = /** @class */ (function () { /** * Constructs a new instance of MfCalculator. * * @param {string} formula - The mathematical formula to be calculated. * @throws Will throw an error if the formula is not provided or is not a string. */ function MofangMopaiCalculator(formula) { if (!formula) throw new Error('[传参错误] - 传入公式不能为空'); if (typeof formula !== 'string') throw new Error('[传参错误] - 传入公式必须是字符串格式'); this._formula = formula.replace(/\s*/g, ''); } /** * Calculates the final result of the mathematical formula. * * @returns {number} The final result of the calculation. */ MofangMopaiCalculator.prototype.get = function () { var res = this._splitFormula(this._formula); return Number(res || 0); }; /** * Splits the mathematical formula into smaller parts for individual calculation. * It continues to do this until there are no more operators left in the formula. * * @param {string} formula - The mathematical formula to be split. * @returns {string} The final result of the calculation. * * @example * _splitFormula('1.23+34.23+33-4-7.8*8.12+103.21') // returns '104.334' */ MofangMopaiCalculator.prototype._splitFormula = function (str) { // 先乘除 后加减 var methodA = str.match(/\*|\//); // 判断有没有乘除法公式 var methodB = str.match(/\+|\-/); // 判断有没有加减法公式 // 如果未匹配到计算公式,则是计算后的最终结果,直接返回 if (!methodA && !methodB) return str; // 定义计算公式正则表达式 var reg; if (methodA) { reg = this._getRegExp(methodA[0]); } else if (methodB) { reg = this._getRegExp(methodB[0]); } else { throw new Error('[计算错误] - 未能成功获得计算公式正则表达式'); } // 匹配字符串中的计算公式 var arr = str.match(reg); var formula = (arr === null || arr === void 0 ? void 0 : arr[0]) || ''; if (!formula) throw new Error('[计算错误] - 未匹配到计算公式'); // 对公式进行计算 var calculationResult = this._startCalc(formula); // 把相应的计算公式替换成计算后的结果值 var replaceFormula = str.replace(formula, calculationResult.toString()); // 继续进行计算 直到字符串中没有计算公式为止 return this._splitFormula(replaceFormula); }; /** * Gets a regular expression based on the given calculation method. * * @param {string} method - The calculation method. * @returns {RegExp} The regular expression. */ MofangMopaiCalculator.prototype._getRegExp = function (method) { return new RegExp("\\d+(\\.\\d+)?\\".concat(method, "\\d+(\\.\\d+)?")); }; /** * Starts the calculation process for a given formula. * * @param {string} formula - The mathematical formula to be calculated. * @returns {number} The result of the calculation. * * @example * _startCalc('1.23+34.23') // returns 35.46 * _startCalc('34.23-33') // returns 1.23 * _startCalc('33*7.8') // returns 257.4 * _startCalc('103.21/8.12') // returns 12.699999999999998 */ MofangMopaiCalculator.prototype._startCalc = function (formula) { var _a; if (!formula) throw new Error('[计算错误] - 未找到需要计算的公式'); var reg = /\+|\-|\*|\//g; var method = (_a = formula.match(reg)) === null || _a === void 0 ? void 0 : _a[0]; // 获取计算符 if (!method) throw new Error('[计算错误] - 计算方法错误'); var numArray = formula.split(reg); return this._execMath(numArray[0], numArray[1], method); }; /** * Executes a mathematical operation on two numbers. * * @param {number | string} [a=0] - The first number. * @param {number | string} [b=0] - The second number. * @param {string} method - The mathematical operation to be performed. * @returns {number} The result of the mathematical operation. * @throws Will throw an error if the method is not one of the following: '+', '-', '*', '/'. * * @example * _execMath(1.23, 34.23, '+') // returns 35.46 * _execMath(34.23, 33, '-') // returns 1.23 * _execMath(33, 7.8, '*') // returns 257.4 * _execMath(103.21, 8.12, '/') // returns 12.699999999999998 */ MofangMopaiCalculator.prototype._execMath = function (a, b, method) { if (a === void 0) { a = 0; } if (b === void 0) { b = 0; } // 获取小数点后位数 var decimalLength = Math.max(this._getDecimalLength(a), this._getDecimalLength(b)); var x = this._transformToInteger(a, decimalLength); // 补位后的a值 var y = this._transformToInteger(b, decimalLength); // 补位后的b值 var z = Number(('1').padEnd(decimalLength + 1, '0')); // 补位数 switch (method) { case '+': { return (x + y) / z; } case '-': { return (x - y) / z; } case '*': { return x * y / Math.pow(z, 2); } case '/': { return x / y; } default: { return 0; } } }; /** * Gets the decimal length of a number. * * @param {number} num - The number to get the decimal length from. * @returns {number} The decimal length of the number. * * @example * _getDecimalLength(1.23) // returns 2 * _getDecimalLength(34.23) // returns 2 * _getDecimalLength(33) // returns 0 */ MofangMopaiCalculator.prototype._getDecimalLength = function (num) { var _a; var n = num.toString(); var arr = n.split(/\./); return ((_a = arr[1]) === null || _a === void 0 ? void 0 : _a.length) || 0; }; /** * Transforms a decimal number into an integer by padding the decimal part with zeros. * !因为直接进位计算还是会出现小数点后无穷位的问题,所以直接用字符串进行格式化 * * @param {number} num - The decimal number to be transformed. * @param {number} offset - The number of decimal places to pad. * @returns {number} The transformed integer. * * @example * _transformToInteger(1.23, 2) // returns 123 * _transformToInteger(34.23, 3) // returns 34230 * _transformToInteger(33, 1) // returns 330 */ MofangMopaiCalculator.prototype._transformToInteger = function (num, offset) { var _a; if (offset === 0) return Number(num); var n = num.toString(); var arr = n.split(/\./); var dec = ((_a = arr[1]) === null || _a === void 0 ? void 0 : _a.toString()) || '0'; arr[1] = dec.padEnd(offset, '0'); return Number(arr.join('')); }; return MofangMopaiCalculator; }()); exports["default"] = MofangMopaiCalculator;