UNPKG

fixed-precision

Version:

A fixed-precision decimal arithmetic library for JavaScript/TypeScript

2 lines (1 loc) 11.6 kB
"use strict";var E=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var Q=Object.getOwnPropertyNames;var Y=Object.prototype.hasOwnProperty;var tt=(e,t)=>{for(var n in t)E(e,n,{get:t[n],enumerable:!0})},nt=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Q(t))!Y.call(e,r)&&r!==n&&E(e,r,{get:()=>t[r],enumerable:!(i=K(t,r))||i.enumerable});return e};var et=e=>nt(E({},"__esModule",{value:!0}),e);var gt={};tt(gt,{default:()=>b,fixedconfig:()=>lt});module.exports=et(gt);function y(e,t,n){let i=t,r=e,o=n;for(;i>0;)i&1&&(o=o*r/n),i=i>>1,i>0&&(r=r*r/n);return o}function R(e,t,n){if(!Number.isInteger(t))throw new Error("Exponent must be an integer");if(t===0)return n;if(e===0n){if(t<0)throw new Error("0 ** negative is undefined");return 0n}let i=t<0,r=Math.abs(t),o;return r===1?o=e:r===2?o=e*e/n:r===3?o=e*e/n*e/n:o=y(e,r,n),i?n*n/o:o}var ot=[1n,10n,100n,1000n,10000n,100000n,1000000n,10000000n,100000000n,1000000000n,10000000000n,100000000000n,1000000000000n,10000000000000n,100000000000000n,1000000000000000n,10000000000000000n,100000000000000000n,1000000000000000000n,10000000000000000000n,100000000000000000000n];function f(e){let t=ot[e];if(t===void 0)throw new Error("Decimal places must be an integer between 0 and 20");return t}function p(e){return e<=20?f(e):10n**BigInt(e)}function k(e){if(!Number.isInteger(e)||e<1||e>=1e6)throw new Error("Precision must be a positive integer")}function V(e,t,n,i,r){let o=(t<0n?-t:t)<<1n;return r===7?i&&o>=n?e+1n:e:(r===4?o>=n:o>n)?i?e+1n:e-1n:e}function T(e,t,n,i){let r=(t<0n?-t:t)<<1n;return r===n?e%2n===0n?e:i?e+1n:e-1n:r>n?i?e+1n:e-1n:e}function $(e,t,n,i){let r=(t<0n?-t:t)<<1n;return i?r>n?e+1n:e:r>=n?e-1n:e}function _(e,t,n){let i=e/t;if(n===1)return i;let r=e-i*t;if(r===0n)return i;let o=e>0n;switch(n){case 0:return o?i+1n:i-1n;case 2:return o?i+1n:i;case 3:return o?i:i-1n;case 4:case 5:case 7:return V(i,r,t,o,n);case 6:return T(i,r,t,o);case 8:return $(i,r,t,o);default:throw new Error(`Rounding mode ${n} is not supported.`)}}function P(e,t,n,i){if(k(t),e===0n)return 0n;let o=(e<0n?-e:e).toString().length-i.places-1,s=i.places+o-t+1;if(s<=0)return e;let u=p(s);return _(e,u,n)*u}function O(e,t){let i=e/t*t,r=e-i;return r===0n?e:(r<0n?-r<<1n:r<<1n)<t?i:e>0n?i+t:i-t}function I(e,t,n,i){if(t<0||t>i.places)throw new Error(`Decimal places (dp) must be between 0 and ${i.places}`);let r=i.places-t,o=f(r);return n===4?O(e,o):_(e,o,n)*o}function A(e,t,n,i){if(!Number.isInteger(t)||t<0||t>20)throw new Error("newScale must be an integer between 0 and 20");if(t===i.places)return e;if(t>i.places)return e*f(t-i.places);let r=f(i.places-t);return _(e,r,n)}function v(e,t){if(e<0n)throw new Error("Square root of negative number");if(e===0n)return 0n;if(e===t)return t;let n=e*t;if(n<2n)return n;let i=n>>1n;for(i===0n&&(i=1n);;){let r=i+n/i>>1n;if(r>=i)return i;i=r}}function d(e,t){return ut(e),{places:e,roundingMode:t,SCALE:f(e),SCALENUMBER:10**e}}function ut(e){if(!Number.isInteger(e)||e<0||e>20)throw new Error("Decimal places must be an integer between 0 and 20")}function N(e,t){if(Number.isNaN(e)||!Number.isFinite(e))throw new Error("Invalid number: value must be a finite number.");let n=e*t.SCALENUMBER;if(Math.abs(n)>Number.MAX_SAFE_INTEGER){if(Number.isInteger(e))return BigInt(e)*t.SCALE;let i=Math.trunc(e),r=Math.abs(i-e),o=BigInt(Math.trunc(r*t.SCALENUMBER));return BigInt(i)*t.SCALE+o}return BigInt(Math.trunc(n))}function U(e,t,n){let i=e.length;return t<16?ct(e,i,t,n):ft(e,i,n)}function ct(e,t,n,i){let r=i.SCALENUMBER;if(t+n<16){let s=Number(e);return BigInt(s*r)}return t<16?at(e,t,n,i):BigInt(e)*i.SCALE}function at(e,t,n,i){let r=i.SCALENUMBER,o=Number(e);if(!Number.isFinite(o))return BigInt(e)*i.SCALE;if(Math.abs(o)<=Number.MAX_SAFE_INTEGER/r)return BigInt(o*r);let s=16-t;return s>=n?BigInt(o*r):BigInt(o*10**s)*f(n-s)}function ft(e,t,n){if(t<16){let r=Number(e);return BigInt(r)*n.SCALE}return BigInt(e)*n.SCALE}function q(e,t,n,i,r){let o=BigInt(e);if(i<16){let a=Number(t);if(!a)return o*r;let m=BigInt(a*10**n);return o<0n?o*r-m:o*r+m}let s=BigInt(t);if(!s)return o*r;let u=s*f(n);return o<0n?o*r-u:o*r+u}function D(e,t,n,i){let r=BigInt(t);if(!r)return BigInt(e*i);let o=r*f(n);return e<0?BigInt(e*i)-o:BigInt(e*i)+o}function z(e,t,n,i,r){let o=e*r;if(i<16){let a=Number(t),m=BigInt(a*10**n);return o<0?BigInt(o)-m:BigInt(o)+m}let u=BigInt(t)*f(n);return o<0?BigInt(o)-u:BigInt(o)+u}function W(e,t,n,i,r,o){let s=Number(t),u=16-n;if(u>=r)return BigInt(e*o+s);let a=e*10**u,m=BigInt(s*10**i);return e<0?BigInt(a)*f(r-u)-m:BigInt(a)*f(r-u)+m}function X(e,t,n,i,r,o){let s=Number(e),u=o.SCALENUMBER;return Math.abs(s)<=Number.MAX_SAFE_INTEGER/u?z(s,t,i,r,u):r<16?W(s,t,n,i,r,u):D(s,t,i,u)}function G(e,t,n,i){let r=e.slice(0,t),o=e.slice(t+1,t+1+n),s=o.length,u=n>=s?n-s:n;return t<16?X(r,o,t,u,n,i):q(r,o,u,n,i.SCALE)}function Z(e,t,n,i){let r=i.SCALENUMBER,o=Number(e),s=16-t,u=o<0?-1/r:1/r;if(s>=n)return BigInt(Math.trunc(n===0?o:o*r+u));let a=o*10**s,m=Math.trunc(a),l=Math.trunc(m-a);return l?BigInt(m)*f(n-s)+BigInt(l):BigInt(m)*f(n-s)}function B(e,t){let n=e.indexOf("."),i=t.places;return n===-1?U(e,i,t):n+i<16?Z(e,n,i,t):G(e,n,i,t)}function x(e,t,n=!0){let i=t.places;if(i===0)return e.toString();if(e===0n)return"0";let r=e.toString(),o=r.length,s=o;if(n&&r[o-1]==="0"){let g=o-i;for(;s>g&&r[s-1]==="0";)--s}let u=i-o+s;if(u===0)return r.slice(0,s);let a=r[0]==="-"?1:0,m=s-a;if(m>u){let g=s-u;return`${r.slice(0,g)}.${r.substring(g,s)}`}let l=r.slice(a,s);return m===u?(a?"-0.":"0.")+l:(a?"-0.":"0.")+"0".repeat(u-m)+l}var _t=BigInt(Number.MAX_SAFE_INTEGER);function C(e,t){if((e<0n?-e:e)<=_t)return Number(e)/t.SCALENUMBER;if(t.places<15){let i=e/t.SCALE,r=e-i*t.SCALE;return Number(i)+Number(r)/t.SCALENUMBER}return Number(x(e,t))}function j(e,t){if(!Number.isInteger(e)||e<0||e>20)throw new Error(t)}function J(e){if(!Number.isInteger(e)||e<0||e>8)throw new Error("Invalid rounding mode. Must be 0, 1, 2, 3, 4, 5, 6, 7 or 8")}var c=class c{static configure(t){let n=t.places??c.defaultContext.places,i=t.roundingMode??c.defaultContext.roundingMode;j(n,"Decimal places must be an integer between 0 and 20"),J(i),c.defaultContext=d(n,i)}static create(t){j(t.places,"Decimal places must be an integer between 0 and 20");let n=t.roundingMode??4;J(n);let i=d(t.places,n);return r=>new c(r,i)}constructor(t,n){this.ctx=n??c.defaultContext,this.value=c.toScaled(t,this.ctx)}fromRaw(t){let n=new c(0n,this.ctx);return n.value=t,n}static toScaled(t,n){if(t instanceof c)return t.value;if(typeof t=="bigint")return t;if(typeof t=="number")return N(t,n);if(typeof t=="string")return B(t,n);throw new Error(`Invalid value type: ${typeof t}`)}toScaledValue(t){return c.toScaled(t,this.ctx)}coerce(t){if(t instanceof c){if(this.ctx.places!==t.ctx.places)throw new Error("Cannot operate on different precisions");return t}return new c(t,this.ctx)}static random(t){let n=t??c.defaultContext.places,i=0n;for(let o=0;o<n;o++)i=i*10n+BigInt(Math.trunc(Math.random()*10));let r=new c(0n,d(n,c.defaultContext.roundingMode));return r.value=i,r}static resolveContext(t){let n=null;for(let i of t)if(i instanceof c&&(!n||i.ctx.places>n.places)&&(n=i.ctx,n.places===20))return n;return n??c.defaultContext}static normalizeTo(t,n){return t instanceof c?t.ctx.places===n.places&&t.ctx.roundingMode===n.roundingMode?t:t.scale(n.places,n.roundingMode):new c(t,n)}static min(t,...n){let i=Array.isArray(t)?[...t,...n]:[t,...n],r=i[0];if(r===void 0)throw new Error("FixedPrecision.min requires at least one argument");let o=c.resolveContext(i),s=c.normalizeTo(r,o);for(let u of i.slice(1)){let a=c.normalizeTo(u,o);a.lt(s)&&(s=a)}return s}static max(t,...n){let i=Array.isArray(t)?[...t,...n]:[t,...n],r=i[0];if(r===void 0)throw new Error("FixedPrecision.max requires at least one argument");let o=c.resolveContext(i),s=c.normalizeTo(r,o);for(let u of i.slice(1)){let a=c.normalizeTo(u,o);a.gt(s)&&(s=a)}return s}static sum(t,...n){let i=Array.isArray(t)?[...t,...n]:[t,...n];if(i[0]===void 0)return new c(0n);let o=c.resolveContext(i),s=0n;for(let a of i)s+=c.normalizeTo(a,o).value;let u=new c(0n,o);return u.value=s,u}abs(){return this.fromRaw(this.value<0n?-this.value:this.value)}cmp(t){let n=this.coerce(t).value;return this.value<n?-1:this.value>n?1:0}eq(t){return this.value===this.coerce(t).value}gt(t){return this.value>this.coerce(t).value}gte(t){return this.value>=this.coerce(t).value}lt(t){return this.value<this.coerce(t).value}lte(t){return this.value<=this.coerce(t).value}isInteger(){return this.value%this.ctx.SCALE===0n}isNegative(){return this.value<0n}isPositive(){return this.value>0n}isZero(){return this.value===0n}add(t){return this.fromRaw(this.value+this.coerce(t).value)}plus(t){return this.fromRaw(this.value+this.toScaledValue(t))}sub(t){return this.fromRaw(this.value-this.coerce(t).value)}minus(t){return this.fromRaw(this.value-this.toScaledValue(t))}mul(t){return this.fromRaw(this.value*this.coerce(t).value/this.ctx.SCALE)}tiems(t){return this.fromRaw(this.value*this.toScaledValue(t))}div(t){return this.fromRaw(this.value*this.ctx.SCALE/this.coerce(t).value)}idiv(t){return this.fromRaw(this.value/this.coerce(t).value*this.ctx.SCALE)}ratio(t){return this.fromRaw(this.value/this.toScaledValue(t))}mod(t){return this.fromRaw(this.value*this.ctx.SCALE%this.coerce(t).value)}rem(t){return this.fromRaw(this.value%this.toScaledValue(t))}divmod(t){let n=this.coerce(t),i=this.fromRaw(this.value*this.ctx.SCALE/n.value);return{quotient:i,remainder:this.fromRaw(this.value-i.value*n.value/this.ctx.SCALE)}}idivmod(t){let n=this.coerce(t),i=this.fromRaw(this.value/n.value*this.ctx.SCALE);return{quotient:i,remainder:this.fromRaw(this.value-i.value*n.value/this.ctx.SCALE)}}rest(t){return this.divmod(t).remainder}neg(){return this.fromRaw(-this.value)}pow(t){return this.fromRaw(R(this.value,t,this.ctx.SCALE))}square(){return this.mul(this)}sqrt(){return this.fromRaw(v(this.value,this.ctx.SCALE))}round(t=this.ctx.places,n=this.ctx.roundingMode){return this.fromRaw(I(this.value,t,n,this.ctx))}scale(t,n=this.ctx.roundingMode){let i=A(this.value,t,n,this.ctx),r=d(t,this.ctx.roundingMode),o=new c(0n,r);return o.value=i,o}prec(t,n=this.ctx.roundingMode){return this.fromRaw(P(this.value,t,n,this.ctx))}trunc(){return this.round(0,1)}ceil(){return this.round(0,2)}floor(){return this.round(0,3)}shiftedBy(t){let n=p(Math.abs(t));return this.fromRaw(t>=0?this.value*n:this.value/n)}toNumber(t){if(t===void 0)return C(this.value,this.ctx);let n=this.scale(t);return C(n.value,n.ctx)}toString(t=!0){return x(this.value,this.ctx,t)}toFixed(t=0,n=this.ctx.roundingMode){return this.scale(t,n).toString(!1)}toExponential(t=this.ctx.places,n){return(t<=this.ctx.places?this.round(t,n):this).toNumber().toExponential(t)}toPrecision(t,n){if(t>=1e6)throw new Error("Invalid precision");if(this.value===0n)return"0";let i=P(this.value,t,n??this.ctx.roundingMode,this.ctx);if(i===0n)return"0";let r=i<0n?-i:i,o=r.toString().length,s=this.ctx.places,u;if(r>=this.ctx.SCALE?u=o-s-1:u=-(s-o+1),u<-6||u>=t){let a=p(Math.abs(u)),m=u>=0?i/a:i*a,l=this.fromRaw(m),g=t-1,L=l.toFixed(g,n),H=u>0?"+":"";return L+=`e${H}${u}`,L}return this.fromRaw(i).toString().replace(/(\.\d*?)0+$/,"$1").replace(/\.$/,"")}toFormat(t=this.ctx.places,n){let i=this.toFixed(t,n),[r="",o]=i.split("."),s=r[0]==="-"?"-":"",u=s?r.slice(1):r;return`${s}${u.replace(/\B(?=(\d{3})+(?!\d))/g,",")}${o===void 0?"":`.${o}`}`}toJSON(){return this.toString()}valueOf(){return this.toString()}};c.defaultContext=d(8,4);var b=c,lt={configure:b.configure.bind(b)};0&&(module.exports={fixedconfig});