UNPKG

nerdamer-ts

Version:

javascript light-weight symbolic math expression evaluator

139 lines 5.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Settings_1 = require("../Settings"); const Utils_1 = require("../Core/Utils"); /** * Javascript has the toExponential method but this allows you to work with string and therefore any number of digits of your choosing * For example Scientific('464589498449496467924197545625247695464569568959124568489548454'); */ class Scientific { constructor(value) { this.sign = 1; this.decp = 0; let num = String(typeof value === 'undefined' ? 0 : value); //convert to a string //remove the sign if (num.startsWith('-')) { this.sign = -1; //remove the sign num = num.substr(1, num.length); } else { this.sign = 1; } if (Scientific.isScientific(num)) { [this.coeff, this.exponent] = Scientific.fromScientific(num); } else { // [this.coeff, this.exponent, this.decp, this.dec, this.wholes] = Scientific.convert(num); let data = Scientific.convert(num); this.coeff = data.coeff; this.exponent = data.exponent; this.dec = data.dec; this.decp = data.decp; this.wholes = data.wholes; } } static fromScientific(num) { let parts = String(num).toLowerCase().split('e'); let coeff = parts[0]; let exponent = parts[1]; return [coeff, exponent]; } static convert(num) { //get wholes and decimals let parts = num.split('.'); //make zero go away let wholes = parts[0] || ''; let d = parts[1] || ''; //convert zero to blank strings wholes = Scientific.removeLeadingZeroes(wholes); d = Scientific.removeTrailingZeroes(d); //find the location of the decimal place which is right after the wholes let dot_location = wholes.length; //add them together so we can move the dot let n = wholes + d; //find the next number let zeroes = Scientific.leadingZeroes(n).length; //set the exponent let exponent = (dot_location - (zeroes + 1)).toString(); //set the coeff but first remove leading zeroes let coeff = Scientific.removeLeadingZeroes(n); coeff = coeff.charAt(0) + '.' + (coeff.substr(1, coeff.length) || '0'); //the coeff decimal places let dec = coeff.split('.')[1] || ''; //if it's undefined or zero it's going to blank let decp = dec === '0' ? 0 : dec.length; //decimals dec = d.toString(); return { coeff, exponent, decp, dec, wholes }; } round(num) { let n = this.copy(); num = Number(num); //cast to number for safety //since we know it guaranteed to be in the format {digit}{optional dot}{optional digits} //we can round based on this if (num === 0) { n.coeff = n.coeff.charAt(0); } else { //get up to n-1 digits let rounded = this.coeff.substring(0, num + 1); //get the next two let next_two = this.coeff.substring(num + 1, num + 3); //the extra digit let ed = parseInt(next_two.charAt(0)); if (parseInt(next_two.charAt(1)) > 4) { ed++; } n.coeff = rounded + ed; } return n; } copy() { let n = new Scientific(0); n.coeff = this.coeff; n.exponent = this.exponent; n.sign = this.sign; return n; } toString(n = 0) { let retval; if (Settings_1.Settings.SCIENTIFIC_IGNORE_ZERO_EXPONENTS && this.exponent === '0' && this.decp < n) { if (this.decp === 0) retval = this.wholes; else retval = this.coeff; } else { let coeff = n === undefined ? this.coeff : Scientific.round(this.coeff, Math.min(n, this.decp || 1)); retval = this.exponent === '0' ? coeff : coeff + 'e' + this.exponent; } return (this.sign === -1 ? '-' : '') + retval; } static isScientific(num) { return /\d+\.?\d*e[+\-]*\d+/i.test(num); } static leadingZeroes(num) { let match = num.match(/^(0*).*$/); return match ? match[1] : ''; } static removeLeadingZeroes(num) { let match = num.match(/^0*(.*)$/); return match ? match[1] : ''; } static removeTrailingZeroes(num) { let match = num.match(/0*$/); return match ? num.substring(0, num.length - match[0].length) : ''; } static round(c, n) { let coeff = (0, Utils_1.nround)(c, n); let m = String(coeff).split('.').pop(); let d = n - ((m === null || m === void 0 ? void 0 : m.length) || 0); //if we're asking for more significant figures if (d > 0) { coeff = coeff + (new Array(d + 1).join('0')); } return coeff; } } exports.default = Scientific; //# sourceMappingURL=Scientific.js.map