exactnumber
Advanced tools
Comparing version 0.8.0 to 0.8.1
/*! | ||
* exactnumber v0.8.0 (https://www.npmjs.com/package/exactnumber) | ||
* exactnumber v0.8.1 (https://www.npmjs.com/package/exactnumber) | ||
* (c) Dani Biro | ||
@@ -239,20 +239,19 @@ * @license MIT | ||
const exp = 10n ** BigInt(Math.abs(shift)); | ||
const numberToZero = shift > 0 ? this.number / exp : this.number * exp; | ||
const outDigits = shift > 0 ? this.number / exp : this.number * exp; | ||
if (roundingMode === RoundingMode.TO_ZERO) { | ||
return new FixedNumber(numberToZero, decimals); | ||
return new FixedNumber(outDigits, decimals); | ||
} | ||
const expectedFracDecimals = shift > 0 ? Math.abs(shift) : decimals; | ||
const fracPart = shift > 0 ? this.number % exp : numberToZero % 10n ** BigInt(decimals); | ||
if (fracPart === 0n) | ||
return new FixedNumber(numberToZero, decimals); | ||
const extraDigits = shift > 0 ? this.number % exp : 0n; | ||
if (extraDigits === 0n) | ||
return new FixedNumber(outDigits, decimals); | ||
if (roundingMode === RoundingMode.AWAY_FROM_ZERO) { | ||
const res = this.number < 0n ? numberToZero - 1n : numberToZero + 1n; | ||
const res = this.number < 0n ? outDigits - 1n : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
} | ||
if (roundingMode === RoundingMode.TO_POSITIVE) { | ||
const res = this.number < 0n ? numberToZero : numberToZero + 1n; | ||
const res = this.number < 0n ? outDigits : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
} | ||
if (roundingMode === RoundingMode.TO_NEGATIVE) { | ||
const res = this.number >= 0n ? numberToZero : numberToZero - 1n; | ||
const res = this.number >= 0n ? outDigits : outDigits - 1n; | ||
return new FixedNumber(res, decimals); | ||
@@ -270,10 +269,13 @@ } | ||
} | ||
let fracStr = (fracPart < 0n ? -fracPart : fracPart).toString(); | ||
if (fracStr.length < expectedFracDecimals) { | ||
fracStr = '0'.repeat(expectedFracDecimals - fracStr.length) + fracStr; | ||
let extraDigitsStr = (extraDigits < 0n ? -extraDigits : extraDigits).toString(); | ||
// '00123' extra part will appear in extraDigitsStr as '123' | ||
// -> in this case we can exclude the tie case by setting the extra part to zero | ||
const expectedFracDecimals = shift > 0 ? shift : 0; | ||
if (extraDigitsStr.length < expectedFracDecimals) { | ||
extraDigitsStr = '0'; | ||
} | ||
let isTie = fracStr[0] === '5'; | ||
let isTie = extraDigitsStr[0] === '5'; | ||
if (isTie) { | ||
for (let i = 1; i < fracStr.length; i++) { | ||
if (fracStr[i] !== '0') { | ||
for (let i = 1; i < extraDigitsStr.length; i++) { | ||
if (extraDigitsStr[i] !== '0') { | ||
isTie = false; | ||
@@ -286,28 +288,28 @@ break; | ||
if (roundingMode === RoundingMode.NEAREST_TO_ZERO) { | ||
return new FixedNumber(numberToZero, decimals); | ||
return new FixedNumber(outDigits, decimals); | ||
} | ||
if (roundingMode === RoundingMode.NEAREST_AWAY_FROM_ZERO) { | ||
const res = this.number < 0n ? numberToZero - 1n : numberToZero + 1n; | ||
const res = this.number < 0n ? outDigits - 1n : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
} | ||
if (roundingMode === undefined || roundingMode === RoundingMode.NEAREST_TO_POSITIVE) { | ||
const res = this.number < 0n ? numberToZero : numberToZero + 1n; | ||
const res = this.number < 0n ? outDigits : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
} | ||
if (roundingMode === RoundingMode.NEAREST_TO_NEGATIVE) { | ||
const res = this.number >= 0n ? numberToZero : numberToZero - 1n; | ||
const res = this.number >= 0n ? outDigits : outDigits - 1n; | ||
return new FixedNumber(res, decimals); | ||
} | ||
if (roundingMode === RoundingMode.NEAREST_TO_EVEN) { | ||
if (numberToZero % 2n === 0n) { | ||
return new FixedNumber(numberToZero, decimals); | ||
if (outDigits % 2n === 0n) { | ||
return new FixedNumber(outDigits, decimals); | ||
} | ||
const res = numberToZero < 0n ? numberToZero - 1n : numberToZero + 1n; | ||
const res = outDigits < 0n ? outDigits - 1n : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
} | ||
} | ||
if (Number(fracStr[0]) < 5) { | ||
return new FixedNumber(numberToZero, decimals); | ||
if (Number(extraDigitsStr[0]) < 5) { | ||
return new FixedNumber(outDigits, decimals); | ||
} | ||
const res = this.number < 0 ? numberToZero - 1n : numberToZero + 1n; | ||
const res = this.number < 0 ? outDigits - 1n : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
@@ -314,0 +316,0 @@ } |
/*! | ||
* exactnumber v0.8.0 (https://www.npmjs.com/package/exactnumber) | ||
* exactnumber v0.8.1 (https://www.npmjs.com/package/exactnumber) | ||
* (c) Dani Biro | ||
@@ -7,2 +7,2 @@ * @license MIT | ||
var t,n;!function(t){t.NEAREST_TO_POSITIVE="NP",t.NEAREST_TO_NEGATIVE="NN",t.NEAREST_TO_EVEN="NE",t.NEAREST_TO_ZERO="NZ",t.NEAREST_AWAY_FROM_ZERO="NA",t.TO_POSITIVE="P",t.TO_NEGATIVE="N",t.TO_ZERO="Z",t.AWAY_FROM_ZERO="A"}(t||(t={})),function(t){t.TRUNCATED="T",t.FLOORED="F",t.EUCLIDEAN="E"}(n||(n={}));const r=t=>{let n=t.length;for(;n>0&&["0","."].includes(t.charAt(n-1));)n--;return n!==t.length?t.slice(0,n):t},e=(t,n,e)=>{let i=t.toString();if(0===n)return i;const o=i.startsWith("-");if(o&&(i=i.slice(1)),n>=i.length&&(i="0".repeat(n-i.length+1)+i),n>0){const t=i.slice(0,-n);let o=i.slice(-n);e&&(o=r(o)),i=o.length?`${t}.${o}`:t}return o?`-${i}`:i};class i{constructor(t,n=0){if(this.type="fixed","bigint"==typeof t)this.number=t,this.decimalPos=n;else{const n=this.parseConstructorParameter(t);this.number=n.number,this.decimalPos=n.decimalPos}}parseConstructorParameter(t){if(t instanceof i)return{number:t.number,decimalPos:t.decimalPos};if(t instanceof o){if(!t.isInteger())throw new Error("Cannot create FixedNumber from non-integer Fraction");return{number:t.trunc().number,decimalPos:0}}if("number"==typeof t){if(!Number.isSafeInteger(t))throw new Error("The specified number cannot be exactly represented as an integer. Please provide a string instead.");return{number:BigInt(t),decimalPos:0}}if("string"==typeof t){if(0===(t=t.trim()).length)throw new Error("Empty string is not allowed");const n=t.match(/^(-?[0-9]*)(?:\.([0-9]*))?(?:[eE]([+-]?[0-9]+))?$/);if(!n)throw new Error(`Cannot parse number "${t}"`);let r=0,e=n[1]??"0";if(void 0!==n[2]&&(e+=n[2],r+=n[2].length),void 0!==n[3]){const t=Number(n[3]);t>0?e+="0".repeat(t):r-=t}return{number:BigInt(e),decimalPos:r}}throw new Error("Unsupported parameter!")}scaleNumber(t,n){const r=Math.max(this.decimalPos,n);return{a:r===this.decimalPos?this.number:this.number*10n**BigInt(r-this.decimalPos),b:r===n?t:t*10n**BigInt(r-n),decimalPos:r}}add(t){const n=s(t);if(n instanceof o)return n.add(this);const r=n,{a:e,b:a,decimalPos:u}=this.scaleNumber(r.number,r.decimalPos);return new i(e+a,u)}sub(t){const n=s(t);return this.add(n.neg())}mul(t){const n=s(t);if(n instanceof o)return n.mul(this);const r=n;return new i(this.number*r.number,this.decimalPos+r.decimalPos)}pow(t){const n=s(t).toNumber();if(!Number.isSafeInteger(n)||n<0)throw new Error("Unsupported parameter");return new i(this.number**BigInt(n),this.decimalPos*n)}div(t){return this.convertToFraction().div(t)}divToInt(t){const n=s(t);if(n instanceof o)return this.convertToFraction().divToInt(n);const r=n,{a:e,b:a}=this.scaleNumber(r.number,r.decimalPos);return new i(e/a)}mod(t,r=n.TRUNCATED){const e=s(t);if(e instanceof o)return this.convertToFraction().mod(e);const a=e,{a:u,b:m,decimalPos:h}=this.scaleNumber(a.number,a.decimalPos),c=u%m,d=new i(c,h);if(r===n.TRUNCATED)return d;if(r===n.FLOORED)return Number(u<0)^Number(m<0)?d.add(m):d;if(r===n.EUCLIDEAN)return c<0?d.add(m<0?-m:m):d;throw new Error("Invalid ModType")}abs(){return new i(this.number<0?-this.number:this.number,this.decimalPos)}neg(){return this.mul(-1n)}inv(){return this.convertToFraction().inv()}floor(n){return 0===this.decimalPos?this:this.round(n,t.TO_NEGATIVE)}ceil(n){return 0===this.decimalPos?this:this.round(n,t.TO_POSITIVE)}trunc(n){return 0===this.decimalPos?this:this.round(n,t.TO_ZERO)}round(n,r){if(n=void 0===n?0:n,!Number.isSafeInteger(n)||n<0)throw new Error("Invalid value for decimals");const e=this.decimalPos-n,o=10n**BigInt(Math.abs(e)),s=e>0?this.number/o:this.number*o;if(r===t.TO_ZERO)return new i(s,n);const a=e>0?Math.abs(e):n,u=e>0?this.number%o:s%10n**BigInt(n);if(0n===u)return new i(s,n);if(r===t.AWAY_FROM_ZERO){const t=this.number<0n?s-1n:s+1n;return new i(t,n)}if(r===t.TO_POSITIVE){const t=this.number<0n?s:s+1n;return new i(t,n)}if(r===t.TO_NEGATIVE){const t=this.number>=0n?s:s-1n;return new i(t,n)}if(![void 0,t.NEAREST_TO_ZERO,t.NEAREST_AWAY_FROM_ZERO,t.NEAREST_TO_POSITIVE,t.NEAREST_TO_NEGATIVE,t.NEAREST_TO_EVEN].includes(r))throw new Error("Invalid rounding mode. Use the predefined values from the RoundingMode enum.");let m=(u<0n?-u:u).toString();m.length<a&&(m="0".repeat(a-m.length)+m);let h="5"===m[0];if(h)for(let t=1;t<m.length;t++)if("0"!==m[t]){h=!1;break}if(h){if(r===t.NEAREST_TO_ZERO)return new i(s,n);if(r===t.NEAREST_AWAY_FROM_ZERO){const t=this.number<0n?s-1n:s+1n;return new i(t,n)}if(void 0===r||r===t.NEAREST_TO_POSITIVE){const t=this.number<0n?s:s+1n;return new i(t,n)}if(r===t.NEAREST_TO_NEGATIVE){const t=this.number>=0n?s:s-1n;return new i(t,n)}if(r===t.NEAREST_TO_EVEN){if(s%2n===0n)return new i(s,n);return new i(s<0n?s-1n:s+1n,n)}}if(Number(m[0])<5)return new i(s,n);const c=this.number<0?s-1n:s+1n;return new i(c,n)}_incExponent(t){if(0===t)return this;let n=this.number,r=this.decimalPos;if(t<0)r-=t;else{const e=Math.min(t,this.decimalPos);r-=e;const i=t-e;i>0&&(n*=10n**BigInt(i))}return new i(n,r)}roundToDigits(t,n){if(!Number.isSafeInteger(t)||t<1)throw new Error("Invalid value for digits");const r=this.number<0n,e=r?-this.number:this.number,o=e.toString();let s=new i(e,o.length).round(t,n);const a=o.length-this.decimalPos;return s=s._incExponent(a),r?s.neg():s}intPart(){return this.trunc()}fracPart(){return this.sub(this.trunc())}sign(){return this.number<0n?-1:1}bitwiseAnd(t){if(t=a(t),!this.isInteger()||-1===this.sign()||!t.isInteger()||-1===t.sign())throw new Error("Only positive integers are supported");t instanceof o&&(t=t.trunc());const n=2n**24n;let r=this.normalize().number,e=t.trunc().normalize().number,s=0n,u=1n;for(;r>0&&e>0;){const t=BigInt.asUintN(24,r),i=BigInt.asUintN(24,e);s+=BigInt(Number(t)&Number(i))*u,u*=n,r/=n,e/=n}return new i(s)}bitwiseOr(t){if(t=a(t),!this.isInteger()||-1===this.sign()||!t.isInteger()||-1===t.sign())throw new Error("Only positive integers are supported");t instanceof o&&(t=t.trunc());const n=2n**24n;let r=this.normalize().number,e=t.trunc().normalize().number,s=0n,u=1n;for(;r>0||e>0;){const t=BigInt.asUintN(24,r),i=BigInt.asUintN(24,e);s+=BigInt(Number(t)|Number(i))*u,u*=n,r/=n,e/=n}return new i(s)}bitwiseXor(t){if(t=a(t),!this.isInteger()||-1===this.sign()||!t.isInteger()||-1===t.sign())throw new Error("Only positive integers are supported");t instanceof o&&(t=t.trunc());const n=2n**24n;let r=this.normalize().number,e=t.trunc().normalize().number,s=0n,u=1n;for(;r>0||e>0;){const t=BigInt.asUintN(24,r),i=BigInt.asUintN(24,e);s+=BigInt(Number(t)^Number(i))*u,u*=n,r/=n,e/=n}return new i(s)}shiftLeft(t){if(!this.isInteger()||-1===this.sign())throw new Error("Only positive integers are supported");if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid value for bitCount");const n=2n**BigInt(t);return this.mul(n)}shiftRight(t){if(!this.isInteger()||-1===this.sign())throw new Error("Only positive integers are supported");if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid value for bitCount");const n=2n**BigInt(t);return new i(this.normalize().number/n)}cmp(t){const n=s(t);if(n instanceof o)return-n.cmp(this);const r=n,{a:e,b:i}=this.scaleNumber(r.number,r.decimalPos);return e===i?0:e>i?1:-1}eq(t){return 0===this.cmp(t)}lt(t){return-1===this.cmp(t)}lte(t){return this.cmp(t)<=0}gt(t){return 1===this.cmp(t)}gte(t){return this.cmp(t)>=0}clamp(t,n){const r=a(t),e=a(n);if(r.gt(e))throw new Error("Min parameter has to be smaller than max");return this.lt(r)?r:this.gt(e)?e:this}isZero(){return 0n===this.number}isOne(){if(0===this.decimalPos)return 1n===this.number;const t=10n**BigInt(this.decimalPos),n=this.number/t;return 1n===n&&n*t===this.number}isInteger(){return 0===this.decimalPos||this.number%10n**BigInt(this.decimalPos)===0n}serialize(){return[this.number,this.decimalPos]}getFractionParts(t=!0){return this.convertToFraction().getFractionParts(t)}normalize(){if(0===this.decimalPos)return this;let t=this.decimalPos,n=this.number;for(;t>0&&n%10n===0n;)t--,n/=10n;return new i(n,t)}convertToFraction(){if(0===this.decimalPos)return new o(this.number,1n);const t=10n**BigInt(this.decimalPos);return new o(this.number,t)}toNumber(){return Number(this.toString())}toFixed(n,r=t.TO_ZERO){if(!Number.isSafeInteger(n)||n<0)throw new Error("Invalid parameter");const i=this.round(n,r);return e(i.number,n,!1)}toExponential(n,r=t.TO_ZERO){if(!Number.isSafeInteger(n)||n<0)throw new Error("Invalid parameter");const e=this.roundToDigits(n+1,r).normalize(),i=-1===e.sign(),o=e.abs(),s=o.number.toString(),a=s.length<=n?`${s}${"0".repeat(n-s.length+1)}`:s.slice(0,n+1),u=a.length>1?`${a.slice(0,1)}.${a.slice(1)}`:a,m=o.decimalPos,h=s.length-1-m;return`${i?"-":""}${u}e${h>=0?"+":""}${h}`}toBase(t,n){if(!Number.isSafeInteger(t)||t<2||t>16)throw new Error("Invalid radix");if(void 0!==n&&(!Number.isSafeInteger(n)||n<0))throw new Error("Invalid parameter");const r=this.normalize();if(0===r.decimalPos)return r.number.toString(t);const e=void 0===n?Number.MAX_SAFE_INTEGER:n;let i=r.intPart(),o=r.sub(i);const s=-1===r.sign();s&&(i=i.neg(),o=o.neg());const a=new Map;let u=[];for(;!o.isZero();){const n=o.mul(t),r=n.toString(),i=a.get(r);if(void 0!==i){u=[...u.slice(0,i-1),"(",...u.slice(i-1),")"];break}if(u.length===e)break;const s=Math.abs(n.intPart().toNumber());u.push(s.toString(t)),o=n.fracPart(),a.set(r,u.length)}return[s?"-":"",i.number.toString(t),u.length?".":"",...u].join("")}toFraction(){return this.convertToFraction().toFraction()}toString(t,n){if(void 0===t||10===t){const t=void 0!==n?this.trunc(n):this;return e(t.number,t.decimalPos,!0)}return this.toBase(t,n)}toPrecision(n,r=t.TO_ZERO){if(!Number.isSafeInteger(n)||n<1)throw new Error("Invalid parameter");const i=this.roundToDigits(n,r);return e(i.number,i.decimalPos,!1)}valueOf(){throw new Error("Unsafe conversion to Number type! Use toNumber() instead.")}}class o{constructor(t,n){if(this.type="fraction","bigint"==typeof t&&"bigint"==typeof n)this.numerator=t,this.denominator=n;else{const r=this.parseParameter(t),e=this.parseParameter(n),o=r.div(e),s=o instanceof i?o.convertToFraction():o;this.numerator=s.numerator,this.denominator=s.denominator}if(0n===this.denominator)throw new Error("Division by zero")}parseRepeatingDecimal(t){if(!t.includes("("))return new i(t).convertToFraction();const n=(t=t.trim()).match(/^(-?[0-9]*)\.([0-9]+)?\(([0-9]+)\)(?:[eE]([+-]?[0-9]+))?$/);if(!n)throw new Error(`Cannot parse string "${t}"`);const r="-"===n[1]?"-0":n[1],e=n[2]??"",s=n[3],a=n[4],u=BigInt(r+e+s)-BigInt(r+e),m=BigInt("9".repeat(s.length)+"0".repeat(e.length)),h=new o(u,m);if(void 0!==a){const t=a.startsWith("-"),n=10n**BigInt(t?a.slice(1):a);return t?h.div(n).normalize():h.mul(n).normalize()}return h.normalize()}parseParameter(t){if(t instanceof o)return t;if(t instanceof i)return t.convertToFraction();if("number"==typeof t){if(!Number.isSafeInteger(t))throw new Error("Floating point values as numbers are unsafe. Please provide them as a string.");return new o(BigInt(t),1n)}if("bigint"==typeof t)return new o(t,1n);if("string"==typeof t){const n=t.split("/");if(n.length>2)throw new Error(`Cannot parse string '${t}'`);const r=this.parseRepeatingDecimal(n[0]),e=n[1]?this.parseRepeatingDecimal(n[1]):new o(1n,1n);return r.div(e).convertToFraction()}throw new Error("Unsupported parameter!")}add(t){const{numerator:n,denominator:r}=this.parseParameter(t);return this.denominator===r?new o(this.numerator+n,this.denominator):new o(this.numerator*r+n*this.denominator,r*this.denominator)}sub(t){const{numerator:n,denominator:r}=this.parseParameter(t);return this.add(new o(-n,r))}mul(t){const{numerator:n,denominator:r}=this.parseParameter(t);return new o(this.numerator*n,this.denominator*r)}div(t){const{numerator:n,denominator:r}=this.parseParameter(t);return this.mul(new o(r,n))}divToInt(t){return this.div(t).trunc()}mod(t,r=n.TRUNCATED){const e=this.parseParameter(t),i=e.denominator*this.numerator%(e.numerator*this.denominator),s=this.denominator*e.denominator,a=new o(i,s);if(r===n.TRUNCATED)return a;if(r===n.FLOORED)return Number(-1===this.sign())^Number(-1===e.sign())?a.add(e):a;if(r===n.EUCLIDEAN)return a.sign()<0?a.add(e.sign()<0?e.neg():e):a;throw new Error("Invalid ModType")}pow(t){const n=this.parseParameter(t);if(!n.isInteger()||-1===n.sign())throw new Error("Unsupported parameter");const r=n.numerator/n.denominator;return new o(this.numerator**r,this.denominator**r)}inv(){return new o(this.denominator,this.numerator)}floor(n){return 1n===this.denominator?new i(this.numerator):this.round(n,t.TO_NEGATIVE)}ceil(n){return 1n===this.denominator?new i(this.numerator):this.round(n,t.TO_POSITIVE)}trunc(n){return 1n===this.denominator?new i(this.numerator):this.round(n,t.TO_ZERO)}round(t,n){if(t=void 0===t?0:t,!Number.isSafeInteger(t)||t<0)throw new Error("Invalid value for decimals");const r=this.toFixedNumber(t+1);if(this.sub(r).isZero())return r.round(t,n);return new i(`${r.toFixed(t+1)}1`).round(t,n)}roundToDigits(t,n){if(!Number.isSafeInteger(t)||t<1)throw new Error("Invalid value for digits");if(this.isZero())return new i(0n);let r=this.abs(),e=0;for(;r.gte(1n);)r=r.div(10n),e++;const s=new o(1n,10n);for(;r.lt(s);)r=r.mul(10n),e--;let a=r.round(t,n);return a=a._incExponent(e),-1===this.sign()?a.neg():a}gcd(t,n){let r=t<0?-t:t,e=n<0?-n:n;if(e>r){const t=r;r=e,e=t}for(;;){if(0n===e)return r;if(r%=e,0n===r)return e;e%=r}}lcm(t,n){return t*n/this.gcd(t,n)}normalize(){let{numerator:t,denominator:n}=this;const r=this.gcd(t,n);return r>1n&&(t/=r,n/=r),n<0n&&(t=-t,n=-n),new o(t,n)}getFractionParts(t=!0){const n=t?this.normalize():this;return{numerator:new i(n.numerator),denominator:new i(n.denominator)}}sign(){return(this.numerator<0n?-1:1)*(this.denominator<0n?-1:1)}abs(){return new o(this.numerator<0n?-this.numerator:this.numerator,this.denominator<0n?-this.denominator:this.denominator)}neg(){return this.mul(-1n)}intPart(){return this.trunc()}fracPart(){return this.sub(this.trunc())}cmp(t){const n=this.parseParameter(t),r=this.denominator===n.denominator,e=r?this.numerator:this.numerator*n.denominator,i=r?n.numerator:n.numerator*this.denominator;return e===i?0:e>i?1:-1}eq(t){return 0===this.cmp(t)}lt(t){return-1===this.cmp(t)}lte(t){return this.cmp(t)<=0}gt(t){return 1===this.cmp(t)}gte(t){return this.cmp(t)>=0}clamp(t,n){const r=a(t),e=a(n);if(r.gt(e))throw new Error("Min parameter has to be smaller than max");return this.lt(r)?r:this.gt(e)?e:this}isZero(){return 0n===this.numerator}isOne(){return this.numerator===this.denominator}isInteger(){return this.numerator%this.denominator===0n}serialize(){return[this.numerator,this.denominator]}toNumber(){return Number(this.numerator)/Number(this.denominator)}convertToFraction(){return this}getNumberForBitwiseOp(){if(!this.isInteger()||-1===this.sign())throw new Error("Only positive integers are supported");return this.intPart()}bitwiseAnd(t){return this.getNumberForBitwiseOp().bitwiseAnd(t)}bitwiseOr(t){return this.getNumberForBitwiseOp().bitwiseOr(t)}bitwiseXor(t){return this.getNumberForBitwiseOp().bitwiseXor(t)}shiftLeft(t){return this.getNumberForBitwiseOp().shiftLeft(t)}shiftRight(t){return this.getNumberForBitwiseOp().shiftRight(t)}getDecimalFormat(t){t=void 0===t?Number.MAX_SAFE_INTEGER:t;let n=this.denominator<0?-this.denominator:this.denominator,r=0;for(;n%2n===0n;)n/=2n,r++;let e=0;for(;n%5n===0n;)n/=5n,e++;const i=Math.max(r,e);if(1n===n)return{cycleLen:0,cycleStart:i};const o=Math.max(1,t-i);let s=10n%n,a=1;for(;1n!==s;){if(a===o)return{cycleLen:null,cycleStart:i};s=10n*s%n,a++}return{cycleLen:a,cycleStart:i}}toFixed(n,r=t.TO_ZERO){if(!Number.isSafeInteger(n)||n<0)throw new Error("Invalid parameter");const[i,o]=this.round(n,r).serialize();return e(i,o,!1)}toRepeatingParts(t){if(this.isZero())return["0","",""];const{cycleLen:n,cycleStart:e}=this.normalize().getDecimalFormat(t);if(null===n||0===n){const n=t??e,i=this.toFixed(n),o=r(i).split(".");return[o[0],o[1]??"",""]}const i=e+n,o=this.toFixed(i).split(".");return[o[0],o[1].slice(0,e),o[1].slice(e)]}toRepeatingDigits(t){const n=this.toRepeatingParts(t);let r=n[0];return(n[1]||n[2])&&(r+=`.${n[1]}`),n[2]&&(r+=`(${n[2]})`),r}toExponential(n,r=t.TO_ZERO){if(!Number.isSafeInteger(n)||n<0)throw new Error("Invalid parameters");return this.toFixedNumber(n).toExponential(n,r)}toFraction(){const{numerator:t,denominator:n}=this.normalize();return`${t.toString()}/${n.toString()}`}toFixedNumber(t){const n=this.numerator*10n**BigInt(t);return new i(n/this.denominator,t)}toBase(t,n){if(!Number.isSafeInteger(t)||t<2||t>16)throw new Error("Invalid radix");if(void 0!==n&&(!Number.isSafeInteger(n)||n<0))throw new Error("Invalid parameter");if(10===t)return void 0===n?this.toRepeatingDigits(n):r(this.toFixed(n));const e=this.normalize(),i=void 0===n?Number.MAX_SAFE_INTEGER:n+1;let o=e.intPart(),s=e.sub(o);const a=-1===e.sign();a&&(o=o.neg(),s=s.neg());const u=new Map;let m=[];for(;!s.isZero()&&m.length!==i;){const n=s.mul(t),r=n.normalize().toFraction(),e=u.get(r);if(void 0!==e){m=[...m.slice(0,e-1),"(",...m.slice(e-1),")"];break}const i=Math.abs(n.intPart().toNumber());m.push(i.toString(t)),s=n.fracPart(),u.set(r,m.length)}return m.length===i&&m.pop(),[a?"-":"",o.toString(t),m.length?".":"",...m].join("")}toString(t,n){return void 0===t||10===t?this.toRepeatingDigits(n):this.toBase(t,n)}toPrecision(n,r=t.TO_ZERO){if(!Number.isSafeInteger(n)||n<1)throw new Error("Invalid parameter");const[i,o]=this.roundToDigits(n,r).serialize();return e(i,o,!1)}valueOf(){throw new Error("Unsafe conversion to Number type! Use toNumber() instead.")}}function s(t){if(t instanceof i||t instanceof o)return t;if("bigint"==typeof t)return new i(t);if("number"==typeof t){if(!Number.isSafeInteger(t))throw new Error("Floating point values as numbers are unsafe. Please provide them as a string.");return new i(t)}if("string"==typeof t)return t.includes("/")||t.includes("(")?new o(t,1n):new i(t);throw new Error("Unsupported parameter type")}const a=(t,n)=>{if(void 0===t)throw new Error("First parameter cannot be undefined");const r=s(t);if(void 0===n)return r;const e=s(n);return new o(r,1n).div(new o(e,1n))};a.min=(...t)=>{if(0===t.length)throw new Error("Got empty array");let n=a(t[0]);for(let r=1;r<t.length;r++){const e=a(t[r]);e.lt(n)&&(n=e)}return n},a.max=(...t)=>{if(0===t.length)throw new Error("Got empty array");let n=a(t[0]);for(let r=1;r<t.length;r++){const e=a(t[r]);e.gt(n)&&(n=e)}return n};const u=(t,n)=>{let r=0n;for(let e=0;e<t.length;e++){const i=t.charAt(e),o=parseInt(i,n);if(Number.isNaN(o))throw new Error(`Invalid digit "${i}"`);r*=BigInt(n),r+=BigInt(o)}return r};a.fromBase=(t,n)=>{if("string"!=typeof t)throw new Error("First parameter must be string");if(!Number.isSafeInteger(n)||n<2||n>16)throw new Error("Invalid radix");if(10===n)return a(t);if(0===(t=t.trim()).length)throw new Error("Empty string is not allowed");const r=t.startsWith("-");r&&(t=t.slice(1));const e=t.match(/^([0-9a-f]*)(?:\.([0-9a-f]*)(?:\(([0-9a-f]+)\))?)?$/i);if(!e)throw new Error(`Cannot parse number "${t}"`);const i=e[1]??"",s=e[2]??"",m=e[3]??"";if(m.length>0){const t=u([i,s,m].join(""),n)-u([i,s].join(""),n),e=u((n-1).toString(n).repeat(m.length)+"0".repeat(s.length),n),a=new o(t,e).normalize();return r?a.neg():a}const h=u(i,n),c=u(s,n),d=new o(c,BigInt(n)**BigInt(s.length)),l=new o(h,1n).add(d).normalize();return r?l.neg():l};const m=(t,n,r)=>{if(!Number.isSafeInteger(t))throw new Error("Integer is expected for N");if(t<0)throw new Error("Negative N is not supported");if(0===t)throw new Error("N cannot be zero");if(1===t)return a(n).toFixed(r);const e=a(n);if(t%2==0&&-1===e.sign())throw new Error("Complex numbers are not supported");if(e.isZero())return new i(0n).toFixed(r);if(e.isOne())return new i(1n).toFixed(r);const s=new o(t-1,t),u=new o(e,t),m=((t,n)=>{const r=n<0;r&&(n=-n);let e=n**(1/t);return r&&(e=-e),e.toString()})(t,e.toNumber());let h=new i(m),c=h.trunc(r);for(;;){h=s.mul(h).add(u.mul(h.inv().pow(t-1)));const n=h.trunc(r);if(h.isZero()||c.eq(n))break;c=n}return h.toFixed(r)},h=(t,n)=>m(2,t,n),c=(t,n)=>m(3,t,n),d=(t,n,r)=>{const e=new o(t,1n),i=new o(n,1n).getFractionParts(!1);return m(i.denominator.toNumber(),e.pow(i.numerator),r)},l=(t,n)=>{const r=a(t);let e=r.add(1n),i=6n,s=4n;const u=r.pow(2n);let m=u;const h=new o(1n,10n**BigInt(n+5));for(;;){const t=m.mul(r.add(s-1n)).div(i);if(i*=s*(s+1n),s+=2n,m=m.mul(u),e=e.add(t).trunc(n+5),t.abs().lte(h))break}return e.toFixed(n)};class g{constructor(t,n){this.cachedDigits=0,this.fn=t,this.max=n}get(t){if(t<=this.cachedDigits)return this.cache.trunc(t);const n=new i(this.fn(t)),r=Math.min(this.max,t);return this.cachedDigits!==r&&(this.cache=n.trunc(r),this.cachedDigits=r),n}}const f=(t,n)=>{let r=a(t);if(r.isOne())return new i(0).toFixed(n);if(r.lte(0n))throw new Error("Invalid parameter");let e=0;for(;r.sub(1n).abs().gt("0.1");)r=new i(h(r,n+10)),e++;const o=r.sub(1n).div(r.add(1n)),s=o.pow(2n).normalize();let u=o,m=1n,c=a(o);for(;;){let t=a(0);for(let r=0;r<4;r++){u=u.mul(s),m+=2n;const r=u.div(m);t=t.add(r).trunc(n+10)}if(t.isZero())break;c=c.add(t)}return c=c.mul(2n**BigInt(e+1)),c.toFixed(n)},w=(t,n,r)=>{if(!Number.isSafeInteger(t)||t<2)throw new Error("Invalid parameter for N");const e=f(n,r+10),o=f(t,r+10);return new i(e).div(o).toFixed(r)},b=new g((t=>f(2n,t)),200),E=(t,n)=>new i(f(t,n+10)).div(b.get(n+10)).toFixed(n),p=new g((t=>f(10n,t)),200),I=(t,n)=>new i(f(t,n+10)).div(p.get(n+10)).toFixed(n),v=new g((t=>{if(0===t)return"3";let n=1n,r=3n*10n**BigInt(t+20),e=r;for(;0n!==r;)r=r*n/(4n*(n+1n)),n+=2n,e+=r/n;return`3.${e.toString().slice(1,t+1)}`}),1e3),N=t=>0===t?"3":v.get(t).toFixed(t),T=(n,r)=>{const e=r+10,{x:o,quadrant:s}=((t,n)=>{const r=new i(N(n)),e=r.mul(2n);(t=t.mod(e)).gt(r)?t=t.sub(e):t.lt(r.neg())&&(t=t.add(e));const o=r.div(2n),s=t.div(o);let a=0;return s.gte(o)?(a=2,t=r.sub(t)):s.gte(0n)?a=1:s.gte(o.neg())?(a=4,t=t.neg()):(a=3,t=r.sub(t.neg())),{quadrant:a,x:t}})(a(n),e),u=o.round(e,t.NEAREST_AWAY_FROM_ZERO).pow(2n).normalize();let m=u,h=2n,c=a(1n).sub(m.div(h).trunc(e)),d=3n;const l=a(1n).div(10n**BigInt(e));let g=1;for(;;){h*=d*(d+1n),d+=2n;const t=d*(d+1n);d+=2n,m=m.mul(u),h*=t;let i=m.mul(t);m=m.mul(u),i=i.sub(m);const o=i.div(h).trunc(e);if(g++,c=c.add(o),o.lt(l)){const t=c.trunc(r),i=o.add(l.mul(g)),s=c.add(i).trunc(r);if(t.eq(s))break;return a(T(n,e+50)).toFixed(r)}}return(1===s||4===s?c:c.neg()).round(r+3,t.TO_ZERO).toFixed(r)},O=(t,n)=>{const r=new i(N(n+10)),e=a(t);return T(r.div(2n).sub(e),n)},P=(t,n)=>{if(a(t).isZero())return"0";return a(O(t,n+10)).div(T(t,n+10)).toFixed(n)},F=(t,n)=>{let r=a(t);if(r.isZero())return"0";if(r.abs().isOne())return a(N(n)).div(4*r.sign()).toFixed(n);let e=0;for(;r.abs().gt("0.42");){const t=a(h(r.pow(2n).add(1n),n+10));r=r.div(t.add(1n)),e++}const i=r.pow(2).normalize(),o=i.pow(2).normalize();let s=3n,u=r.sub(r.mul(i).div(s)),m=r.mul(o);const c=a(1n).div(10n**BigInt(n+10));for(;;){s+=2n;const t=s+2n,r=m.mul(i.mul(-s).add(t)).div(s*t);if(s=t,m=m.mul(o),u=u.add(r).trunc(n+10),r.abs().lt(c))break}return u=u.mul(2n**BigInt(e)),u.toFixed(n)},S=(t,n)=>{const r=a(t);if(r.isZero())return"0";if(r.abs().isOne())return a(N(n)).mul(r.sign()).div(2n).toFixed(n);if(r.abs().eq("1/2"))return a(N(n)).mul(r.sign()).div(6n).toFixed(n);if(r.gt(1n)||r.lt(-1n))throw new Error("Out of range");const e=a(h(r.pow(2n).neg().add(1),n+10));return a(F(r.div(e.add(1n)),n+10)).mul(2).toFixed(n)},_=(t,n)=>{const r=a(t);if(r.isZero())return a(N(n)).div(2n).toFixed(n);if(r.isOne())return"0";if(r.abs().isOne())return N(n);if(r.abs().eq("1/2")){const t=a(N(n)).div(3n);return-1===r.sign()?t.mul(2n).toFixed(n):t.toFixed(n)}if(r.gt(1n)||r.lt(-1n))throw new Error("Out of range");return a(N(n+10)).div(2n).sub(S(r,n+10)).toFixed(n)},R=(t,n)=>{const r=a(t),e=r.pow(2n).normalize();let i=r,o=1n,s=r.trunc(n+5),u=2n;const m=a(1n).div(10n**BigInt(n+5));for(;;){i=i.mul(e),o*=u*(u+1n),u+=2n;const t=i.div(o);if(s=s.add(t).trunc(n+5),t.abs().lt(m))break}return s.toFixed(n)},x=(t,n)=>{const r=a(t).pow(2n).normalize();let e=r,i=2n,o=e.div(i).add(1n).trunc(n+5),s=3n;const u=a(1n).div(10n**BigInt(n+5));for(;;){e=e.mul(r),i*=s*(s+1n),s+=2n;const t=e.div(i);if(o=o.add(t).trunc(n+5),t.abs().lt(u))break}return o.toFixed(n)};export{a as ExactNumber,n as ModType,N as PI,t as RoundingMode,_ as acos,S as asin,F as atan,c as cbrt,T as cos,x as cosh,l as exp,f as log,I as log10,E as log2,w as logn,m as nthroot,d as pow,O as sin,R as sinh,h as sqrt,P as tan,r as trimTrailingZeros}; | ||
var t,n;!function(t){t.NEAREST_TO_POSITIVE="NP",t.NEAREST_TO_NEGATIVE="NN",t.NEAREST_TO_EVEN="NE",t.NEAREST_TO_ZERO="NZ",t.NEAREST_AWAY_FROM_ZERO="NA",t.TO_POSITIVE="P",t.TO_NEGATIVE="N",t.TO_ZERO="Z",t.AWAY_FROM_ZERO="A"}(t||(t={})),function(t){t.TRUNCATED="T",t.FLOORED="F",t.EUCLIDEAN="E"}(n||(n={}));const r=t=>{let n=t.length;for(;n>0&&["0","."].includes(t.charAt(n-1));)n--;return n!==t.length?t.slice(0,n):t},e=(t,n,e)=>{let i=t.toString();if(0===n)return i;const o=i.startsWith("-");if(o&&(i=i.slice(1)),n>=i.length&&(i="0".repeat(n-i.length+1)+i),n>0){const t=i.slice(0,-n);let o=i.slice(-n);e&&(o=r(o)),i=o.length?`${t}.${o}`:t}return o?`-${i}`:i};class i{constructor(t,n=0){if(this.type="fixed","bigint"==typeof t)this.number=t,this.decimalPos=n;else{const n=this.parseConstructorParameter(t);this.number=n.number,this.decimalPos=n.decimalPos}}parseConstructorParameter(t){if(t instanceof i)return{number:t.number,decimalPos:t.decimalPos};if(t instanceof o){if(!t.isInteger())throw new Error("Cannot create FixedNumber from non-integer Fraction");return{number:t.trunc().number,decimalPos:0}}if("number"==typeof t){if(!Number.isSafeInteger(t))throw new Error("The specified number cannot be exactly represented as an integer. Please provide a string instead.");return{number:BigInt(t),decimalPos:0}}if("string"==typeof t){if(0===(t=t.trim()).length)throw new Error("Empty string is not allowed");const n=t.match(/^(-?[0-9]*)(?:\.([0-9]*))?(?:[eE]([+-]?[0-9]+))?$/);if(!n)throw new Error(`Cannot parse number "${t}"`);let r=0,e=n[1]??"0";if(void 0!==n[2]&&(e+=n[2],r+=n[2].length),void 0!==n[3]){const t=Number(n[3]);t>0?e+="0".repeat(t):r-=t}return{number:BigInt(e),decimalPos:r}}throw new Error("Unsupported parameter!")}scaleNumber(t,n){const r=Math.max(this.decimalPos,n);return{a:r===this.decimalPos?this.number:this.number*10n**BigInt(r-this.decimalPos),b:r===n?t:t*10n**BigInt(r-n),decimalPos:r}}add(t){const n=s(t);if(n instanceof o)return n.add(this);const r=n,{a:e,b:a,decimalPos:u}=this.scaleNumber(r.number,r.decimalPos);return new i(e+a,u)}sub(t){const n=s(t);return this.add(n.neg())}mul(t){const n=s(t);if(n instanceof o)return n.mul(this);const r=n;return new i(this.number*r.number,this.decimalPos+r.decimalPos)}pow(t){const n=s(t).toNumber();if(!Number.isSafeInteger(n)||n<0)throw new Error("Unsupported parameter");return new i(this.number**BigInt(n),this.decimalPos*n)}div(t){return this.convertToFraction().div(t)}divToInt(t){const n=s(t);if(n instanceof o)return this.convertToFraction().divToInt(n);const r=n,{a:e,b:a}=this.scaleNumber(r.number,r.decimalPos);return new i(e/a)}mod(t,r=n.TRUNCATED){const e=s(t);if(e instanceof o)return this.convertToFraction().mod(e);const a=e,{a:u,b:m,decimalPos:c}=this.scaleNumber(a.number,a.decimalPos),h=u%m,d=new i(h,c);if(r===n.TRUNCATED)return d;if(r===n.FLOORED)return Number(u<0)^Number(m<0)?d.add(m):d;if(r===n.EUCLIDEAN)return h<0?d.add(m<0?-m:m):d;throw new Error("Invalid ModType")}abs(){return new i(this.number<0?-this.number:this.number,this.decimalPos)}neg(){return this.mul(-1n)}inv(){return this.convertToFraction().inv()}floor(n){return 0===this.decimalPos?this:this.round(n,t.TO_NEGATIVE)}ceil(n){return 0===this.decimalPos?this:this.round(n,t.TO_POSITIVE)}trunc(n){return 0===this.decimalPos?this:this.round(n,t.TO_ZERO)}round(n,r){if(n=void 0===n?0:n,!Number.isSafeInteger(n)||n<0)throw new Error("Invalid value for decimals");const e=this.decimalPos-n,o=10n**BigInt(Math.abs(e)),s=e>0?this.number/o:this.number*o;if(r===t.TO_ZERO)return new i(s,n);const a=e>0?this.number%o:0n;if(0n===a)return new i(s,n);if(r===t.AWAY_FROM_ZERO){const t=this.number<0n?s-1n:s+1n;return new i(t,n)}if(r===t.TO_POSITIVE){const t=this.number<0n?s:s+1n;return new i(t,n)}if(r===t.TO_NEGATIVE){const t=this.number>=0n?s:s-1n;return new i(t,n)}if(![void 0,t.NEAREST_TO_ZERO,t.NEAREST_AWAY_FROM_ZERO,t.NEAREST_TO_POSITIVE,t.NEAREST_TO_NEGATIVE,t.NEAREST_TO_EVEN].includes(r))throw new Error("Invalid rounding mode. Use the predefined values from the RoundingMode enum.");let u=(a<0n?-a:a).toString();const m=e>0?e:0;u.length<m&&(u="0");let c="5"===u[0];if(c)for(let t=1;t<u.length;t++)if("0"!==u[t]){c=!1;break}if(c){if(r===t.NEAREST_TO_ZERO)return new i(s,n);if(r===t.NEAREST_AWAY_FROM_ZERO){const t=this.number<0n?s-1n:s+1n;return new i(t,n)}if(void 0===r||r===t.NEAREST_TO_POSITIVE){const t=this.number<0n?s:s+1n;return new i(t,n)}if(r===t.NEAREST_TO_NEGATIVE){const t=this.number>=0n?s:s-1n;return new i(t,n)}if(r===t.NEAREST_TO_EVEN){if(s%2n===0n)return new i(s,n);return new i(s<0n?s-1n:s+1n,n)}}if(Number(u[0])<5)return new i(s,n);const h=this.number<0?s-1n:s+1n;return new i(h,n)}_incExponent(t){if(0===t)return this;let n=this.number,r=this.decimalPos;if(t<0)r-=t;else{const e=Math.min(t,this.decimalPos);r-=e;const i=t-e;i>0&&(n*=10n**BigInt(i))}return new i(n,r)}roundToDigits(t,n){if(!Number.isSafeInteger(t)||t<1)throw new Error("Invalid value for digits");const r=this.number<0n,e=r?-this.number:this.number,o=e.toString();let s=new i(e,o.length).round(t,n);const a=o.length-this.decimalPos;return s=s._incExponent(a),r?s.neg():s}intPart(){return this.trunc()}fracPart(){return this.sub(this.trunc())}sign(){return this.number<0n?-1:1}bitwiseAnd(t){if(t=a(t),!this.isInteger()||-1===this.sign()||!t.isInteger()||-1===t.sign())throw new Error("Only positive integers are supported");t instanceof o&&(t=t.trunc());const n=2n**24n;let r=this.normalize().number,e=t.trunc().normalize().number,s=0n,u=1n;for(;r>0&&e>0;){const t=BigInt.asUintN(24,r),i=BigInt.asUintN(24,e);s+=BigInt(Number(t)&Number(i))*u,u*=n,r/=n,e/=n}return new i(s)}bitwiseOr(t){if(t=a(t),!this.isInteger()||-1===this.sign()||!t.isInteger()||-1===t.sign())throw new Error("Only positive integers are supported");t instanceof o&&(t=t.trunc());const n=2n**24n;let r=this.normalize().number,e=t.trunc().normalize().number,s=0n,u=1n;for(;r>0||e>0;){const t=BigInt.asUintN(24,r),i=BigInt.asUintN(24,e);s+=BigInt(Number(t)|Number(i))*u,u*=n,r/=n,e/=n}return new i(s)}bitwiseXor(t){if(t=a(t),!this.isInteger()||-1===this.sign()||!t.isInteger()||-1===t.sign())throw new Error("Only positive integers are supported");t instanceof o&&(t=t.trunc());const n=2n**24n;let r=this.normalize().number,e=t.trunc().normalize().number,s=0n,u=1n;for(;r>0||e>0;){const t=BigInt.asUintN(24,r),i=BigInt.asUintN(24,e);s+=BigInt(Number(t)^Number(i))*u,u*=n,r/=n,e/=n}return new i(s)}shiftLeft(t){if(!this.isInteger()||-1===this.sign())throw new Error("Only positive integers are supported");if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid value for bitCount");const n=2n**BigInt(t);return this.mul(n)}shiftRight(t){if(!this.isInteger()||-1===this.sign())throw new Error("Only positive integers are supported");if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid value for bitCount");const n=2n**BigInt(t);return new i(this.normalize().number/n)}cmp(t){const n=s(t);if(n instanceof o)return-n.cmp(this);const r=n,{a:e,b:i}=this.scaleNumber(r.number,r.decimalPos);return e===i?0:e>i?1:-1}eq(t){return 0===this.cmp(t)}lt(t){return-1===this.cmp(t)}lte(t){return this.cmp(t)<=0}gt(t){return 1===this.cmp(t)}gte(t){return this.cmp(t)>=0}clamp(t,n){const r=a(t),e=a(n);if(r.gt(e))throw new Error("Min parameter has to be smaller than max");return this.lt(r)?r:this.gt(e)?e:this}isZero(){return 0n===this.number}isOne(){if(0===this.decimalPos)return 1n===this.number;const t=10n**BigInt(this.decimalPos),n=this.number/t;return 1n===n&&n*t===this.number}isInteger(){return 0===this.decimalPos||this.number%10n**BigInt(this.decimalPos)===0n}serialize(){return[this.number,this.decimalPos]}getFractionParts(t=!0){return this.convertToFraction().getFractionParts(t)}normalize(){if(0===this.decimalPos)return this;let t=this.decimalPos,n=this.number;for(;t>0&&n%10n===0n;)t--,n/=10n;return new i(n,t)}convertToFraction(){if(0===this.decimalPos)return new o(this.number,1n);const t=10n**BigInt(this.decimalPos);return new o(this.number,t)}toNumber(){return Number(this.toString())}toFixed(n,r=t.TO_ZERO){if(!Number.isSafeInteger(n)||n<0)throw new Error("Invalid parameter");const i=this.round(n,r);return e(i.number,n,!1)}toExponential(n,r=t.TO_ZERO){if(!Number.isSafeInteger(n)||n<0)throw new Error("Invalid parameter");const e=this.roundToDigits(n+1,r).normalize(),i=-1===e.sign(),o=e.abs(),s=o.number.toString(),a=s.length<=n?`${s}${"0".repeat(n-s.length+1)}`:s.slice(0,n+1),u=a.length>1?`${a.slice(0,1)}.${a.slice(1)}`:a,m=o.decimalPos,c=s.length-1-m;return`${i?"-":""}${u}e${c>=0?"+":""}${c}`}toBase(t,n){if(!Number.isSafeInteger(t)||t<2||t>16)throw new Error("Invalid radix");if(void 0!==n&&(!Number.isSafeInteger(n)||n<0))throw new Error("Invalid parameter");const r=this.normalize();if(0===r.decimalPos)return r.number.toString(t);const e=void 0===n?Number.MAX_SAFE_INTEGER:n;let i=r.intPart(),o=r.sub(i);const s=-1===r.sign();s&&(i=i.neg(),o=o.neg());const a=new Map;let u=[];for(;!o.isZero();){const n=o.mul(t),r=n.toString(),i=a.get(r);if(void 0!==i){u=[...u.slice(0,i-1),"(",...u.slice(i-1),")"];break}if(u.length===e)break;const s=Math.abs(n.intPart().toNumber());u.push(s.toString(t)),o=n.fracPart(),a.set(r,u.length)}return[s?"-":"",i.number.toString(t),u.length?".":"",...u].join("")}toFraction(){return this.convertToFraction().toFraction()}toString(t,n){if(void 0===t||10===t){const t=void 0!==n?this.trunc(n):this;return e(t.number,t.decimalPos,!0)}return this.toBase(t,n)}toPrecision(n,r=t.TO_ZERO){if(!Number.isSafeInteger(n)||n<1)throw new Error("Invalid parameter");const i=this.roundToDigits(n,r);return e(i.number,i.decimalPos,!1)}valueOf(){throw new Error("Unsafe conversion to Number type! Use toNumber() instead.")}}class o{constructor(t,n){if(this.type="fraction","bigint"==typeof t&&"bigint"==typeof n)this.numerator=t,this.denominator=n;else{const r=this.parseParameter(t),e=this.parseParameter(n),o=r.div(e),s=o instanceof i?o.convertToFraction():o;this.numerator=s.numerator,this.denominator=s.denominator}if(0n===this.denominator)throw new Error("Division by zero")}parseRepeatingDecimal(t){if(!t.includes("("))return new i(t).convertToFraction();const n=(t=t.trim()).match(/^(-?[0-9]*)\.([0-9]+)?\(([0-9]+)\)(?:[eE]([+-]?[0-9]+))?$/);if(!n)throw new Error(`Cannot parse string "${t}"`);const r="-"===n[1]?"-0":n[1],e=n[2]??"",s=n[3],a=n[4],u=BigInt(r+e+s)-BigInt(r+e),m=BigInt("9".repeat(s.length)+"0".repeat(e.length)),c=new o(u,m);if(void 0!==a){const t=a.startsWith("-"),n=10n**BigInt(t?a.slice(1):a);return t?c.div(n).normalize():c.mul(n).normalize()}return c.normalize()}parseParameter(t){if(t instanceof o)return t;if(t instanceof i)return t.convertToFraction();if("number"==typeof t){if(!Number.isSafeInteger(t))throw new Error("Floating point values as numbers are unsafe. Please provide them as a string.");return new o(BigInt(t),1n)}if("bigint"==typeof t)return new o(t,1n);if("string"==typeof t){const n=t.split("/");if(n.length>2)throw new Error(`Cannot parse string '${t}'`);const r=this.parseRepeatingDecimal(n[0]),e=n[1]?this.parseRepeatingDecimal(n[1]):new o(1n,1n);return r.div(e).convertToFraction()}throw new Error("Unsupported parameter!")}add(t){const{numerator:n,denominator:r}=this.parseParameter(t);return this.denominator===r?new o(this.numerator+n,this.denominator):new o(this.numerator*r+n*this.denominator,r*this.denominator)}sub(t){const{numerator:n,denominator:r}=this.parseParameter(t);return this.add(new o(-n,r))}mul(t){const{numerator:n,denominator:r}=this.parseParameter(t);return new o(this.numerator*n,this.denominator*r)}div(t){const{numerator:n,denominator:r}=this.parseParameter(t);return this.mul(new o(r,n))}divToInt(t){return this.div(t).trunc()}mod(t,r=n.TRUNCATED){const e=this.parseParameter(t),i=e.denominator*this.numerator%(e.numerator*this.denominator),s=this.denominator*e.denominator,a=new o(i,s);if(r===n.TRUNCATED)return a;if(r===n.FLOORED)return Number(-1===this.sign())^Number(-1===e.sign())?a.add(e):a;if(r===n.EUCLIDEAN)return a.sign()<0?a.add(e.sign()<0?e.neg():e):a;throw new Error("Invalid ModType")}pow(t){const n=this.parseParameter(t);if(!n.isInteger()||-1===n.sign())throw new Error("Unsupported parameter");const r=n.numerator/n.denominator;return new o(this.numerator**r,this.denominator**r)}inv(){return new o(this.denominator,this.numerator)}floor(n){return 1n===this.denominator?new i(this.numerator):this.round(n,t.TO_NEGATIVE)}ceil(n){return 1n===this.denominator?new i(this.numerator):this.round(n,t.TO_POSITIVE)}trunc(n){return 1n===this.denominator?new i(this.numerator):this.round(n,t.TO_ZERO)}round(t,n){if(t=void 0===t?0:t,!Number.isSafeInteger(t)||t<0)throw new Error("Invalid value for decimals");const r=this.toFixedNumber(t+1);if(this.sub(r).isZero())return r.round(t,n);return new i(`${r.toFixed(t+1)}1`).round(t,n)}roundToDigits(t,n){if(!Number.isSafeInteger(t)||t<1)throw new Error("Invalid value for digits");if(this.isZero())return new i(0n);let r=this.abs(),e=0;for(;r.gte(1n);)r=r.div(10n),e++;const s=new o(1n,10n);for(;r.lt(s);)r=r.mul(10n),e--;let a=r.round(t,n);return a=a._incExponent(e),-1===this.sign()?a.neg():a}gcd(t,n){let r=t<0?-t:t,e=n<0?-n:n;if(e>r){const t=r;r=e,e=t}for(;;){if(0n===e)return r;if(r%=e,0n===r)return e;e%=r}}lcm(t,n){return t*n/this.gcd(t,n)}normalize(){let{numerator:t,denominator:n}=this;const r=this.gcd(t,n);return r>1n&&(t/=r,n/=r),n<0n&&(t=-t,n=-n),new o(t,n)}getFractionParts(t=!0){const n=t?this.normalize():this;return{numerator:new i(n.numerator),denominator:new i(n.denominator)}}sign(){return(this.numerator<0n?-1:1)*(this.denominator<0n?-1:1)}abs(){return new o(this.numerator<0n?-this.numerator:this.numerator,this.denominator<0n?-this.denominator:this.denominator)}neg(){return this.mul(-1n)}intPart(){return this.trunc()}fracPart(){return this.sub(this.trunc())}cmp(t){const n=this.parseParameter(t),r=this.denominator===n.denominator,e=r?this.numerator:this.numerator*n.denominator,i=r?n.numerator:n.numerator*this.denominator;return e===i?0:e>i?1:-1}eq(t){return 0===this.cmp(t)}lt(t){return-1===this.cmp(t)}lte(t){return this.cmp(t)<=0}gt(t){return 1===this.cmp(t)}gte(t){return this.cmp(t)>=0}clamp(t,n){const r=a(t),e=a(n);if(r.gt(e))throw new Error("Min parameter has to be smaller than max");return this.lt(r)?r:this.gt(e)?e:this}isZero(){return 0n===this.numerator}isOne(){return this.numerator===this.denominator}isInteger(){return this.numerator%this.denominator===0n}serialize(){return[this.numerator,this.denominator]}toNumber(){return Number(this.numerator)/Number(this.denominator)}convertToFraction(){return this}getNumberForBitwiseOp(){if(!this.isInteger()||-1===this.sign())throw new Error("Only positive integers are supported");return this.intPart()}bitwiseAnd(t){return this.getNumberForBitwiseOp().bitwiseAnd(t)}bitwiseOr(t){return this.getNumberForBitwiseOp().bitwiseOr(t)}bitwiseXor(t){return this.getNumberForBitwiseOp().bitwiseXor(t)}shiftLeft(t){return this.getNumberForBitwiseOp().shiftLeft(t)}shiftRight(t){return this.getNumberForBitwiseOp().shiftRight(t)}getDecimalFormat(t){t=void 0===t?Number.MAX_SAFE_INTEGER:t;let n=this.denominator<0?-this.denominator:this.denominator,r=0;for(;n%2n===0n;)n/=2n,r++;let e=0;for(;n%5n===0n;)n/=5n,e++;const i=Math.max(r,e);if(1n===n)return{cycleLen:0,cycleStart:i};const o=Math.max(1,t-i);let s=10n%n,a=1;for(;1n!==s;){if(a===o)return{cycleLen:null,cycleStart:i};s=10n*s%n,a++}return{cycleLen:a,cycleStart:i}}toFixed(n,r=t.TO_ZERO){if(!Number.isSafeInteger(n)||n<0)throw new Error("Invalid parameter");const[i,o]=this.round(n,r).serialize();return e(i,o,!1)}toRepeatingParts(t){if(this.isZero())return["0","",""];const{cycleLen:n,cycleStart:e}=this.normalize().getDecimalFormat(t);if(null===n||0===n){const n=t??e,i=this.toFixed(n),o=r(i).split(".");return[o[0],o[1]??"",""]}const i=e+n,o=this.toFixed(i).split(".");return[o[0],o[1].slice(0,e),o[1].slice(e)]}toRepeatingDigits(t){const n=this.toRepeatingParts(t);let r=n[0];return(n[1]||n[2])&&(r+=`.${n[1]}`),n[2]&&(r+=`(${n[2]})`),r}toExponential(n,r=t.TO_ZERO){if(!Number.isSafeInteger(n)||n<0)throw new Error("Invalid parameters");return this.toFixedNumber(n).toExponential(n,r)}toFraction(){const{numerator:t,denominator:n}=this.normalize();return`${t.toString()}/${n.toString()}`}toFixedNumber(t){const n=this.numerator*10n**BigInt(t);return new i(n/this.denominator,t)}toBase(t,n){if(!Number.isSafeInteger(t)||t<2||t>16)throw new Error("Invalid radix");if(void 0!==n&&(!Number.isSafeInteger(n)||n<0))throw new Error("Invalid parameter");if(10===t)return void 0===n?this.toRepeatingDigits(n):r(this.toFixed(n));const e=this.normalize(),i=void 0===n?Number.MAX_SAFE_INTEGER:n+1;let o=e.intPart(),s=e.sub(o);const a=-1===e.sign();a&&(o=o.neg(),s=s.neg());const u=new Map;let m=[];for(;!s.isZero()&&m.length!==i;){const n=s.mul(t),r=n.normalize().toFraction(),e=u.get(r);if(void 0!==e){m=[...m.slice(0,e-1),"(",...m.slice(e-1),")"];break}const i=Math.abs(n.intPart().toNumber());m.push(i.toString(t)),s=n.fracPart(),u.set(r,m.length)}return m.length===i&&m.pop(),[a?"-":"",o.toString(t),m.length?".":"",...m].join("")}toString(t,n){return void 0===t||10===t?this.toRepeatingDigits(n):this.toBase(t,n)}toPrecision(n,r=t.TO_ZERO){if(!Number.isSafeInteger(n)||n<1)throw new Error("Invalid parameter");const[i,o]=this.roundToDigits(n,r).serialize();return e(i,o,!1)}valueOf(){throw new Error("Unsafe conversion to Number type! Use toNumber() instead.")}}function s(t){if(t instanceof i||t instanceof o)return t;if("bigint"==typeof t)return new i(t);if("number"==typeof t){if(!Number.isSafeInteger(t))throw new Error("Floating point values as numbers are unsafe. Please provide them as a string.");return new i(t)}if("string"==typeof t)return t.includes("/")||t.includes("(")?new o(t,1n):new i(t);throw new Error("Unsupported parameter type")}const a=(t,n)=>{if(void 0===t)throw new Error("First parameter cannot be undefined");const r=s(t);if(void 0===n)return r;const e=s(n);return new o(r,1n).div(new o(e,1n))};a.min=(...t)=>{if(0===t.length)throw new Error("Got empty array");let n=a(t[0]);for(let r=1;r<t.length;r++){const e=a(t[r]);e.lt(n)&&(n=e)}return n},a.max=(...t)=>{if(0===t.length)throw new Error("Got empty array");let n=a(t[0]);for(let r=1;r<t.length;r++){const e=a(t[r]);e.gt(n)&&(n=e)}return n};const u=(t,n)=>{let r=0n;for(let e=0;e<t.length;e++){const i=t.charAt(e),o=parseInt(i,n);if(Number.isNaN(o))throw new Error(`Invalid digit "${i}"`);r*=BigInt(n),r+=BigInt(o)}return r};a.fromBase=(t,n)=>{if("string"!=typeof t)throw new Error("First parameter must be string");if(!Number.isSafeInteger(n)||n<2||n>16)throw new Error("Invalid radix");if(10===n)return a(t);if(0===(t=t.trim()).length)throw new Error("Empty string is not allowed");const r=t.startsWith("-");r&&(t=t.slice(1));const e=t.match(/^([0-9a-f]*)(?:\.([0-9a-f]*)(?:\(([0-9a-f]+)\))?)?$/i);if(!e)throw new Error(`Cannot parse number "${t}"`);const i=e[1]??"",s=e[2]??"",m=e[3]??"";if(m.length>0){const t=u([i,s,m].join(""),n)-u([i,s].join(""),n),e=u((n-1).toString(n).repeat(m.length)+"0".repeat(s.length),n),a=new o(t,e).normalize();return r?a.neg():a}const c=u(i,n),h=u(s,n),d=new o(h,BigInt(n)**BigInt(s.length)),l=new o(c,1n).add(d).normalize();return r?l.neg():l};const m=(t,n,r)=>{if(!Number.isSafeInteger(t))throw new Error("Integer is expected for N");if(t<0)throw new Error("Negative N is not supported");if(0===t)throw new Error("N cannot be zero");if(1===t)return a(n).toFixed(r);const e=a(n);if(t%2==0&&-1===e.sign())throw new Error("Complex numbers are not supported");if(e.isZero())return new i(0n).toFixed(r);if(e.isOne())return new i(1n).toFixed(r);const s=new o(t-1,t),u=new o(e,t),m=((t,n)=>{const r=n<0;r&&(n=-n);let e=n**(1/t);return r&&(e=-e),e.toString()})(t,e.toNumber());let c=new i(m),h=c.trunc(r);for(;;){c=s.mul(c).add(u.mul(c.inv().pow(t-1)));const n=c.trunc(r);if(c.isZero()||h.eq(n))break;h=n}return c.toFixed(r)},c=(t,n)=>m(2,t,n),h=(t,n)=>m(3,t,n),d=(t,n,r)=>{const e=new o(t,1n),i=new o(n,1n).getFractionParts(!1);return m(i.denominator.toNumber(),e.pow(i.numerator),r)},l=(t,n)=>{const r=a(t);let e=r.add(1n),i=6n,s=4n;const u=r.pow(2n);let m=u;const c=new o(1n,10n**BigInt(n+5));for(;;){const t=m.mul(r.add(s-1n)).div(i);if(i*=s*(s+1n),s+=2n,m=m.mul(u),e=e.add(t).trunc(n+5),t.abs().lte(c))break}return e.toFixed(n)};class f{constructor(t,n){this.cachedDigits=0,this.fn=t,this.max=n}get(t){if(t<=this.cachedDigits)return this.cache.trunc(t);const n=new i(this.fn(t)),r=Math.min(this.max,t);return this.cachedDigits!==r&&(this.cache=n.trunc(r),this.cachedDigits=r),n}}const g=(t,n)=>{let r=a(t);if(r.isOne())return new i(0).toFixed(n);if(r.lte(0n))throw new Error("Invalid parameter");let e=0;for(;r.sub(1n).abs().gt("0.1");)r=new i(c(r,n+10)),e++;const o=r.sub(1n).div(r.add(1n)),s=o.pow(2n).normalize();let u=o,m=1n,h=a(o);for(;;){let t=a(0);for(let r=0;r<4;r++){u=u.mul(s),m+=2n;const r=u.div(m);t=t.add(r).trunc(n+10)}if(t.isZero())break;h=h.add(t)}return h=h.mul(2n**BigInt(e+1)),h.toFixed(n)},w=(t,n,r)=>{if(!Number.isSafeInteger(t)||t<2)throw new Error("Invalid parameter for N");const e=g(n,r+10),o=g(t,r+10);return new i(e).div(o).toFixed(r)},b=new f((t=>g(2n,t)),200),E=(t,n)=>new i(g(t,n+10)).div(b.get(n+10)).toFixed(n),p=new f((t=>g(10n,t)),200),I=(t,n)=>new i(g(t,n+10)).div(p.get(n+10)).toFixed(n),v=new f((t=>{if(0===t)return"3";let n=1n,r=3n*10n**BigInt(t+20),e=r;for(;0n!==r;)r=r*n/(4n*(n+1n)),n+=2n,e+=r/n;return`3.${e.toString().slice(1,t+1)}`}),1e3),N=t=>0===t?"3":v.get(t).toFixed(t),T=(n,r)=>{const e=r+10,{x:o,quadrant:s}=((t,n)=>{const r=new i(N(n)),e=r.mul(2n);(t=t.mod(e)).gt(r)?t=t.sub(e):t.lt(r.neg())&&(t=t.add(e));const o=r.div(2n),s=t.div(o);let a=0;return s.gte(o)?(a=2,t=r.sub(t)):s.gte(0n)?a=1:s.gte(o.neg())?(a=4,t=t.neg()):(a=3,t=r.sub(t.neg())),{quadrant:a,x:t}})(a(n),e),u=o.round(e,t.NEAREST_AWAY_FROM_ZERO).pow(2n).normalize();let m=u,c=2n,h=a(1n).sub(m.div(c).trunc(e)),d=3n;const l=a(1n).div(10n**BigInt(e));let f=1;for(;;){c*=d*(d+1n),d+=2n;const t=d*(d+1n);d+=2n,m=m.mul(u),c*=t;let i=m.mul(t);m=m.mul(u),i=i.sub(m);const o=i.div(c).trunc(e);if(f++,h=h.add(o),o.lt(l)){const t=h.trunc(r),i=o.add(l.mul(f)),s=h.add(i).trunc(r);if(t.eq(s))break;return a(T(n,e+50)).toFixed(r)}}return(1===s||4===s?h:h.neg()).round(r+3,t.TO_ZERO).toFixed(r)},O=(t,n)=>{const r=new i(N(n+10)),e=a(t);return T(r.div(2n).sub(e),n)},P=(t,n)=>{if(a(t).isZero())return"0";return a(O(t,n+10)).div(T(t,n+10)).toFixed(n)},F=(t,n)=>{let r=a(t);if(r.isZero())return"0";if(r.abs().isOne())return a(N(n)).div(4*r.sign()).toFixed(n);let e=0;for(;r.abs().gt("0.42");){const t=a(c(r.pow(2n).add(1n),n+10));r=r.div(t.add(1n)),e++}const i=r.pow(2).normalize(),o=i.pow(2).normalize();let s=3n,u=r.sub(r.mul(i).div(s)),m=r.mul(o);const h=a(1n).div(10n**BigInt(n+10));for(;;){s+=2n;const t=s+2n,r=m.mul(i.mul(-s).add(t)).div(s*t);if(s=t,m=m.mul(o),u=u.add(r).trunc(n+10),r.abs().lt(h))break}return u=u.mul(2n**BigInt(e)),u.toFixed(n)},S=(t,n)=>{const r=a(t);if(r.isZero())return"0";if(r.abs().isOne())return a(N(n)).mul(r.sign()).div(2n).toFixed(n);if(r.abs().eq("1/2"))return a(N(n)).mul(r.sign()).div(6n).toFixed(n);if(r.gt(1n)||r.lt(-1n))throw new Error("Out of range");const e=a(c(r.pow(2n).neg().add(1),n+10));return a(F(r.div(e.add(1n)),n+10)).mul(2).toFixed(n)},_=(t,n)=>{const r=a(t);if(r.isZero())return a(N(n)).div(2n).toFixed(n);if(r.isOne())return"0";if(r.abs().isOne())return N(n);if(r.abs().eq("1/2")){const t=a(N(n)).div(3n);return-1===r.sign()?t.mul(2n).toFixed(n):t.toFixed(n)}if(r.gt(1n)||r.lt(-1n))throw new Error("Out of range");return a(N(n+10)).div(2n).sub(S(r,n+10)).toFixed(n)},R=(t,n)=>{const r=a(t),e=r.pow(2n).normalize();let i=r,o=1n,s=r.trunc(n+5),u=2n;const m=a(1n).div(10n**BigInt(n+5));for(;;){i=i.mul(e),o*=u*(u+1n),u+=2n;const t=i.div(o);if(s=s.add(t).trunc(n+5),t.abs().lt(m))break}return s.toFixed(n)},x=(t,n)=>{const r=a(t).pow(2n).normalize();let e=r,i=2n,o=e.div(i).add(1n).trunc(n+5),s=3n;const u=a(1n).div(10n**BigInt(n+5));for(;;){e=e.mul(r),i*=s*(s+1n),s+=2n;const t=e.div(i);if(o=o.add(t).trunc(n+5),t.abs().lt(u))break}return o.toFixed(n)};export{a as ExactNumber,n as ModType,N as PI,t as RoundingMode,_ as acos,S as asin,F as atan,h as cbrt,T as cos,x as cosh,l as exp,g as log,I as log10,E as log2,w as logn,m as nthroot,d as pow,O as sin,R as sinh,c as sqrt,P as tan,r as trimTrailingZeros}; |
/*! | ||
* exactnumber v0.8.0 (https://www.npmjs.com/package/exactnumber) | ||
* exactnumber v0.8.1 (https://www.npmjs.com/package/exactnumber) | ||
* (c) Dani Biro | ||
@@ -245,20 +245,19 @@ * @license MIT | ||
const exp = 10n ** BigInt(Math.abs(shift)); | ||
const numberToZero = shift > 0 ? this.number / exp : this.number * exp; | ||
const outDigits = shift > 0 ? this.number / exp : this.number * exp; | ||
if (roundingMode === exports.RoundingMode.TO_ZERO) { | ||
return new FixedNumber(numberToZero, decimals); | ||
return new FixedNumber(outDigits, decimals); | ||
} | ||
const expectedFracDecimals = shift > 0 ? Math.abs(shift) : decimals; | ||
const fracPart = shift > 0 ? this.number % exp : numberToZero % 10n ** BigInt(decimals); | ||
if (fracPart === 0n) | ||
return new FixedNumber(numberToZero, decimals); | ||
const extraDigits = shift > 0 ? this.number % exp : 0n; | ||
if (extraDigits === 0n) | ||
return new FixedNumber(outDigits, decimals); | ||
if (roundingMode === exports.RoundingMode.AWAY_FROM_ZERO) { | ||
const res = this.number < 0n ? numberToZero - 1n : numberToZero + 1n; | ||
const res = this.number < 0n ? outDigits - 1n : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
} | ||
if (roundingMode === exports.RoundingMode.TO_POSITIVE) { | ||
const res = this.number < 0n ? numberToZero : numberToZero + 1n; | ||
const res = this.number < 0n ? outDigits : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
} | ||
if (roundingMode === exports.RoundingMode.TO_NEGATIVE) { | ||
const res = this.number >= 0n ? numberToZero : numberToZero - 1n; | ||
const res = this.number >= 0n ? outDigits : outDigits - 1n; | ||
return new FixedNumber(res, decimals); | ||
@@ -276,10 +275,13 @@ } | ||
} | ||
let fracStr = (fracPart < 0n ? -fracPart : fracPart).toString(); | ||
if (fracStr.length < expectedFracDecimals) { | ||
fracStr = '0'.repeat(expectedFracDecimals - fracStr.length) + fracStr; | ||
let extraDigitsStr = (extraDigits < 0n ? -extraDigits : extraDigits).toString(); | ||
// '00123' extra part will appear in extraDigitsStr as '123' | ||
// -> in this case we can exclude the tie case by setting the extra part to zero | ||
const expectedFracDecimals = shift > 0 ? shift : 0; | ||
if (extraDigitsStr.length < expectedFracDecimals) { | ||
extraDigitsStr = '0'; | ||
} | ||
let isTie = fracStr[0] === '5'; | ||
let isTie = extraDigitsStr[0] === '5'; | ||
if (isTie) { | ||
for (let i = 1; i < fracStr.length; i++) { | ||
if (fracStr[i] !== '0') { | ||
for (let i = 1; i < extraDigitsStr.length; i++) { | ||
if (extraDigitsStr[i] !== '0') { | ||
isTie = false; | ||
@@ -292,28 +294,28 @@ break; | ||
if (roundingMode === exports.RoundingMode.NEAREST_TO_ZERO) { | ||
return new FixedNumber(numberToZero, decimals); | ||
return new FixedNumber(outDigits, decimals); | ||
} | ||
if (roundingMode === exports.RoundingMode.NEAREST_AWAY_FROM_ZERO) { | ||
const res = this.number < 0n ? numberToZero - 1n : numberToZero + 1n; | ||
const res = this.number < 0n ? outDigits - 1n : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
} | ||
if (roundingMode === undefined || roundingMode === exports.RoundingMode.NEAREST_TO_POSITIVE) { | ||
const res = this.number < 0n ? numberToZero : numberToZero + 1n; | ||
const res = this.number < 0n ? outDigits : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
} | ||
if (roundingMode === exports.RoundingMode.NEAREST_TO_NEGATIVE) { | ||
const res = this.number >= 0n ? numberToZero : numberToZero - 1n; | ||
const res = this.number >= 0n ? outDigits : outDigits - 1n; | ||
return new FixedNumber(res, decimals); | ||
} | ||
if (roundingMode === exports.RoundingMode.NEAREST_TO_EVEN) { | ||
if (numberToZero % 2n === 0n) { | ||
return new FixedNumber(numberToZero, decimals); | ||
if (outDigits % 2n === 0n) { | ||
return new FixedNumber(outDigits, decimals); | ||
} | ||
const res = numberToZero < 0n ? numberToZero - 1n : numberToZero + 1n; | ||
const res = outDigits < 0n ? outDigits - 1n : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
} | ||
} | ||
if (Number(fracStr[0]) < 5) { | ||
return new FixedNumber(numberToZero, decimals); | ||
if (Number(extraDigitsStr[0]) < 5) { | ||
return new FixedNumber(outDigits, decimals); | ||
} | ||
const res = this.number < 0 ? numberToZero - 1n : numberToZero + 1n; | ||
const res = this.number < 0 ? outDigits - 1n : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
@@ -320,0 +322,0 @@ } |
/*! | ||
* exactnumber v0.8.0 (https://www.npmjs.com/package/exactnumber) | ||
* exactnumber v0.8.1 (https://www.npmjs.com/package/exactnumber) | ||
* (c) Dani Biro | ||
@@ -7,2 +7,2 @@ * @license MIT | ||
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((n="undefined"!=typeof globalThis?globalThis:n||self).exactnumber={})}(this,(function(n){"use strict";var t,e;n.RoundingMode=void 0,(t=n.RoundingMode||(n.RoundingMode={})).NEAREST_TO_POSITIVE="NP",t.NEAREST_TO_NEGATIVE="NN",t.NEAREST_TO_EVEN="NE",t.NEAREST_TO_ZERO="NZ",t.NEAREST_AWAY_FROM_ZERO="NA",t.TO_POSITIVE="P",t.TO_NEGATIVE="N",t.TO_ZERO="Z",t.AWAY_FROM_ZERO="A",n.ModType=void 0,(e=n.ModType||(n.ModType={})).TRUNCATED="T",e.FLOORED="F",e.EUCLIDEAN="E";const r=n=>{let t=n.length;for(;t>0&&["0","."].includes(n.charAt(t-1));)t--;return t!==n.length?n.slice(0,t):n},i=(n,t,e)=>{let i=n.toString();if(0===t)return i;const o=i.startsWith("-");if(o&&(i=i.slice(1)),t>=i.length&&(i="0".repeat(t-i.length+1)+i),t>0){const n=i.slice(0,-t);let o=i.slice(-t);e&&(o=r(o)),i=o.length?`${n}.${o}`:n}return o?`-${i}`:i};class o{constructor(n,t=0){if(this.type="fixed","bigint"==typeof n)this.number=n,this.decimalPos=t;else{const t=this.parseConstructorParameter(n);this.number=t.number,this.decimalPos=t.decimalPos}}parseConstructorParameter(n){if(n instanceof o)return{number:n.number,decimalPos:n.decimalPos};if(n instanceof s){if(!n.isInteger())throw new Error("Cannot create FixedNumber from non-integer Fraction");return{number:n.trunc().number,decimalPos:0}}if("number"==typeof n){if(!Number.isSafeInteger(n))throw new Error("The specified number cannot be exactly represented as an integer. Please provide a string instead.");return{number:BigInt(n),decimalPos:0}}if("string"==typeof n){if(0===(n=n.trim()).length)throw new Error("Empty string is not allowed");const t=n.match(/^(-?[0-9]*)(?:\.([0-9]*))?(?:[eE]([+-]?[0-9]+))?$/);if(!t)throw new Error(`Cannot parse number "${n}"`);let e=0,r=t[1]??"0";if(void 0!==t[2]&&(r+=t[2],e+=t[2].length),void 0!==t[3]){const n=Number(t[3]);n>0?r+="0".repeat(n):e-=n}return{number:BigInt(r),decimalPos:e}}throw new Error("Unsupported parameter!")}scaleNumber(n,t){const e=Math.max(this.decimalPos,t);return{a:e===this.decimalPos?this.number:this.number*10n**BigInt(e-this.decimalPos),b:e===t?n:n*10n**BigInt(e-t),decimalPos:e}}add(n){const t=a(n);if(t instanceof s)return t.add(this);const e=t,{a:r,b:i,decimalPos:u}=this.scaleNumber(e.number,e.decimalPos);return new o(r+i,u)}sub(n){const t=a(n);return this.add(t.neg())}mul(n){const t=a(n);if(t instanceof s)return t.mul(this);const e=t;return new o(this.number*e.number,this.decimalPos+e.decimalPos)}pow(n){const t=a(n).toNumber();if(!Number.isSafeInteger(t)||t<0)throw new Error("Unsupported parameter");return new o(this.number**BigInt(t),this.decimalPos*t)}div(n){return this.convertToFraction().div(n)}divToInt(n){const t=a(n);if(t instanceof s)return this.convertToFraction().divToInt(t);const e=t,{a:r,b:i}=this.scaleNumber(e.number,e.decimalPos);return new o(r/i)}mod(t,e=n.ModType.TRUNCATED){const r=a(t);if(r instanceof s)return this.convertToFraction().mod(r);const i=r,{a:u,b:d,decimalPos:m}=this.scaleNumber(i.number,i.decimalPos),c=u%d,h=new o(c,m);if(e===n.ModType.TRUNCATED)return h;if(e===n.ModType.FLOORED)return Number(u<0)^Number(d<0)?h.add(d):h;if(e===n.ModType.EUCLIDEAN)return c<0?h.add(d<0?-d:d):h;throw new Error("Invalid ModType")}abs(){return new o(this.number<0?-this.number:this.number,this.decimalPos)}neg(){return this.mul(-1n)}inv(){return this.convertToFraction().inv()}floor(t){return 0===this.decimalPos?this:this.round(t,n.RoundingMode.TO_NEGATIVE)}ceil(t){return 0===this.decimalPos?this:this.round(t,n.RoundingMode.TO_POSITIVE)}trunc(t){return 0===this.decimalPos?this:this.round(t,n.RoundingMode.TO_ZERO)}round(t,e){if(t=void 0===t?0:t,!Number.isSafeInteger(t)||t<0)throw new Error("Invalid value for decimals");const r=this.decimalPos-t,i=10n**BigInt(Math.abs(r)),s=r>0?this.number/i:this.number*i;if(e===n.RoundingMode.TO_ZERO)return new o(s,t);const a=r>0?Math.abs(r):t,u=r>0?this.number%i:s%10n**BigInt(t);if(0n===u)return new o(s,t);if(e===n.RoundingMode.AWAY_FROM_ZERO){const n=this.number<0n?s-1n:s+1n;return new o(n,t)}if(e===n.RoundingMode.TO_POSITIVE){const n=this.number<0n?s:s+1n;return new o(n,t)}if(e===n.RoundingMode.TO_NEGATIVE){const n=this.number>=0n?s:s-1n;return new o(n,t)}if(![void 0,n.RoundingMode.NEAREST_TO_ZERO,n.RoundingMode.NEAREST_AWAY_FROM_ZERO,n.RoundingMode.NEAREST_TO_POSITIVE,n.RoundingMode.NEAREST_TO_NEGATIVE,n.RoundingMode.NEAREST_TO_EVEN].includes(e))throw new Error("Invalid rounding mode. Use the predefined values from the RoundingMode enum.");let d=(u<0n?-u:u).toString();d.length<a&&(d="0".repeat(a-d.length)+d);let m="5"===d[0];if(m)for(let n=1;n<d.length;n++)if("0"!==d[n]){m=!1;break}if(m){if(e===n.RoundingMode.NEAREST_TO_ZERO)return new o(s,t);if(e===n.RoundingMode.NEAREST_AWAY_FROM_ZERO){const n=this.number<0n?s-1n:s+1n;return new o(n,t)}if(void 0===e||e===n.RoundingMode.NEAREST_TO_POSITIVE){const n=this.number<0n?s:s+1n;return new o(n,t)}if(e===n.RoundingMode.NEAREST_TO_NEGATIVE){const n=this.number>=0n?s:s-1n;return new o(n,t)}if(e===n.RoundingMode.NEAREST_TO_EVEN){if(s%2n===0n)return new o(s,t);return new o(s<0n?s-1n:s+1n,t)}}if(Number(d[0])<5)return new o(s,t);const c=this.number<0?s-1n:s+1n;return new o(c,t)}_incExponent(n){if(0===n)return this;let t=this.number,e=this.decimalPos;if(n<0)e-=n;else{const r=Math.min(n,this.decimalPos);e-=r;const i=n-r;i>0&&(t*=10n**BigInt(i))}return new o(t,e)}roundToDigits(n,t){if(!Number.isSafeInteger(n)||n<1)throw new Error("Invalid value for digits");const e=this.number<0n,r=e?-this.number:this.number,i=r.toString();let s=new o(r,i.length).round(n,t);const a=i.length-this.decimalPos;return s=s._incExponent(a),e?s.neg():s}intPart(){return this.trunc()}fracPart(){return this.sub(this.trunc())}sign(){return this.number<0n?-1:1}bitwiseAnd(n){if(n=u(n),!this.isInteger()||-1===this.sign()||!n.isInteger()||-1===n.sign())throw new Error("Only positive integers are supported");n instanceof s&&(n=n.trunc());const t=2n**24n;let e=this.normalize().number,r=n.trunc().normalize().number,i=0n,a=1n;for(;e>0&&r>0;){const n=BigInt.asUintN(24,e),o=BigInt.asUintN(24,r);i+=BigInt(Number(n)&Number(o))*a,a*=t,e/=t,r/=t}return new o(i)}bitwiseOr(n){if(n=u(n),!this.isInteger()||-1===this.sign()||!n.isInteger()||-1===n.sign())throw new Error("Only positive integers are supported");n instanceof s&&(n=n.trunc());const t=2n**24n;let e=this.normalize().number,r=n.trunc().normalize().number,i=0n,a=1n;for(;e>0||r>0;){const n=BigInt.asUintN(24,e),o=BigInt.asUintN(24,r);i+=BigInt(Number(n)|Number(o))*a,a*=t,e/=t,r/=t}return new o(i)}bitwiseXor(n){if(n=u(n),!this.isInteger()||-1===this.sign()||!n.isInteger()||-1===n.sign())throw new Error("Only positive integers are supported");n instanceof s&&(n=n.trunc());const t=2n**24n;let e=this.normalize().number,r=n.trunc().normalize().number,i=0n,a=1n;for(;e>0||r>0;){const n=BigInt.asUintN(24,e),o=BigInt.asUintN(24,r);i+=BigInt(Number(n)^Number(o))*a,a*=t,e/=t,r/=t}return new o(i)}shiftLeft(n){if(!this.isInteger()||-1===this.sign())throw new Error("Only positive integers are supported");if(!Number.isSafeInteger(n)||n<0)throw new Error("Invalid value for bitCount");const t=2n**BigInt(n);return this.mul(t)}shiftRight(n){if(!this.isInteger()||-1===this.sign())throw new Error("Only positive integers are supported");if(!Number.isSafeInteger(n)||n<0)throw new Error("Invalid value for bitCount");const t=2n**BigInt(n);return new o(this.normalize().number/t)}cmp(n){const t=a(n);if(t instanceof s)return-t.cmp(this);const e=t,{a:r,b:i}=this.scaleNumber(e.number,e.decimalPos);return r===i?0:r>i?1:-1}eq(n){return 0===this.cmp(n)}lt(n){return-1===this.cmp(n)}lte(n){return this.cmp(n)<=0}gt(n){return 1===this.cmp(n)}gte(n){return this.cmp(n)>=0}clamp(n,t){const e=u(n),r=u(t);if(e.gt(r))throw new Error("Min parameter has to be smaller than max");return this.lt(e)?e:this.gt(r)?r:this}isZero(){return 0n===this.number}isOne(){if(0===this.decimalPos)return 1n===this.number;const n=10n**BigInt(this.decimalPos),t=this.number/n;return 1n===t&&t*n===this.number}isInteger(){return 0===this.decimalPos||this.number%10n**BigInt(this.decimalPos)===0n}serialize(){return[this.number,this.decimalPos]}getFractionParts(n=!0){return this.convertToFraction().getFractionParts(n)}normalize(){if(0===this.decimalPos)return this;let n=this.decimalPos,t=this.number;for(;n>0&&t%10n===0n;)n--,t/=10n;return new o(t,n)}convertToFraction(){if(0===this.decimalPos)return new s(this.number,1n);const n=10n**BigInt(this.decimalPos);return new s(this.number,n)}toNumber(){return Number(this.toString())}toFixed(t,e=n.RoundingMode.TO_ZERO){if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid parameter");const r=this.round(t,e);return i(r.number,t,!1)}toExponential(t,e=n.RoundingMode.TO_ZERO){if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid parameter");const r=this.roundToDigits(t+1,e).normalize(),i=-1===r.sign(),o=r.abs(),s=o.number.toString(),a=s.length<=t?`${s}${"0".repeat(t-s.length+1)}`:s.slice(0,t+1),u=a.length>1?`${a.slice(0,1)}.${a.slice(1)}`:a,d=o.decimalPos,m=s.length-1-d;return`${i?"-":""}${u}e${m>=0?"+":""}${m}`}toBase(n,t){if(!Number.isSafeInteger(n)||n<2||n>16)throw new Error("Invalid radix");if(void 0!==t&&(!Number.isSafeInteger(t)||t<0))throw new Error("Invalid parameter");const e=this.normalize();if(0===e.decimalPos)return e.number.toString(n);const r=void 0===t?Number.MAX_SAFE_INTEGER:t;let i=e.intPart(),o=e.sub(i);const s=-1===e.sign();s&&(i=i.neg(),o=o.neg());const a=new Map;let u=[];for(;!o.isZero();){const t=o.mul(n),e=t.toString(),i=a.get(e);if(void 0!==i){u=[...u.slice(0,i-1),"(",...u.slice(i-1),")"];break}if(u.length===r)break;const s=Math.abs(t.intPart().toNumber());u.push(s.toString(n)),o=t.fracPart(),a.set(e,u.length)}return[s?"-":"",i.number.toString(n),u.length?".":"",...u].join("")}toFraction(){return this.convertToFraction().toFraction()}toString(n,t){if(void 0===n||10===n){const n=void 0!==t?this.trunc(t):this;return i(n.number,n.decimalPos,!0)}return this.toBase(n,t)}toPrecision(t,e=n.RoundingMode.TO_ZERO){if(!Number.isSafeInteger(t)||t<1)throw new Error("Invalid parameter");const r=this.roundToDigits(t,e);return i(r.number,r.decimalPos,!1)}valueOf(){throw new Error("Unsafe conversion to Number type! Use toNumber() instead.")}}class s{constructor(n,t){if(this.type="fraction","bigint"==typeof n&&"bigint"==typeof t)this.numerator=n,this.denominator=t;else{const e=this.parseParameter(n),r=this.parseParameter(t),i=e.div(r),s=i instanceof o?i.convertToFraction():i;this.numerator=s.numerator,this.denominator=s.denominator}if(0n===this.denominator)throw new Error("Division by zero")}parseRepeatingDecimal(n){if(!n.includes("("))return new o(n).convertToFraction();const t=(n=n.trim()).match(/^(-?[0-9]*)\.([0-9]+)?\(([0-9]+)\)(?:[eE]([+-]?[0-9]+))?$/);if(!t)throw new Error(`Cannot parse string "${n}"`);const e="-"===t[1]?"-0":t[1],r=t[2]??"",i=t[3],a=t[4],u=BigInt(e+r+i)-BigInt(e+r),d=BigInt("9".repeat(i.length)+"0".repeat(r.length)),m=new s(u,d);if(void 0!==a){const n=a.startsWith("-"),t=10n**BigInt(n?a.slice(1):a);return n?m.div(t).normalize():m.mul(t).normalize()}return m.normalize()}parseParameter(n){if(n instanceof s)return n;if(n instanceof o)return n.convertToFraction();if("number"==typeof n){if(!Number.isSafeInteger(n))throw new Error("Floating point values as numbers are unsafe. Please provide them as a string.");return new s(BigInt(n),1n)}if("bigint"==typeof n)return new s(n,1n);if("string"==typeof n){const t=n.split("/");if(t.length>2)throw new Error(`Cannot parse string '${n}'`);const e=this.parseRepeatingDecimal(t[0]),r=t[1]?this.parseRepeatingDecimal(t[1]):new s(1n,1n);return e.div(r).convertToFraction()}throw new Error("Unsupported parameter!")}add(n){const{numerator:t,denominator:e}=this.parseParameter(n);return this.denominator===e?new s(this.numerator+t,this.denominator):new s(this.numerator*e+t*this.denominator,e*this.denominator)}sub(n){const{numerator:t,denominator:e}=this.parseParameter(n);return this.add(new s(-t,e))}mul(n){const{numerator:t,denominator:e}=this.parseParameter(n);return new s(this.numerator*t,this.denominator*e)}div(n){const{numerator:t,denominator:e}=this.parseParameter(n);return this.mul(new s(e,t))}divToInt(n){return this.div(n).trunc()}mod(t,e=n.ModType.TRUNCATED){const r=this.parseParameter(t),i=r.denominator*this.numerator%(r.numerator*this.denominator),o=this.denominator*r.denominator,a=new s(i,o);if(e===n.ModType.TRUNCATED)return a;if(e===n.ModType.FLOORED)return Number(-1===this.sign())^Number(-1===r.sign())?a.add(r):a;if(e===n.ModType.EUCLIDEAN)return a.sign()<0?a.add(r.sign()<0?r.neg():r):a;throw new Error("Invalid ModType")}pow(n){const t=this.parseParameter(n);if(!t.isInteger()||-1===t.sign())throw new Error("Unsupported parameter");const e=t.numerator/t.denominator;return new s(this.numerator**e,this.denominator**e)}inv(){return new s(this.denominator,this.numerator)}floor(t){return 1n===this.denominator?new o(this.numerator):this.round(t,n.RoundingMode.TO_NEGATIVE)}ceil(t){return 1n===this.denominator?new o(this.numerator):this.round(t,n.RoundingMode.TO_POSITIVE)}trunc(t){return 1n===this.denominator?new o(this.numerator):this.round(t,n.RoundingMode.TO_ZERO)}round(n,t){if(n=void 0===n?0:n,!Number.isSafeInteger(n)||n<0)throw new Error("Invalid value for decimals");const e=this.toFixedNumber(n+1);if(this.sub(e).isZero())return e.round(n,t);return new o(`${e.toFixed(n+1)}1`).round(n,t)}roundToDigits(n,t){if(!Number.isSafeInteger(n)||n<1)throw new Error("Invalid value for digits");if(this.isZero())return new o(0n);let e=this.abs(),r=0;for(;e.gte(1n);)e=e.div(10n),r++;const i=new s(1n,10n);for(;e.lt(i);)e=e.mul(10n),r--;let a=e.round(n,t);return a=a._incExponent(r),-1===this.sign()?a.neg():a}gcd(n,t){let e=n<0?-n:n,r=t<0?-t:t;if(r>e){const n=e;e=r,r=n}for(;;){if(0n===r)return e;if(e%=r,0n===e)return r;r%=e}}lcm(n,t){return n*t/this.gcd(n,t)}normalize(){let{numerator:n,denominator:t}=this;const e=this.gcd(n,t);return e>1n&&(n/=e,t/=e),t<0n&&(n=-n,t=-t),new s(n,t)}getFractionParts(n=!0){const t=n?this.normalize():this;return{numerator:new o(t.numerator),denominator:new o(t.denominator)}}sign(){return(this.numerator<0n?-1:1)*(this.denominator<0n?-1:1)}abs(){return new s(this.numerator<0n?-this.numerator:this.numerator,this.denominator<0n?-this.denominator:this.denominator)}neg(){return this.mul(-1n)}intPart(){return this.trunc()}fracPart(){return this.sub(this.trunc())}cmp(n){const t=this.parseParameter(n),e=this.denominator===t.denominator,r=e?this.numerator:this.numerator*t.denominator,i=e?t.numerator:t.numerator*this.denominator;return r===i?0:r>i?1:-1}eq(n){return 0===this.cmp(n)}lt(n){return-1===this.cmp(n)}lte(n){return this.cmp(n)<=0}gt(n){return 1===this.cmp(n)}gte(n){return this.cmp(n)>=0}clamp(n,t){const e=u(n),r=u(t);if(e.gt(r))throw new Error("Min parameter has to be smaller than max");return this.lt(e)?e:this.gt(r)?r:this}isZero(){return 0n===this.numerator}isOne(){return this.numerator===this.denominator}isInteger(){return this.numerator%this.denominator===0n}serialize(){return[this.numerator,this.denominator]}toNumber(){return Number(this.numerator)/Number(this.denominator)}convertToFraction(){return this}getNumberForBitwiseOp(){if(!this.isInteger()||-1===this.sign())throw new Error("Only positive integers are supported");return this.intPart()}bitwiseAnd(n){return this.getNumberForBitwiseOp().bitwiseAnd(n)}bitwiseOr(n){return this.getNumberForBitwiseOp().bitwiseOr(n)}bitwiseXor(n){return this.getNumberForBitwiseOp().bitwiseXor(n)}shiftLeft(n){return this.getNumberForBitwiseOp().shiftLeft(n)}shiftRight(n){return this.getNumberForBitwiseOp().shiftRight(n)}getDecimalFormat(n){n=void 0===n?Number.MAX_SAFE_INTEGER:n;let t=this.denominator<0?-this.denominator:this.denominator,e=0;for(;t%2n===0n;)t/=2n,e++;let r=0;for(;t%5n===0n;)t/=5n,r++;const i=Math.max(e,r);if(1n===t)return{cycleLen:0,cycleStart:i};const o=Math.max(1,n-i);let s=10n%t,a=1;for(;1n!==s;){if(a===o)return{cycleLen:null,cycleStart:i};s=10n*s%t,a++}return{cycleLen:a,cycleStart:i}}toFixed(t,e=n.RoundingMode.TO_ZERO){if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid parameter");const[r,o]=this.round(t,e).serialize();return i(r,o,!1)}toRepeatingParts(n){if(this.isZero())return["0","",""];const{cycleLen:t,cycleStart:e}=this.normalize().getDecimalFormat(n);if(null===t||0===t){const t=n??e,i=this.toFixed(t),o=r(i).split(".");return[o[0],o[1]??"",""]}const i=e+t,o=this.toFixed(i).split(".");return[o[0],o[1].slice(0,e),o[1].slice(e)]}toRepeatingDigits(n){const t=this.toRepeatingParts(n);let e=t[0];return(t[1]||t[2])&&(e+=`.${t[1]}`),t[2]&&(e+=`(${t[2]})`),e}toExponential(t,e=n.RoundingMode.TO_ZERO){if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid parameters");return this.toFixedNumber(t).toExponential(t,e)}toFraction(){const{numerator:n,denominator:t}=this.normalize();return`${n.toString()}/${t.toString()}`}toFixedNumber(n){const t=this.numerator*10n**BigInt(n);return new o(t/this.denominator,n)}toBase(n,t){if(!Number.isSafeInteger(n)||n<2||n>16)throw new Error("Invalid radix");if(void 0!==t&&(!Number.isSafeInteger(t)||t<0))throw new Error("Invalid parameter");if(10===n)return void 0===t?this.toRepeatingDigits(t):r(this.toFixed(t));const e=this.normalize(),i=void 0===t?Number.MAX_SAFE_INTEGER:t+1;let o=e.intPart(),s=e.sub(o);const a=-1===e.sign();a&&(o=o.neg(),s=s.neg());const u=new Map;let d=[];for(;!s.isZero()&&d.length!==i;){const t=s.mul(n),e=t.normalize().toFraction(),r=u.get(e);if(void 0!==r){d=[...d.slice(0,r-1),"(",...d.slice(r-1),")"];break}const i=Math.abs(t.intPart().toNumber());d.push(i.toString(n)),s=t.fracPart(),u.set(e,d.length)}return d.length===i&&d.pop(),[a?"-":"",o.toString(n),d.length?".":"",...d].join("")}toString(n,t){return void 0===n||10===n?this.toRepeatingDigits(t):this.toBase(n,t)}toPrecision(t,e=n.RoundingMode.TO_ZERO){if(!Number.isSafeInteger(t)||t<1)throw new Error("Invalid parameter");const[r,o]=this.roundToDigits(t,e).serialize();return i(r,o,!1)}valueOf(){throw new Error("Unsafe conversion to Number type! Use toNumber() instead.")}}function a(n){if(n instanceof o||n instanceof s)return n;if("bigint"==typeof n)return new o(n);if("number"==typeof n){if(!Number.isSafeInteger(n))throw new Error("Floating point values as numbers are unsafe. Please provide them as a string.");return new o(n)}if("string"==typeof n)return n.includes("/")||n.includes("(")?new s(n,1n):new o(n);throw new Error("Unsupported parameter type")}const u=(n,t)=>{if(void 0===n)throw new Error("First parameter cannot be undefined");const e=a(n);if(void 0===t)return e;const r=a(t);return new s(e,1n).div(new s(r,1n))};u.min=(...n)=>{if(0===n.length)throw new Error("Got empty array");let t=u(n[0]);for(let e=1;e<n.length;e++){const r=u(n[e]);r.lt(t)&&(t=r)}return t},u.max=(...n)=>{if(0===n.length)throw new Error("Got empty array");let t=u(n[0]);for(let e=1;e<n.length;e++){const r=u(n[e]);r.gt(t)&&(t=r)}return t};const d=(n,t)=>{let e=0n;for(let r=0;r<n.length;r++){const i=n.charAt(r),o=parseInt(i,t);if(Number.isNaN(o))throw new Error(`Invalid digit "${i}"`);e*=BigInt(t),e+=BigInt(o)}return e};u.fromBase=(n,t)=>{if("string"!=typeof n)throw new Error("First parameter must be string");if(!Number.isSafeInteger(t)||t<2||t>16)throw new Error("Invalid radix");if(10===t)return u(n);if(0===(n=n.trim()).length)throw new Error("Empty string is not allowed");const e=n.startsWith("-");e&&(n=n.slice(1));const r=n.match(/^([0-9a-f]*)(?:\.([0-9a-f]*)(?:\(([0-9a-f]+)\))?)?$/i);if(!r)throw new Error(`Cannot parse number "${n}"`);const i=r[1]??"",o=r[2]??"",a=r[3]??"";if(a.length>0){const n=d([i,o,a].join(""),t)-d([i,o].join(""),t),r=d((t-1).toString(t).repeat(a.length)+"0".repeat(o.length),t),u=new s(n,r).normalize();return e?u.neg():u}const m=d(i,t),c=d(o,t),h=new s(c,BigInt(t)**BigInt(o.length)),l=new s(m,1n).add(h).normalize();return e?l.neg():l};const m=(n,t,e)=>{if(!Number.isSafeInteger(n))throw new Error("Integer is expected for N");if(n<0)throw new Error("Negative N is not supported");if(0===n)throw new Error("N cannot be zero");if(1===n)return u(t).toFixed(e);const r=u(t);if(n%2==0&&-1===r.sign())throw new Error("Complex numbers are not supported");if(r.isZero())return new o(0n).toFixed(e);if(r.isOne())return new o(1n).toFixed(e);const i=new s(n-1,n),a=new s(r,n),d=((n,t)=>{const e=t<0;e&&(t=-t);let r=t**(1/n);return e&&(r=-r),r.toString()})(n,r.toNumber());let m=new o(d),c=m.trunc(e);for(;;){m=i.mul(m).add(a.mul(m.inv().pow(n-1)));const t=m.trunc(e);if(m.isZero()||c.eq(t))break;c=t}return m.toFixed(e)},c=(n,t)=>m(2,n,t);class h{constructor(n,t){this.cachedDigits=0,this.fn=n,this.max=t}get(n){if(n<=this.cachedDigits)return this.cache.trunc(n);const t=new o(this.fn(n)),e=Math.min(this.max,n);return this.cachedDigits!==e&&(this.cache=t.trunc(e),this.cachedDigits=e),t}}const l=(n,t)=>{let e=u(n);if(e.isOne())return new o(0).toFixed(t);if(e.lte(0n))throw new Error("Invalid parameter");let r=0;for(;e.sub(1n).abs().gt("0.1");)e=new o(c(e,t+10)),r++;const i=e.sub(1n).div(e.add(1n)),s=i.pow(2n).normalize();let a=i,d=1n,m=u(i);for(;;){let n=u(0);for(let e=0;e<4;e++){a=a.mul(s),d+=2n;const e=a.div(d);n=n.add(e).trunc(t+10)}if(n.isZero())break;m=m.add(n)}return m=m.mul(2n**BigInt(r+1)),m.toFixed(t)},g=new h((n=>l(2n,n)),200),f=new h((n=>l(10n,n)),200),w=new h((n=>{if(0===n)return"3";let t=1n,e=3n*10n**BigInt(n+20),r=e;for(;0n!==e;)e=e*t/(4n*(t+1n)),t+=2n,r+=e/t;return`3.${r.toString().slice(1,n+1)}`}),1e3),b=n=>0===n?"3":w.get(n).toFixed(n),p=(t,e)=>{const r=e+10,{x:i,quadrant:s}=((n,t)=>{const e=new o(b(t)),r=e.mul(2n);(n=n.mod(r)).gt(e)?n=n.sub(r):n.lt(e.neg())&&(n=n.add(r));const i=e.div(2n),s=n.div(i);let a=0;return s.gte(i)?(a=2,n=e.sub(n)):s.gte(0n)?a=1:s.gte(i.neg())?(a=4,n=n.neg()):(a=3,n=e.sub(n.neg())),{quadrant:a,x:n}})(u(t),r),a=i.round(r,n.RoundingMode.NEAREST_AWAY_FROM_ZERO).pow(2n).normalize();let d=a,m=2n,c=u(1n).sub(d.div(m).trunc(r)),h=3n;const l=u(1n).div(10n**BigInt(r));let g=1;for(;;){m*=h*(h+1n),h+=2n;const n=h*(h+1n);h+=2n,d=d.mul(a),m*=n;let i=d.mul(n);d=d.mul(a),i=i.sub(d);const o=i.div(m).trunc(r);if(g++,c=c.add(o),o.lt(l)){const n=c.trunc(e),i=o.add(l.mul(g)),s=c.add(i).trunc(e);if(n.eq(s))break;return u(p(t,r+50)).toFixed(e)}}return(1===s||4===s?c:c.neg()).round(e+3,n.RoundingMode.TO_ZERO).toFixed(e)},E=(n,t)=>{const e=new o(b(t+10)),r=u(n);return p(e.div(2n).sub(r),t)},I=(n,t)=>{let e=u(n);if(e.isZero())return"0";if(e.abs().isOne())return u(b(t)).div(4*e.sign()).toFixed(t);let r=0;for(;e.abs().gt("0.42");){const n=u(c(e.pow(2n).add(1n),t+10));e=e.div(n.add(1n)),r++}const i=e.pow(2).normalize(),o=i.pow(2).normalize();let s=3n,a=e.sub(e.mul(i).div(s)),d=e.mul(o);const m=u(1n).div(10n**BigInt(t+10));for(;;){s+=2n;const n=s+2n,e=d.mul(i.mul(-s).add(n)).div(s*n);if(s=n,d=d.mul(o),a=a.add(e).trunc(t+10),e.abs().lt(m))break}return a=a.mul(2n**BigInt(r)),a.toFixed(t)},v=(n,t)=>{const e=u(n);if(e.isZero())return"0";if(e.abs().isOne())return u(b(t)).mul(e.sign()).div(2n).toFixed(t);if(e.abs().eq("1/2"))return u(b(t)).mul(e.sign()).div(6n).toFixed(t);if(e.gt(1n)||e.lt(-1n))throw new Error("Out of range");const r=u(c(e.pow(2n).neg().add(1),t+10));return u(I(e.div(r.add(1n)),t+10)).mul(2).toFixed(t)};n.ExactNumber=u,n.PI=b,n.acos=(n,t)=>{const e=u(n);if(e.isZero())return u(b(t)).div(2n).toFixed(t);if(e.isOne())return"0";if(e.abs().isOne())return b(t);if(e.abs().eq("1/2")){const n=u(b(t)).div(3n);return-1===e.sign()?n.mul(2n).toFixed(t):n.toFixed(t)}if(e.gt(1n)||e.lt(-1n))throw new Error("Out of range");return u(b(t+10)).div(2n).sub(v(e,t+10)).toFixed(t)},n.asin=v,n.atan=I,n.cbrt=(n,t)=>m(3,n,t),n.cos=p,n.cosh=(n,t)=>{const e=u(n).pow(2n).normalize();let r=e,i=2n,o=r.div(i).add(1n).trunc(t+5),s=3n;const a=u(1n).div(10n**BigInt(t+5));for(;;){r=r.mul(e),i*=s*(s+1n),s+=2n;const n=r.div(i);if(o=o.add(n).trunc(t+5),n.abs().lt(a))break}return o.toFixed(t)},n.exp=(n,t)=>{const e=u(n);let r=e.add(1n),i=6n,o=4n;const a=e.pow(2n);let d=a;const m=new s(1n,10n**BigInt(t+5));for(;;){const n=d.mul(e.add(o-1n)).div(i);if(i*=o*(o+1n),o+=2n,d=d.mul(a),r=r.add(n).trunc(t+5),n.abs().lte(m))break}return r.toFixed(t)},n.log=l,n.log10=(n,t)=>new o(l(n,t+10)).div(f.get(t+10)).toFixed(t),n.log2=(n,t)=>new o(l(n,t+10)).div(g.get(t+10)).toFixed(t),n.logn=(n,t,e)=>{if(!Number.isSafeInteger(n)||n<2)throw new Error("Invalid parameter for N");const r=l(t,e+10),i=l(n,e+10);return new o(r).div(i).toFixed(e)},n.nthroot=m,n.pow=(n,t,e)=>{const r=new s(n,1n),i=new s(t,1n).getFractionParts(!1);return m(i.denominator.toNumber(),r.pow(i.numerator),e)},n.sin=E,n.sinh=(n,t)=>{const e=u(n),r=e.pow(2n).normalize();let i=e,o=1n,s=e.trunc(t+5),a=2n;const d=u(1n).div(10n**BigInt(t+5));for(;;){i=i.mul(r),o*=a*(a+1n),a+=2n;const n=i.div(o);if(s=s.add(n).trunc(t+5),n.abs().lt(d))break}return s.toFixed(t)},n.sqrt=c,n.tan=(n,t)=>{if(u(n).isZero())return"0";return u(E(n,t+10)).div(p(n,t+10)).toFixed(t)},n.trimTrailingZeros=r,Object.defineProperty(n,"__esModule",{value:!0})})); | ||
!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((n="undefined"!=typeof globalThis?globalThis:n||self).exactnumber={})}(this,(function(n){"use strict";var t,e;n.RoundingMode=void 0,(t=n.RoundingMode||(n.RoundingMode={})).NEAREST_TO_POSITIVE="NP",t.NEAREST_TO_NEGATIVE="NN",t.NEAREST_TO_EVEN="NE",t.NEAREST_TO_ZERO="NZ",t.NEAREST_AWAY_FROM_ZERO="NA",t.TO_POSITIVE="P",t.TO_NEGATIVE="N",t.TO_ZERO="Z",t.AWAY_FROM_ZERO="A",n.ModType=void 0,(e=n.ModType||(n.ModType={})).TRUNCATED="T",e.FLOORED="F",e.EUCLIDEAN="E";const r=n=>{let t=n.length;for(;t>0&&["0","."].includes(n.charAt(t-1));)t--;return t!==n.length?n.slice(0,t):n},i=(n,t,e)=>{let i=n.toString();if(0===t)return i;const o=i.startsWith("-");if(o&&(i=i.slice(1)),t>=i.length&&(i="0".repeat(t-i.length+1)+i),t>0){const n=i.slice(0,-t);let o=i.slice(-t);e&&(o=r(o)),i=o.length?`${n}.${o}`:n}return o?`-${i}`:i};class o{constructor(n,t=0){if(this.type="fixed","bigint"==typeof n)this.number=n,this.decimalPos=t;else{const t=this.parseConstructorParameter(n);this.number=t.number,this.decimalPos=t.decimalPos}}parseConstructorParameter(n){if(n instanceof o)return{number:n.number,decimalPos:n.decimalPos};if(n instanceof s){if(!n.isInteger())throw new Error("Cannot create FixedNumber from non-integer Fraction");return{number:n.trunc().number,decimalPos:0}}if("number"==typeof n){if(!Number.isSafeInteger(n))throw new Error("The specified number cannot be exactly represented as an integer. Please provide a string instead.");return{number:BigInt(n),decimalPos:0}}if("string"==typeof n){if(0===(n=n.trim()).length)throw new Error("Empty string is not allowed");const t=n.match(/^(-?[0-9]*)(?:\.([0-9]*))?(?:[eE]([+-]?[0-9]+))?$/);if(!t)throw new Error(`Cannot parse number "${n}"`);let e=0,r=t[1]??"0";if(void 0!==t[2]&&(r+=t[2],e+=t[2].length),void 0!==t[3]){const n=Number(t[3]);n>0?r+="0".repeat(n):e-=n}return{number:BigInt(r),decimalPos:e}}throw new Error("Unsupported parameter!")}scaleNumber(n,t){const e=Math.max(this.decimalPos,t);return{a:e===this.decimalPos?this.number:this.number*10n**BigInt(e-this.decimalPos),b:e===t?n:n*10n**BigInt(e-t),decimalPos:e}}add(n){const t=a(n);if(t instanceof s)return t.add(this);const e=t,{a:r,b:i,decimalPos:u}=this.scaleNumber(e.number,e.decimalPos);return new o(r+i,u)}sub(n){const t=a(n);return this.add(t.neg())}mul(n){const t=a(n);if(t instanceof s)return t.mul(this);const e=t;return new o(this.number*e.number,this.decimalPos+e.decimalPos)}pow(n){const t=a(n).toNumber();if(!Number.isSafeInteger(t)||t<0)throw new Error("Unsupported parameter");return new o(this.number**BigInt(t),this.decimalPos*t)}div(n){return this.convertToFraction().div(n)}divToInt(n){const t=a(n);if(t instanceof s)return this.convertToFraction().divToInt(t);const e=t,{a:r,b:i}=this.scaleNumber(e.number,e.decimalPos);return new o(r/i)}mod(t,e=n.ModType.TRUNCATED){const r=a(t);if(r instanceof s)return this.convertToFraction().mod(r);const i=r,{a:u,b:d,decimalPos:m}=this.scaleNumber(i.number,i.decimalPos),c=u%d,h=new o(c,m);if(e===n.ModType.TRUNCATED)return h;if(e===n.ModType.FLOORED)return Number(u<0)^Number(d<0)?h.add(d):h;if(e===n.ModType.EUCLIDEAN)return c<0?h.add(d<0?-d:d):h;throw new Error("Invalid ModType")}abs(){return new o(this.number<0?-this.number:this.number,this.decimalPos)}neg(){return this.mul(-1n)}inv(){return this.convertToFraction().inv()}floor(t){return 0===this.decimalPos?this:this.round(t,n.RoundingMode.TO_NEGATIVE)}ceil(t){return 0===this.decimalPos?this:this.round(t,n.RoundingMode.TO_POSITIVE)}trunc(t){return 0===this.decimalPos?this:this.round(t,n.RoundingMode.TO_ZERO)}round(t,e){if(t=void 0===t?0:t,!Number.isSafeInteger(t)||t<0)throw new Error("Invalid value for decimals");const r=this.decimalPos-t,i=10n**BigInt(Math.abs(r)),s=r>0?this.number/i:this.number*i;if(e===n.RoundingMode.TO_ZERO)return new o(s,t);const a=r>0?this.number%i:0n;if(0n===a)return new o(s,t);if(e===n.RoundingMode.AWAY_FROM_ZERO){const n=this.number<0n?s-1n:s+1n;return new o(n,t)}if(e===n.RoundingMode.TO_POSITIVE){const n=this.number<0n?s:s+1n;return new o(n,t)}if(e===n.RoundingMode.TO_NEGATIVE){const n=this.number>=0n?s:s-1n;return new o(n,t)}if(![void 0,n.RoundingMode.NEAREST_TO_ZERO,n.RoundingMode.NEAREST_AWAY_FROM_ZERO,n.RoundingMode.NEAREST_TO_POSITIVE,n.RoundingMode.NEAREST_TO_NEGATIVE,n.RoundingMode.NEAREST_TO_EVEN].includes(e))throw new Error("Invalid rounding mode. Use the predefined values from the RoundingMode enum.");let u=(a<0n?-a:a).toString();const d=r>0?r:0;u.length<d&&(u="0");let m="5"===u[0];if(m)for(let n=1;n<u.length;n++)if("0"!==u[n]){m=!1;break}if(m){if(e===n.RoundingMode.NEAREST_TO_ZERO)return new o(s,t);if(e===n.RoundingMode.NEAREST_AWAY_FROM_ZERO){const n=this.number<0n?s-1n:s+1n;return new o(n,t)}if(void 0===e||e===n.RoundingMode.NEAREST_TO_POSITIVE){const n=this.number<0n?s:s+1n;return new o(n,t)}if(e===n.RoundingMode.NEAREST_TO_NEGATIVE){const n=this.number>=0n?s:s-1n;return new o(n,t)}if(e===n.RoundingMode.NEAREST_TO_EVEN){if(s%2n===0n)return new o(s,t);return new o(s<0n?s-1n:s+1n,t)}}if(Number(u[0])<5)return new o(s,t);const c=this.number<0?s-1n:s+1n;return new o(c,t)}_incExponent(n){if(0===n)return this;let t=this.number,e=this.decimalPos;if(n<0)e-=n;else{const r=Math.min(n,this.decimalPos);e-=r;const i=n-r;i>0&&(t*=10n**BigInt(i))}return new o(t,e)}roundToDigits(n,t){if(!Number.isSafeInteger(n)||n<1)throw new Error("Invalid value for digits");const e=this.number<0n,r=e?-this.number:this.number,i=r.toString();let s=new o(r,i.length).round(n,t);const a=i.length-this.decimalPos;return s=s._incExponent(a),e?s.neg():s}intPart(){return this.trunc()}fracPart(){return this.sub(this.trunc())}sign(){return this.number<0n?-1:1}bitwiseAnd(n){if(n=u(n),!this.isInteger()||-1===this.sign()||!n.isInteger()||-1===n.sign())throw new Error("Only positive integers are supported");n instanceof s&&(n=n.trunc());const t=2n**24n;let e=this.normalize().number,r=n.trunc().normalize().number,i=0n,a=1n;for(;e>0&&r>0;){const n=BigInt.asUintN(24,e),o=BigInt.asUintN(24,r);i+=BigInt(Number(n)&Number(o))*a,a*=t,e/=t,r/=t}return new o(i)}bitwiseOr(n){if(n=u(n),!this.isInteger()||-1===this.sign()||!n.isInteger()||-1===n.sign())throw new Error("Only positive integers are supported");n instanceof s&&(n=n.trunc());const t=2n**24n;let e=this.normalize().number,r=n.trunc().normalize().number,i=0n,a=1n;for(;e>0||r>0;){const n=BigInt.asUintN(24,e),o=BigInt.asUintN(24,r);i+=BigInt(Number(n)|Number(o))*a,a*=t,e/=t,r/=t}return new o(i)}bitwiseXor(n){if(n=u(n),!this.isInteger()||-1===this.sign()||!n.isInteger()||-1===n.sign())throw new Error("Only positive integers are supported");n instanceof s&&(n=n.trunc());const t=2n**24n;let e=this.normalize().number,r=n.trunc().normalize().number,i=0n,a=1n;for(;e>0||r>0;){const n=BigInt.asUintN(24,e),o=BigInt.asUintN(24,r);i+=BigInt(Number(n)^Number(o))*a,a*=t,e/=t,r/=t}return new o(i)}shiftLeft(n){if(!this.isInteger()||-1===this.sign())throw new Error("Only positive integers are supported");if(!Number.isSafeInteger(n)||n<0)throw new Error("Invalid value for bitCount");const t=2n**BigInt(n);return this.mul(t)}shiftRight(n){if(!this.isInteger()||-1===this.sign())throw new Error("Only positive integers are supported");if(!Number.isSafeInteger(n)||n<0)throw new Error("Invalid value for bitCount");const t=2n**BigInt(n);return new o(this.normalize().number/t)}cmp(n){const t=a(n);if(t instanceof s)return-t.cmp(this);const e=t,{a:r,b:i}=this.scaleNumber(e.number,e.decimalPos);return r===i?0:r>i?1:-1}eq(n){return 0===this.cmp(n)}lt(n){return-1===this.cmp(n)}lte(n){return this.cmp(n)<=0}gt(n){return 1===this.cmp(n)}gte(n){return this.cmp(n)>=0}clamp(n,t){const e=u(n),r=u(t);if(e.gt(r))throw new Error("Min parameter has to be smaller than max");return this.lt(e)?e:this.gt(r)?r:this}isZero(){return 0n===this.number}isOne(){if(0===this.decimalPos)return 1n===this.number;const n=10n**BigInt(this.decimalPos),t=this.number/n;return 1n===t&&t*n===this.number}isInteger(){return 0===this.decimalPos||this.number%10n**BigInt(this.decimalPos)===0n}serialize(){return[this.number,this.decimalPos]}getFractionParts(n=!0){return this.convertToFraction().getFractionParts(n)}normalize(){if(0===this.decimalPos)return this;let n=this.decimalPos,t=this.number;for(;n>0&&t%10n===0n;)n--,t/=10n;return new o(t,n)}convertToFraction(){if(0===this.decimalPos)return new s(this.number,1n);const n=10n**BigInt(this.decimalPos);return new s(this.number,n)}toNumber(){return Number(this.toString())}toFixed(t,e=n.RoundingMode.TO_ZERO){if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid parameter");const r=this.round(t,e);return i(r.number,t,!1)}toExponential(t,e=n.RoundingMode.TO_ZERO){if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid parameter");const r=this.roundToDigits(t+1,e).normalize(),i=-1===r.sign(),o=r.abs(),s=o.number.toString(),a=s.length<=t?`${s}${"0".repeat(t-s.length+1)}`:s.slice(0,t+1),u=a.length>1?`${a.slice(0,1)}.${a.slice(1)}`:a,d=o.decimalPos,m=s.length-1-d;return`${i?"-":""}${u}e${m>=0?"+":""}${m}`}toBase(n,t){if(!Number.isSafeInteger(n)||n<2||n>16)throw new Error("Invalid radix");if(void 0!==t&&(!Number.isSafeInteger(t)||t<0))throw new Error("Invalid parameter");const e=this.normalize();if(0===e.decimalPos)return e.number.toString(n);const r=void 0===t?Number.MAX_SAFE_INTEGER:t;let i=e.intPart(),o=e.sub(i);const s=-1===e.sign();s&&(i=i.neg(),o=o.neg());const a=new Map;let u=[];for(;!o.isZero();){const t=o.mul(n),e=t.toString(),i=a.get(e);if(void 0!==i){u=[...u.slice(0,i-1),"(",...u.slice(i-1),")"];break}if(u.length===r)break;const s=Math.abs(t.intPart().toNumber());u.push(s.toString(n)),o=t.fracPart(),a.set(e,u.length)}return[s?"-":"",i.number.toString(n),u.length?".":"",...u].join("")}toFraction(){return this.convertToFraction().toFraction()}toString(n,t){if(void 0===n||10===n){const n=void 0!==t?this.trunc(t):this;return i(n.number,n.decimalPos,!0)}return this.toBase(n,t)}toPrecision(t,e=n.RoundingMode.TO_ZERO){if(!Number.isSafeInteger(t)||t<1)throw new Error("Invalid parameter");const r=this.roundToDigits(t,e);return i(r.number,r.decimalPos,!1)}valueOf(){throw new Error("Unsafe conversion to Number type! Use toNumber() instead.")}}class s{constructor(n,t){if(this.type="fraction","bigint"==typeof n&&"bigint"==typeof t)this.numerator=n,this.denominator=t;else{const e=this.parseParameter(n),r=this.parseParameter(t),i=e.div(r),s=i instanceof o?i.convertToFraction():i;this.numerator=s.numerator,this.denominator=s.denominator}if(0n===this.denominator)throw new Error("Division by zero")}parseRepeatingDecimal(n){if(!n.includes("("))return new o(n).convertToFraction();const t=(n=n.trim()).match(/^(-?[0-9]*)\.([0-9]+)?\(([0-9]+)\)(?:[eE]([+-]?[0-9]+))?$/);if(!t)throw new Error(`Cannot parse string "${n}"`);const e="-"===t[1]?"-0":t[1],r=t[2]??"",i=t[3],a=t[4],u=BigInt(e+r+i)-BigInt(e+r),d=BigInt("9".repeat(i.length)+"0".repeat(r.length)),m=new s(u,d);if(void 0!==a){const n=a.startsWith("-"),t=10n**BigInt(n?a.slice(1):a);return n?m.div(t).normalize():m.mul(t).normalize()}return m.normalize()}parseParameter(n){if(n instanceof s)return n;if(n instanceof o)return n.convertToFraction();if("number"==typeof n){if(!Number.isSafeInteger(n))throw new Error("Floating point values as numbers are unsafe. Please provide them as a string.");return new s(BigInt(n),1n)}if("bigint"==typeof n)return new s(n,1n);if("string"==typeof n){const t=n.split("/");if(t.length>2)throw new Error(`Cannot parse string '${n}'`);const e=this.parseRepeatingDecimal(t[0]),r=t[1]?this.parseRepeatingDecimal(t[1]):new s(1n,1n);return e.div(r).convertToFraction()}throw new Error("Unsupported parameter!")}add(n){const{numerator:t,denominator:e}=this.parseParameter(n);return this.denominator===e?new s(this.numerator+t,this.denominator):new s(this.numerator*e+t*this.denominator,e*this.denominator)}sub(n){const{numerator:t,denominator:e}=this.parseParameter(n);return this.add(new s(-t,e))}mul(n){const{numerator:t,denominator:e}=this.parseParameter(n);return new s(this.numerator*t,this.denominator*e)}div(n){const{numerator:t,denominator:e}=this.parseParameter(n);return this.mul(new s(e,t))}divToInt(n){return this.div(n).trunc()}mod(t,e=n.ModType.TRUNCATED){const r=this.parseParameter(t),i=r.denominator*this.numerator%(r.numerator*this.denominator),o=this.denominator*r.denominator,a=new s(i,o);if(e===n.ModType.TRUNCATED)return a;if(e===n.ModType.FLOORED)return Number(-1===this.sign())^Number(-1===r.sign())?a.add(r):a;if(e===n.ModType.EUCLIDEAN)return a.sign()<0?a.add(r.sign()<0?r.neg():r):a;throw new Error("Invalid ModType")}pow(n){const t=this.parseParameter(n);if(!t.isInteger()||-1===t.sign())throw new Error("Unsupported parameter");const e=t.numerator/t.denominator;return new s(this.numerator**e,this.denominator**e)}inv(){return new s(this.denominator,this.numerator)}floor(t){return 1n===this.denominator?new o(this.numerator):this.round(t,n.RoundingMode.TO_NEGATIVE)}ceil(t){return 1n===this.denominator?new o(this.numerator):this.round(t,n.RoundingMode.TO_POSITIVE)}trunc(t){return 1n===this.denominator?new o(this.numerator):this.round(t,n.RoundingMode.TO_ZERO)}round(n,t){if(n=void 0===n?0:n,!Number.isSafeInteger(n)||n<0)throw new Error("Invalid value for decimals");const e=this.toFixedNumber(n+1);if(this.sub(e).isZero())return e.round(n,t);return new o(`${e.toFixed(n+1)}1`).round(n,t)}roundToDigits(n,t){if(!Number.isSafeInteger(n)||n<1)throw new Error("Invalid value for digits");if(this.isZero())return new o(0n);let e=this.abs(),r=0;for(;e.gte(1n);)e=e.div(10n),r++;const i=new s(1n,10n);for(;e.lt(i);)e=e.mul(10n),r--;let a=e.round(n,t);return a=a._incExponent(r),-1===this.sign()?a.neg():a}gcd(n,t){let e=n<0?-n:n,r=t<0?-t:t;if(r>e){const n=e;e=r,r=n}for(;;){if(0n===r)return e;if(e%=r,0n===e)return r;r%=e}}lcm(n,t){return n*t/this.gcd(n,t)}normalize(){let{numerator:n,denominator:t}=this;const e=this.gcd(n,t);return e>1n&&(n/=e,t/=e),t<0n&&(n=-n,t=-t),new s(n,t)}getFractionParts(n=!0){const t=n?this.normalize():this;return{numerator:new o(t.numerator),denominator:new o(t.denominator)}}sign(){return(this.numerator<0n?-1:1)*(this.denominator<0n?-1:1)}abs(){return new s(this.numerator<0n?-this.numerator:this.numerator,this.denominator<0n?-this.denominator:this.denominator)}neg(){return this.mul(-1n)}intPart(){return this.trunc()}fracPart(){return this.sub(this.trunc())}cmp(n){const t=this.parseParameter(n),e=this.denominator===t.denominator,r=e?this.numerator:this.numerator*t.denominator,i=e?t.numerator:t.numerator*this.denominator;return r===i?0:r>i?1:-1}eq(n){return 0===this.cmp(n)}lt(n){return-1===this.cmp(n)}lte(n){return this.cmp(n)<=0}gt(n){return 1===this.cmp(n)}gte(n){return this.cmp(n)>=0}clamp(n,t){const e=u(n),r=u(t);if(e.gt(r))throw new Error("Min parameter has to be smaller than max");return this.lt(e)?e:this.gt(r)?r:this}isZero(){return 0n===this.numerator}isOne(){return this.numerator===this.denominator}isInteger(){return this.numerator%this.denominator===0n}serialize(){return[this.numerator,this.denominator]}toNumber(){return Number(this.numerator)/Number(this.denominator)}convertToFraction(){return this}getNumberForBitwiseOp(){if(!this.isInteger()||-1===this.sign())throw new Error("Only positive integers are supported");return this.intPart()}bitwiseAnd(n){return this.getNumberForBitwiseOp().bitwiseAnd(n)}bitwiseOr(n){return this.getNumberForBitwiseOp().bitwiseOr(n)}bitwiseXor(n){return this.getNumberForBitwiseOp().bitwiseXor(n)}shiftLeft(n){return this.getNumberForBitwiseOp().shiftLeft(n)}shiftRight(n){return this.getNumberForBitwiseOp().shiftRight(n)}getDecimalFormat(n){n=void 0===n?Number.MAX_SAFE_INTEGER:n;let t=this.denominator<0?-this.denominator:this.denominator,e=0;for(;t%2n===0n;)t/=2n,e++;let r=0;for(;t%5n===0n;)t/=5n,r++;const i=Math.max(e,r);if(1n===t)return{cycleLen:0,cycleStart:i};const o=Math.max(1,n-i);let s=10n%t,a=1;for(;1n!==s;){if(a===o)return{cycleLen:null,cycleStart:i};s=10n*s%t,a++}return{cycleLen:a,cycleStart:i}}toFixed(t,e=n.RoundingMode.TO_ZERO){if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid parameter");const[r,o]=this.round(t,e).serialize();return i(r,o,!1)}toRepeatingParts(n){if(this.isZero())return["0","",""];const{cycleLen:t,cycleStart:e}=this.normalize().getDecimalFormat(n);if(null===t||0===t){const t=n??e,i=this.toFixed(t),o=r(i).split(".");return[o[0],o[1]??"",""]}const i=e+t,o=this.toFixed(i).split(".");return[o[0],o[1].slice(0,e),o[1].slice(e)]}toRepeatingDigits(n){const t=this.toRepeatingParts(n);let e=t[0];return(t[1]||t[2])&&(e+=`.${t[1]}`),t[2]&&(e+=`(${t[2]})`),e}toExponential(t,e=n.RoundingMode.TO_ZERO){if(!Number.isSafeInteger(t)||t<0)throw new Error("Invalid parameters");return this.toFixedNumber(t).toExponential(t,e)}toFraction(){const{numerator:n,denominator:t}=this.normalize();return`${n.toString()}/${t.toString()}`}toFixedNumber(n){const t=this.numerator*10n**BigInt(n);return new o(t/this.denominator,n)}toBase(n,t){if(!Number.isSafeInteger(n)||n<2||n>16)throw new Error("Invalid radix");if(void 0!==t&&(!Number.isSafeInteger(t)||t<0))throw new Error("Invalid parameter");if(10===n)return void 0===t?this.toRepeatingDigits(t):r(this.toFixed(t));const e=this.normalize(),i=void 0===t?Number.MAX_SAFE_INTEGER:t+1;let o=e.intPart(),s=e.sub(o);const a=-1===e.sign();a&&(o=o.neg(),s=s.neg());const u=new Map;let d=[];for(;!s.isZero()&&d.length!==i;){const t=s.mul(n),e=t.normalize().toFraction(),r=u.get(e);if(void 0!==r){d=[...d.slice(0,r-1),"(",...d.slice(r-1),")"];break}const i=Math.abs(t.intPart().toNumber());d.push(i.toString(n)),s=t.fracPart(),u.set(e,d.length)}return d.length===i&&d.pop(),[a?"-":"",o.toString(n),d.length?".":"",...d].join("")}toString(n,t){return void 0===n||10===n?this.toRepeatingDigits(t):this.toBase(n,t)}toPrecision(t,e=n.RoundingMode.TO_ZERO){if(!Number.isSafeInteger(t)||t<1)throw new Error("Invalid parameter");const[r,o]=this.roundToDigits(t,e).serialize();return i(r,o,!1)}valueOf(){throw new Error("Unsafe conversion to Number type! Use toNumber() instead.")}}function a(n){if(n instanceof o||n instanceof s)return n;if("bigint"==typeof n)return new o(n);if("number"==typeof n){if(!Number.isSafeInteger(n))throw new Error("Floating point values as numbers are unsafe. Please provide them as a string.");return new o(n)}if("string"==typeof n)return n.includes("/")||n.includes("(")?new s(n,1n):new o(n);throw new Error("Unsupported parameter type")}const u=(n,t)=>{if(void 0===n)throw new Error("First parameter cannot be undefined");const e=a(n);if(void 0===t)return e;const r=a(t);return new s(e,1n).div(new s(r,1n))};u.min=(...n)=>{if(0===n.length)throw new Error("Got empty array");let t=u(n[0]);for(let e=1;e<n.length;e++){const r=u(n[e]);r.lt(t)&&(t=r)}return t},u.max=(...n)=>{if(0===n.length)throw new Error("Got empty array");let t=u(n[0]);for(let e=1;e<n.length;e++){const r=u(n[e]);r.gt(t)&&(t=r)}return t};const d=(n,t)=>{let e=0n;for(let r=0;r<n.length;r++){const i=n.charAt(r),o=parseInt(i,t);if(Number.isNaN(o))throw new Error(`Invalid digit "${i}"`);e*=BigInt(t),e+=BigInt(o)}return e};u.fromBase=(n,t)=>{if("string"!=typeof n)throw new Error("First parameter must be string");if(!Number.isSafeInteger(t)||t<2||t>16)throw new Error("Invalid radix");if(10===t)return u(n);if(0===(n=n.trim()).length)throw new Error("Empty string is not allowed");const e=n.startsWith("-");e&&(n=n.slice(1));const r=n.match(/^([0-9a-f]*)(?:\.([0-9a-f]*)(?:\(([0-9a-f]+)\))?)?$/i);if(!r)throw new Error(`Cannot parse number "${n}"`);const i=r[1]??"",o=r[2]??"",a=r[3]??"";if(a.length>0){const n=d([i,o,a].join(""),t)-d([i,o].join(""),t),r=d((t-1).toString(t).repeat(a.length)+"0".repeat(o.length),t),u=new s(n,r).normalize();return e?u.neg():u}const m=d(i,t),c=d(o,t),h=new s(c,BigInt(t)**BigInt(o.length)),l=new s(m,1n).add(h).normalize();return e?l.neg():l};const m=(n,t,e)=>{if(!Number.isSafeInteger(n))throw new Error("Integer is expected for N");if(n<0)throw new Error("Negative N is not supported");if(0===n)throw new Error("N cannot be zero");if(1===n)return u(t).toFixed(e);const r=u(t);if(n%2==0&&-1===r.sign())throw new Error("Complex numbers are not supported");if(r.isZero())return new o(0n).toFixed(e);if(r.isOne())return new o(1n).toFixed(e);const i=new s(n-1,n),a=new s(r,n),d=((n,t)=>{const e=t<0;e&&(t=-t);let r=t**(1/n);return e&&(r=-r),r.toString()})(n,r.toNumber());let m=new o(d),c=m.trunc(e);for(;;){m=i.mul(m).add(a.mul(m.inv().pow(n-1)));const t=m.trunc(e);if(m.isZero()||c.eq(t))break;c=t}return m.toFixed(e)},c=(n,t)=>m(2,n,t);class h{constructor(n,t){this.cachedDigits=0,this.fn=n,this.max=t}get(n){if(n<=this.cachedDigits)return this.cache.trunc(n);const t=new o(this.fn(n)),e=Math.min(this.max,n);return this.cachedDigits!==e&&(this.cache=t.trunc(e),this.cachedDigits=e),t}}const l=(n,t)=>{let e=u(n);if(e.isOne())return new o(0).toFixed(t);if(e.lte(0n))throw new Error("Invalid parameter");let r=0;for(;e.sub(1n).abs().gt("0.1");)e=new o(c(e,t+10)),r++;const i=e.sub(1n).div(e.add(1n)),s=i.pow(2n).normalize();let a=i,d=1n,m=u(i);for(;;){let n=u(0);for(let e=0;e<4;e++){a=a.mul(s),d+=2n;const e=a.div(d);n=n.add(e).trunc(t+10)}if(n.isZero())break;m=m.add(n)}return m=m.mul(2n**BigInt(r+1)),m.toFixed(t)},g=new h((n=>l(2n,n)),200),f=new h((n=>l(10n,n)),200),w=new h((n=>{if(0===n)return"3";let t=1n,e=3n*10n**BigInt(n+20),r=e;for(;0n!==e;)e=e*t/(4n*(t+1n)),t+=2n,r+=e/t;return`3.${r.toString().slice(1,n+1)}`}),1e3),b=n=>0===n?"3":w.get(n).toFixed(n),p=(t,e)=>{const r=e+10,{x:i,quadrant:s}=((n,t)=>{const e=new o(b(t)),r=e.mul(2n);(n=n.mod(r)).gt(e)?n=n.sub(r):n.lt(e.neg())&&(n=n.add(r));const i=e.div(2n),s=n.div(i);let a=0;return s.gte(i)?(a=2,n=e.sub(n)):s.gte(0n)?a=1:s.gte(i.neg())?(a=4,n=n.neg()):(a=3,n=e.sub(n.neg())),{quadrant:a,x:n}})(u(t),r),a=i.round(r,n.RoundingMode.NEAREST_AWAY_FROM_ZERO).pow(2n).normalize();let d=a,m=2n,c=u(1n).sub(d.div(m).trunc(r)),h=3n;const l=u(1n).div(10n**BigInt(r));let g=1;for(;;){m*=h*(h+1n),h+=2n;const n=h*(h+1n);h+=2n,d=d.mul(a),m*=n;let i=d.mul(n);d=d.mul(a),i=i.sub(d);const o=i.div(m).trunc(r);if(g++,c=c.add(o),o.lt(l)){const n=c.trunc(e),i=o.add(l.mul(g)),s=c.add(i).trunc(e);if(n.eq(s))break;return u(p(t,r+50)).toFixed(e)}}return(1===s||4===s?c:c.neg()).round(e+3,n.RoundingMode.TO_ZERO).toFixed(e)},E=(n,t)=>{const e=new o(b(t+10)),r=u(n);return p(e.div(2n).sub(r),t)},I=(n,t)=>{let e=u(n);if(e.isZero())return"0";if(e.abs().isOne())return u(b(t)).div(4*e.sign()).toFixed(t);let r=0;for(;e.abs().gt("0.42");){const n=u(c(e.pow(2n).add(1n),t+10));e=e.div(n.add(1n)),r++}const i=e.pow(2).normalize(),o=i.pow(2).normalize();let s=3n,a=e.sub(e.mul(i).div(s)),d=e.mul(o);const m=u(1n).div(10n**BigInt(t+10));for(;;){s+=2n;const n=s+2n,e=d.mul(i.mul(-s).add(n)).div(s*n);if(s=n,d=d.mul(o),a=a.add(e).trunc(t+10),e.abs().lt(m))break}return a=a.mul(2n**BigInt(r)),a.toFixed(t)},v=(n,t)=>{const e=u(n);if(e.isZero())return"0";if(e.abs().isOne())return u(b(t)).mul(e.sign()).div(2n).toFixed(t);if(e.abs().eq("1/2"))return u(b(t)).mul(e.sign()).div(6n).toFixed(t);if(e.gt(1n)||e.lt(-1n))throw new Error("Out of range");const r=u(c(e.pow(2n).neg().add(1),t+10));return u(I(e.div(r.add(1n)),t+10)).mul(2).toFixed(t)};n.ExactNumber=u,n.PI=b,n.acos=(n,t)=>{const e=u(n);if(e.isZero())return u(b(t)).div(2n).toFixed(t);if(e.isOne())return"0";if(e.abs().isOne())return b(t);if(e.abs().eq("1/2")){const n=u(b(t)).div(3n);return-1===e.sign()?n.mul(2n).toFixed(t):n.toFixed(t)}if(e.gt(1n)||e.lt(-1n))throw new Error("Out of range");return u(b(t+10)).div(2n).sub(v(e,t+10)).toFixed(t)},n.asin=v,n.atan=I,n.cbrt=(n,t)=>m(3,n,t),n.cos=p,n.cosh=(n,t)=>{const e=u(n).pow(2n).normalize();let r=e,i=2n,o=r.div(i).add(1n).trunc(t+5),s=3n;const a=u(1n).div(10n**BigInt(t+5));for(;;){r=r.mul(e),i*=s*(s+1n),s+=2n;const n=r.div(i);if(o=o.add(n).trunc(t+5),n.abs().lt(a))break}return o.toFixed(t)},n.exp=(n,t)=>{const e=u(n);let r=e.add(1n),i=6n,o=4n;const a=e.pow(2n);let d=a;const m=new s(1n,10n**BigInt(t+5));for(;;){const n=d.mul(e.add(o-1n)).div(i);if(i*=o*(o+1n),o+=2n,d=d.mul(a),r=r.add(n).trunc(t+5),n.abs().lte(m))break}return r.toFixed(t)},n.log=l,n.log10=(n,t)=>new o(l(n,t+10)).div(f.get(t+10)).toFixed(t),n.log2=(n,t)=>new o(l(n,t+10)).div(g.get(t+10)).toFixed(t),n.logn=(n,t,e)=>{if(!Number.isSafeInteger(n)||n<2)throw new Error("Invalid parameter for N");const r=l(t,e+10),i=l(n,e+10);return new o(r).div(i).toFixed(e)},n.nthroot=m,n.pow=(n,t,e)=>{const r=new s(n,1n),i=new s(t,1n).getFractionParts(!1);return m(i.denominator.toNumber(),r.pow(i.numerator),e)},n.sin=E,n.sinh=(n,t)=>{const e=u(n),r=e.pow(2n).normalize();let i=e,o=1n,s=e.trunc(t+5),a=2n;const d=u(1n).div(10n**BigInt(t+5));for(;;){i=i.mul(r),o*=a*(a+1n),a+=2n;const n=i.div(o);if(s=s.add(n).trunc(t+5),n.abs().lt(d))break}return s.toFixed(t)},n.sqrt=c,n.tan=(n,t)=>{if(u(n).isZero())return"0";return u(E(n,t+10)).div(p(n,t+10)).toFixed(t)},n.trimTrailingZeros=r,Object.defineProperty(n,"__esModule",{value:!0})})); |
{ | ||
"name": "exactnumber", | ||
"description": "Arbitrary-precision decimals. Enables making precise math calculations with rational numbers, without precision loss.", | ||
"version": "0.8.0", | ||
"version": "0.8.1", | ||
"main": "dist/index.umd.js", | ||
@@ -6,0 +6,0 @@ "module": "dist/index.esm.js", |
@@ -397,2 +397,22 @@ import { FixedNumber } from './FixedNumber'; | ||
expect(run('1.5010', 0, RoundingMode.NEAREST_TO_NEGATIVE)).toBe('2'); | ||
expect(run('52', 1, RoundingMode.TO_ZERO)).toBe('52.0'); | ||
expect(run('5.2', 1, RoundingMode.TO_ZERO)).toBe('5.2'); | ||
expect(run('5.5', 0, RoundingMode.TO_ZERO)).toBe('5'); | ||
expect(run('5.5', 1, RoundingMode.TO_ZERO)).toBe('5.5'); | ||
expect(run('5.5', 2, RoundingMode.TO_ZERO)).toBe('5.50'); | ||
expect(run('52', 1, RoundingMode.NEAREST_TO_POSITIVE)).toBe('52.0'); | ||
expect(run('5.2', 1, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.2'); | ||
expect(run('5.5', 0, RoundingMode.NEAREST_TO_POSITIVE)).toBe('6'); | ||
expect(run('5.5', 1, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.5'); | ||
expect(run('5.5', 2, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.50'); | ||
expect(run('5.54', 1, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.5'); | ||
expect(run('5.55', 1, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.6'); | ||
expect(run('5.55', 2, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.55'); | ||
expect(run('5.554', 2, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.55'); | ||
expect(run('5.555000', 2, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.56'); | ||
expect(run('5.555000', 3, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.555'); | ||
expect(run('5.555', 2, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.56'); | ||
expect(run('5.09', 1, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.1'); | ||
}); | ||
@@ -437,2 +457,7 @@ | ||
expect(run('52', 10, RoundingMode.NEAREST_TO_POSITIVE)).toBe('52'); | ||
expect(run('5.2', 10, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.2'); | ||
expect(run('5.5', 10, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.5'); | ||
expect(run('5.09', 10, RoundingMode.NEAREST_TO_POSITIVE)).toBe('5.09'); | ||
expect(run('129.000', 2, RoundingMode.TO_ZERO)).toBe('120'); | ||
@@ -439,0 +464,0 @@ expect(run('129.000', 2, RoundingMode.TO_POSITIVE)).toBe('130'); |
@@ -207,14 +207,13 @@ import { bigIntToStr } from './util'; | ||
const numberToZero = shift > 0 ? this.number / exp : this.number * exp; | ||
const outDigits = shift > 0 ? this.number / exp : this.number * exp; | ||
if (roundingMode === RoundingMode.TO_ZERO) { | ||
return new FixedNumber(numberToZero, decimals); | ||
return new FixedNumber(outDigits, decimals); | ||
} | ||
const expectedFracDecimals = shift > 0 ? Math.abs(shift) : decimals; | ||
const fracPart = shift > 0 ? this.number % exp : numberToZero % 10n ** BigInt(decimals); | ||
if (fracPart === 0n) return new FixedNumber(numberToZero, decimals); | ||
const extraDigits = shift > 0 ? this.number % exp : 0n; | ||
if (extraDigits === 0n) return new FixedNumber(outDigits, decimals); | ||
if (roundingMode === RoundingMode.AWAY_FROM_ZERO) { | ||
const res = this.number < 0n ? numberToZero - 1n : numberToZero + 1n; | ||
const res = this.number < 0n ? outDigits - 1n : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
@@ -224,3 +223,3 @@ } | ||
if (roundingMode === RoundingMode.TO_POSITIVE) { | ||
const res = this.number < 0n ? numberToZero : numberToZero + 1n; | ||
const res = this.number < 0n ? outDigits : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
@@ -230,3 +229,3 @@ } | ||
if (roundingMode === RoundingMode.TO_NEGATIVE) { | ||
const res = this.number >= 0n ? numberToZero : numberToZero - 1n; | ||
const res = this.number >= 0n ? outDigits : outDigits - 1n; | ||
return new FixedNumber(res, decimals); | ||
@@ -248,12 +247,14 @@ } | ||
let fracStr = (fracPart < 0n ? -fracPart : fracPart).toString(); | ||
if (fracStr.length < expectedFracDecimals) { | ||
fracStr = '0'.repeat(expectedFracDecimals - fracStr.length) + fracStr; | ||
let extraDigitsStr = (extraDigits < 0n ? -extraDigits : extraDigits).toString(); | ||
// '00123' extra part will appear in extraDigitsStr as '123' | ||
// -> in this case we can exclude the tie case by setting the extra part to zero | ||
const expectedFracDecimals = shift > 0 ? shift : 0; | ||
if (extraDigitsStr.length < expectedFracDecimals) { | ||
extraDigitsStr = '0'; | ||
} | ||
let isTie = fracStr[0] === '5'; | ||
let isTie = extraDigitsStr[0] === '5'; | ||
if (isTie) { | ||
for (let i = 1; i < fracStr.length; i++) { | ||
if (fracStr[i] !== '0') { | ||
for (let i = 1; i < extraDigitsStr.length; i++) { | ||
if (extraDigitsStr[i] !== '0') { | ||
isTie = false; | ||
@@ -267,7 +268,7 @@ break; | ||
if (roundingMode === RoundingMode.NEAREST_TO_ZERO) { | ||
return new FixedNumber(numberToZero, decimals); | ||
return new FixedNumber(outDigits, decimals); | ||
} | ||
if (roundingMode === RoundingMode.NEAREST_AWAY_FROM_ZERO) { | ||
const res = this.number < 0n ? numberToZero - 1n : numberToZero + 1n; | ||
const res = this.number < 0n ? outDigits - 1n : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
@@ -277,3 +278,3 @@ } | ||
if (roundingMode === undefined || roundingMode === RoundingMode.NEAREST_TO_POSITIVE) { | ||
const res = this.number < 0n ? numberToZero : numberToZero + 1n; | ||
const res = this.number < 0n ? outDigits : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
@@ -283,3 +284,3 @@ } | ||
if (roundingMode === RoundingMode.NEAREST_TO_NEGATIVE) { | ||
const res = this.number >= 0n ? numberToZero : numberToZero - 1n; | ||
const res = this.number >= 0n ? outDigits : outDigits - 1n; | ||
return new FixedNumber(res, decimals); | ||
@@ -289,7 +290,7 @@ } | ||
if (roundingMode === RoundingMode.NEAREST_TO_EVEN) { | ||
if (numberToZero % 2n === 0n) { | ||
return new FixedNumber(numberToZero, decimals); | ||
if (outDigits % 2n === 0n) { | ||
return new FixedNumber(outDigits, decimals); | ||
} | ||
const res = numberToZero < 0n ? numberToZero - 1n : numberToZero + 1n; | ||
const res = outDigits < 0n ? outDigits - 1n : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
@@ -299,7 +300,7 @@ } | ||
if (Number(fracStr[0]) < 5) { | ||
return new FixedNumber(numberToZero, decimals); | ||
if (Number(extraDigitsStr[0]) < 5) { | ||
return new FixedNumber(outDigits, decimals); | ||
} | ||
const res = this.number < 0 ? numberToZero - 1n : numberToZero + 1n; | ||
const res = this.number < 0 ? outDigits - 1n : outDigits + 1n; | ||
return new FixedNumber(res, decimals); | ||
@@ -306,0 +307,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
337194
7110