UNPKG

js-calculation

Version:

solving the problem of javaScript computing accuracy loss

97 lines (77 loc) 3.3 kB
import type { BigNumber } from 'https://esm.sh/mathjs'; import { bignumber, evaluate } from 'https://esm.sh/mathjs'; import { isNumber, isConstantNumber, isOperator, isFunction, OPERATOR } from './utils.ts'; export function computedPrefix(expr: string | string[]) { // 前缀表达式 const nodes = typeof expr === 'string' ? expr.split(/\s+/) : expr; // 表达式节点 const _nodes: BigNumber[] = []; for (let index = 0; index < nodes.length;){ const node = nodes[index]; if (isNumber(node, false)) { _nodes.push(bignumber(node)); // 数字存储 index += 1; continue; } if (isConstantNumber(node)) { _nodes.push(bignumber(Math[node as keyof Math] as number)); // 常量存储为数字 index += 1; continue; } if (isFunction(node)) { // 方法计算 const paramsLength = (Math[node as keyof Math] as Function).length; _nodes.push(bignumber((Math[node as keyof Math] as Function)( ...new Array(paramsLength) .fill(undefined) .map((_, _index) => nodes[index + _index + 1]) ))); index += paramsLength; continue; }; if (isOperator(node)) { // 运算符计算 const paramsLength = OPERATOR[node as keyof typeof OPERATOR].length; _nodes.push(bignumber((OPERATOR[node as keyof typeof OPERATOR] as Function)( ...new Array(paramsLength) .fill(undefined) .map((_, _index) => nodes[index + _index + 1]) ))); index += paramsLength; continue; } index += 1; } return _nodes.pop() as BigNumber; } export function computedInfix(expr: string | string[]): number { // 中缀表达式 const _expr = typeof expr === 'string' ? expr : expr.join(''); // 表达式节点 return evaluate(_expr); } export function computedPostfix(expr: string | string[]) { // 后缀表达式 const nodes = typeof expr === 'string' ? expr.split(/\s+/) : expr; // 表达式节点 return nodes.reduce<BigNumber[]>((_nodes, node) => { // 数字存储 if (isConstantNumber(node)) { // 常量存储为数字 _nodes.push(bignumber(Math[node as keyof Math] as number)); return _nodes; } if (isFunction(node)) { // 方法计算 _nodes.push(bignumber((Math[node as keyof Math] as Function)( ...new Array((Math[node as keyof Math] as Function).length) .fill(undefined) .map(() => _nodes.pop() as BigNumber) .reverse() ))); return _nodes; } if (isOperator(node)) { // 运算符计算 _nodes.push(bignumber((OPERATOR[node as keyof typeof OPERATOR] as Function)( ...new Array(OPERATOR[node as keyof typeof OPERATOR].length) .fill(undefined) .map(() => _nodes.pop() as BigNumber) .reverse() ))); return _nodes; } if (isNumber(node, false)) { _nodes.push(bignumber(node)); } return _nodes; }, []).shift() as BigNumber; };