New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@bignum/core

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bignum/core - npm Package Compare versions

Comparing version 0.7.0 to 0.8.0

130

lib/index.d.ts

@@ -5,103 +5,53 @@ type OverflowContext = {

};
type IsOverflow = (context: OverflowContext) => boolean | undefined | null;
type IsOverflow = (context: OverflowContext) => boolean;
type MathOptions = {
/** You can specify an overflow test function. */
overflow?: IsOverflow;
/** @deprecated The maximum number of decimal places. */
maxDp?: bigint;
/** @deprecated The maximum number of precision when having decimals. */
maxDecimalPrecision?: bigint;
/**
* Specifies a rounding behavior for numerical operations capable of discarding precision.
* If rounding must be performed to generate a result with the given scale, the specified rounding mode is applied.
*/
roundingMode?: RoundingMode;
};
type DivideOptions = MathOptions;
type SqrtOptions = MathOptions;
type NthRootOptions = MathOptions;
/** This is used in negative pows. */
type PowOptions = MathOptions;
/** Specifies a rounding behavior for numerical operations capable of discarding precision. */
declare enum RoundingMode {
trunc = 0,
round = 1,
floor = 2,
ceil = 3
}
/** Internal Fraction class */
declare class Frac {
#private;
/** numerator */
readonly n: Num;
private readonly n;
/** denominator */
readonly d: Num;
readonly opt: IsOverflow;
static valueOf(n: Num, d: Num, overflowOpt: IsOverflow): Frac;
private constructor();
static add(a: Num, b: Num): Frac | null;
static mul(a: Num, b: Num): Frac | null;
static div(n: Num, d: Num): Frac | null;
resolve(overflow?: IsOverflow, useFrac?: boolean): Num | Inf;
}
/** Internal Number class */
declare class Num {
#private;
readonly inf = false;
/** int value */
private i;
/** exponent */
private e;
/** pow of ten denominator */
private d;
/** original fraction */
readonly frac: Frac | null | undefined;
constructor(intValue: bigint, exponent: bigint, frac?: Frac | null | undefined);
private readonly d;
static numOf(i: bigint, e?: bigint): Frac;
constructor(numerator: bigint, denominator: bigint);
signum(): 1 | 0 | -1;
negate(): Num;
abs(): Num;
add(augend: Num): Num;
add(augend: Num | Inf): Num | Inf;
subtract(subtrahend: Num): Num;
subtract(subtrahend: Num | Inf): Num | Inf;
multiply(multiplicand: Num): Num;
multiply(multiplicand: Inf): Inf | null;
multiply(multiplicand: Num | Inf): Num | Inf | null;
divide(divisor: Num, options?: DivideOptions): Num;
divide(divisor: Num | Inf, options?: DivideOptions): Num | Inf;
modulo(divisor: Num | Inf): Num | Inf | null;
pow(n: Num, options?: PowOptions): Num | null;
pow(n: Num | Inf, options?: PowOptions): Num | Inf | null;
scaleByPowerOfTen(n: Num | Inf): Num | Inf | null;
sqrt(options?: SqrtOptions): Num;
nthRoot(n: Num, options?: NthRootOptions): Num;
nthRoot(n: Num | Inf, options?: NthRootOptions): Num | Inf | null;
trunc(): Num;
round(): Num;
floor(mod?: bigint): Num;
ceil(mod?: bigint): Num;
compareTo(other: Num | Inf): 0 | -1 | 1;
negate(): Frac;
abs(): Frac;
get inf(): boolean;
add(a: Frac): Frac | null;
multiply(m: Frac): Frac | null;
divide(d: Frac): Frac | null;
modulo(d: Frac): Frac | null;
pow(n: Frac, options?: MathOptions): Frac | null;
scaleByPowerOfTen(n: Frac): Frac | null;
sqrt(options?: MathOptions): Frac | null;
nthRoot(n: Frac, options?: MathOptions): Frac | null;
trunc(): Frac;
round(): Frac;
floor(): Frac;
ceil(): Frac;
compareTo(other: Frac): 0 | -1 | 1;
toString(): string;
static div(dividend: Num, divisor: Num, overflow: IsOverflow, useFrac: boolean): Num | Inf;
}
/** Internal Infinity class */
declare class Inf {
readonly inf = true;
private readonly s;
constructor(sign: 1 | -1);
signum(): 1 | -1;
negate(): Inf;
add(augend: Inf | Num): Inf | null;
subtract(subtrahend: Inf | Num): Inf | null;
multiply(multiplicand: Inf | Num): Inf | null;
divide(divisor: Inf | Num): Inf | null;
modulo(): null;
pow(n: Inf | Num): Inf | Num;
sqrt(): Inf | null;
nthRoot(n: Inf | Num): Inf | Num | null;
scaleByPowerOfTen(n: Inf | Num): Inf | null;
compareTo(n: Inf | Num): 1 | 0 | -1;
abs(): Inf;
trunc(): Inf;
round(): Inf;
ceil(): Inf;
floor(): Inf;
toString(): string;
toNum(): number;
}
declare class BigNum {
#private;
static readonly valueOf: typeof valueOf;
constructor(value: string | number | bigint | boolean | BigNum | Num | Inf | null | undefined);
constructor(value: string | number | bigint | boolean | BigNum | Frac | null | undefined);
/** Returns a number indicating the sign. */

@@ -120,3 +70,3 @@ signum(): -1 | 0 | 1 | typeof NaN;

*/
divide(divisor: BigNum | string | number | bigint, options?: DivideOptions): BigNum;
divide(divisor: BigNum | string | number | bigint): BigNum;
/**

@@ -129,9 +79,9 @@ * Returns a BigNum whose value is (this % divisor)

*/
pow(n: BigNum | string | number | bigint, options?: PowOptions): BigNum;
pow(n: BigNum | string | number | bigint, options?: MathOptions): BigNum;
/** Returns a BigNum whose numerical value is equal to (this * 10 ** n). */
scaleByPowerOfTen(n: BigNum | string | number | bigint): BigNum;
/** Returns an approximation to the square root of this. */
sqrt(options?: SqrtOptions): BigNum;
sqrt(options?: MathOptions): BigNum;
/** Returns an approximation to the nth root of this. */
nthRoot(n: BigNum | string | number | bigint, options?: NthRootOptions): BigNum;
nthRoot(n: BigNum | string | number | bigint, options?: MathOptions): BigNum;
/** Returns a BigNum whose value is the absolute value of this BigNum. */

@@ -157,2 +107,2 @@ abs(): BigNum;

export { BigNum, type DivideOptions, type IsOverflow, type MathOptions, type NthRootOptions, type OverflowContext, type PowOptions, type SqrtOptions };
export { BigNum, type IsOverflow, type MathOptions, type OverflowContext, RoundingMode };

@@ -1,29 +0,1 @@

// src/frac.mts
var Frac = class _Frac {
static valueOf(n, d, overflowOpt) {
if (n.frac)
_Frac.valueOf(n.frac.n, d.multiply(n.frac.d), overflowOpt);
if (d.frac)
_Frac.valueOf(n.multiply(d.frac.d), d.frac.n, overflowOpt);
return new _Frac(n, d, overflowOpt);
}
constructor(n, d, opt) {
this.n = n;
this.d = d;
this.opt = opt;
}
static add(a, b) {
return a.frac ? _Frac.valueOf(a.frac.n.add(b.multiply(a.frac.d)), a.frac.d, a.frac.opt) : b.frac ? _Frac.add(b, a) : null;
}
static mul(a, b) {
return a.frac ? _Frac.valueOf(a.frac.n.multiply(b), a.frac.d, a.frac.opt) : b.frac ? _Frac.mul(b, a) : null;
}
static div(n, d) {
return n.frac ? _Frac.valueOf(n.frac.n, d.multiply(n.frac.d), n.frac.opt) : d.frac ? _Frac.valueOf(n.multiply(d.frac.d), d.frac.n, d.frac.opt) : null;
}
resolve(overflow, useFrac) {
return Num.div(this.n, this.d, overflow ?? this.opt, useFrac ?? true);
}
};
// src/nth-root-utils.mts

@@ -65,2 +37,11 @@ function createNthRootTable(nth) {

// src/options.mts
var RoundingMode = /* @__PURE__ */ ((RoundingMode2) => {
RoundingMode2[RoundingMode2["trunc"] = 0] = "trunc";
RoundingMode2[RoundingMode2["round"] = 1] = "round";
RoundingMode2[RoundingMode2["floor"] = 2] = "floor";
RoundingMode2[RoundingMode2["ceil"] = 3] = "ceil";
return RoundingMode2;
})(RoundingMode || {});
// src/util.mts

@@ -79,5 +60,2 @@ function compare(a, b) {

}
function min(a, b) {
return a <= b ? a : b;
}
function abs(a) {

@@ -87,116 +65,127 @@ return a >= 0n ? a : -a;

function gcd(a, b) {
return b ? gcd(b, a % b) : a;
while (b) {
const t = a % b;
a = b;
b = t;
}
return a;
}
// src/num.mts
var MOD_DIV_OPT = (ctx) => ctx.scale > 0n;
// src/frac.mts
var NOT_SCALE_ZERO = (ctx) => ctx.scale > 0n;
var ROUND_OPTS = Object.fromEntries(
Object.keys(RoundingMode).map(Number).filter(isFinite).map((k) => [k, { overflow: NOT_SCALE_ZERO, roundingMode: k }])
);
var DEF_OPT = (ctx) => ctx.scale > 0n && ctx.precision > 20n;
function parseOFOption(options) {
const { overflow, maxDecimalPrecision, maxDp } = options ?? {};
if (overflow)
return overflow;
if (maxDecimalPrecision != null) {
const checkPrecision = (ctx) => ctx.scale > 0n && ctx.precision > maxDecimalPrecision;
if (maxDp == null)
return checkPrecision;
return (ctx) => ctx.scale > maxDp || checkPrecision(ctx);
var Frac = class _Frac {
static numOf(i, e = 0n) {
return e >= 0n ? new _Frac(i * 10n ** e, 1n) : new _Frac(i, 10n ** -e);
}
if (maxDp != null)
return (ctx) => ctx.scale > maxDp;
return DEF_OPT;
}
function shouldUseFrac(options = {}) {
if (options.overflow)
return false;
const { maxDecimalPrecision, maxDp } = options;
return maxDecimalPrecision == null && maxDp == null;
}
var Num = class _Num {
constructor(intValue, exponent, frac) {
this.inf = false;
if (exponent > 0n) {
this.i = intValue * 10n ** exponent;
this.e = 0n;
this.d = 1n;
constructor(numerator, denominator) {
let n = numerator, d = denominator;
if (d < 0n) {
n = -n;
d = -d;
}
if (d) {
const g = gcd(abs(n), abs(d));
this.n = n / g;
this.d = d / g;
} else {
this.i = intValue;
this.e = exponent;
this.d = 10n ** -exponent;
this.n = n >= 0n ? 1n : -1n;
this.d = d;
}
this.frac = frac;
}
signum() {
return !this.i ? 0 : this.i > 0n ? 1 : -1;
return !this.n ? 0 : this.n > 0n ? 1 : -1;
}
negate() {
return new _Num(-this.i, this.e);
return new _Frac(-this.n, this.d);
}
abs() {
if (this.i >= 0n)
if (this.n >= 0n)
return this;
return this.negate();
}
add(augend) {
const a = augend;
get inf() {
return !this.d;
}
add(a) {
if (this.inf)
return !a.inf || this.n === a.n ? this : null;
if (a.inf)
return a;
const frac = Frac.add(this, a);
if (frac)
return frac.resolve();
this.#alignExponent(a);
return new _Num(this.i + a.i, this.e);
const n = this.n * a.d + a.n * this.d;
const d = this.d * a.d;
return new _Frac(n, d);
}
subtract(subtrahend) {
return this.add(subtrahend.negate());
}
multiply(multiplicand) {
const m = multiplicand;
multiply(m) {
if (this.inf)
return !m.n ? null : this.n >= 0 === m.n >= 0n ? INF : N_INF;
if (m.inf)
return m.multiply(this);
return Frac.mul(this, m)?.resolve() ?? new _Num(this.i * m.i, this.e + m.e);
return new _Frac(this.n * m.n, this.d * m.d);
}
divide(divisor, options) {
if (divisor.inf)
divide(d) {
if (this.inf)
return d.inf ? null : this.n >= 0 === d.n >= 0n ? INF : N_INF;
if (d.inf)
return ZERO;
const overflow = parseOFOption(options);
return this.#div(divisor, overflow, shouldUseFrac(options));
if (!d.n)
return this.n >= 0 ? INF : N_INF;
if (!this.n)
return this;
return new _Frac(this.n * d.d, this.d * d.n);
}
modulo(divisor) {
if (divisor.inf)
modulo(d) {
if (this.inf)
return null;
if (d.inf)
return this;
if (!divisor.i)
if (!d.n)
return null;
const times = this.#div(divisor, MOD_DIV_OPT, false);
return this.subtract(divisor.multiply(times));
const times = this.divide(d).#setScale(ROUND_OPTS[0 /* trunc */]);
return this.add(d.multiply(times).negate());
}
pow(n, options) {
if (this.inf) {
if (n.inf)
return n.n < 0 ? ZERO : INF;
if (!n.n)
return ONE;
if (n.n < 0n)
return ZERO;
if (this.n < 0) {
const hasFrac = n.modulo(ONE).compareTo(ZERO);
if (hasFrac)
return INF;
const binary = !n.modulo(_Frac.numOf(2n)).compareTo(ZERO);
if (binary)
return INF;
}
return this;
}
if (n.inf) {
const minus = n.signum() < 0;
const minus = n.n < 0;
const cmpO = this.abs().compareTo(ONE);
return cmpO < 0 ? minus ? INF : ZERO : cmpO === 0 ? null : minus ? ZERO : INF;
}
if (n.frac) {
n.frac.n.#alignExponent(n.frac.d);
return this.#pow(n.frac.n.i, n.frac.d.i, options);
}
return this.#pow(n.i, n.d, options);
return _Frac.#pow(this, n.n, n.d, options);
}
scaleByPowerOfTen(n) {
if (this.inf)
return n.inf ? n.n > 0 ? this : null : this;
if (n.inf)
return n.signum() < 0 ? ZERO : !this.i ? null : this.i >= 0n ? INF : N_INF;
if (!(n.i % n.d)) {
const bn = n.#trunc();
return new _Num(this.i, this.e + bn);
}
return this.multiply(new _Num(10n, 0n).pow(n));
return n.n < 0n ? ZERO : !this.n ? null : this.n >= 0n ? INF : N_INF;
return this.multiply(_Frac.numOf(10n).pow(n));
}
sqrt(options) {
if (!this.i)
return this;
if (this.i < 0n)
if (this.inf)
return this.n < 0 ? null : INF;
if (this.n < 0n)
throw new Error("Negative number");
const overflow = parseOFOption(options);
const decimalLength = this.#scale();
const [i, e] = this.#toNum();
const decimalLength = -e;
const decimalLengthIsOdd = decimalLength & 1n;
let remainder = this.#simplify().i;
let remainder = i;
if (decimalLengthIsOdd)

@@ -207,16 +196,11 @@ remainder *= 10n;

const pow = 100n ** digitExponent;
let digits = 0n;
let exponent = digitExponent - decimalLength / 2n - (decimalLengthIsOdd ? 1n : 0n);
const overflowCtx = {
get scale() {
return -exponent;
},
get precision() {
return length(digits);
}
};
while (remainder > 0n && !overflow(overflowCtx)) {
exponent--;
const numCtx = numberContext(
1n,
digitExponent - decimalLength / 2n - (decimalLengthIsOdd ? 1n : 0n),
options
);
while (remainder > 0n && !numCtx.overflow()) {
numCtx.intVal *= 10n;
numCtx.exponent--;
remainder *= 100n;
digits *= 10n;
part *= 10n;

@@ -229,3 +213,3 @@ if (remainder < (part + 1n) * pow)

continue;
digits += n;
numCtx.intVal += n;
remainder -= amount;

@@ -236,60 +220,49 @@ part += n * 2n;

}
while (overflow(overflowCtx) && digits) {
exponent++;
digits /= 10n;
}
return new _Num(digits, exponent);
numCtx.round(remainder);
return _Frac.numOf(...numCtx.toNum());
}
nthRoot(n, options) {
if (this.inf)
return n.inf ? ONE : n.compareTo(ONE) === 0 ? this : n.signum() < 0 ? ZERO : INF;
if (n.inf)
return this.pow(ZERO);
if (n.abs().compareTo(ONE) === 0)
return this.pow(n);
if (!n.i)
if (!n.n)
return this.pow(INF);
if (!this.i)
return this;
if (this.i < 0n)
if (this.n < 0n)
throw new Error("Negative number");
if (n.i % n.d) {
return this.#pow(n.d, n.i, options);
}
const overflow = parseOFOption(options);
return this.#nthRoot(n, overflow, shouldUseFrac(options));
return _Frac.#pow(this, n.d, n.n, options);
}
trunc() {
return !this.i || !this.e ? this : new _Num(this.#trunc(), 0n);
return this.#setScale(ROUND_OPTS[0 /* trunc */]);
}
round() {
const mod = this.i % this.d;
if (!mod)
return this;
const h = 10n ** (-this.e - 1n) * 5n;
if (this.i < 0n) {
return mod < -h ? this.floor(mod) : this.ceil(mod);
}
return mod < h ? this.floor(mod) : this.ceil(mod);
return this.#setScale(ROUND_OPTS[1 /* round */]);
}
floor(mod = this.i % this.d) {
if (!mod)
return this;
return this.i >= 0n ? this.trunc() : new _Num(this.#trunc() - 1n, 0n);
floor() {
return this.#setScale(ROUND_OPTS[2 /* floor */]);
}
ceil(mod = this.i % this.d) {
if (!mod)
return this;
return this.i < 0n ? this.trunc() : new _Num(this.#trunc() + 1n, 0n);
ceil() {
return this.#setScale(ROUND_OPTS[3 /* ceil */]);
}
compareTo(other) {
if (this.inf)
return other.inf && this.n > 0 === other.n > 0 ? 0 : this.n > 0 ? 1 : -1;
if (other.inf)
return other.signum() > 0 ? -1 : 1;
this.#alignExponent(other);
return compare(this.i, other.i);
return other.n > 0 ? -1 : 1;
const a = this.n * other.d;
const b = other.n * this.d;
return compare(a, b);
}
toString() {
if (!this.e)
return String(this.i);
let integer = abs(this.i);
if (this.inf)
return this.n > 0 ? "Infinity" : "-Infinity";
const [i, e] = this.#toNum();
if (e >= 0n) {
return String(i * 10n ** e);
}
if (!e)
return String(i);
let integer = abs(i);
const decimal = [];
for (let n = this.e; n < 0; n++) {
for (let n = e; n < 0; n++) {
const last = integer % 10n;

@@ -300,52 +273,51 @@ integer /= 10n;

}
const sign = this.i < 0n ? "-" : "";
const sign = i < 0n ? "-" : "";
return `${sign}${integer}${decimal.length ? `.${decimal.join("")}` : ""}`;
}
#div(divisor, overflow, useFrac) {
if (!divisor.i)
return this.d >= 0 ? INF : N_INF;
if (!this.i)
#setScale(options) {
if (this.inf)
return this;
const frac = Frac.div(this, divisor);
if (frac)
return frac.resolve(overflow, useFrac);
const alignMultiplicand = new _Num(10n ** divisor.#scale(), 0n);
const alignedTarget = this.multiply(alignMultiplicand).#simplify();
const alignedDivisor = divisor.multiply(alignMultiplicand).#simplify();
if (!(alignedTarget.i % alignedDivisor.i)) {
const candidate = new _Num(
alignedTarget.i / alignedDivisor.i,
alignedTarget.e - alignedDivisor.e
);
if (!overflow({
scale: candidate.#scale(),
precision: candidate.#precision()
}))
return candidate;
return _Frac.numOf(...this.#toNum(options));
}
/** Checks whether the this fraction is a finite decimal. */
#finiteDecimal() {
let t = this.d;
for (const n of [1000n, 10n, 5n, 2n]) {
while (t >= n) {
if (t % n)
break;
t /= n;
}
}
const iDivisor = abs(alignedDivisor.#trunc());
let remainder = abs(alignedTarget.i);
const digitExponent = max(length(remainder) - length(iDivisor) + 1n, 0n);
return t === 1n;
}
#toNum(options) {
if (this.inf)
throw new Error("Infinity");
const { n, d } = this;
if (!n)
return [0n, 0n];
if (!options) {
options = this.#finiteDecimal() ? {
overflow: () => false,
roundingMode: 0 /* trunc */
} : {
roundingMode: 0 /* trunc */
};
}
let remainder = abs(n);
const digitExponent = max(length(remainder) - length(d) + 1n, 0n);
const pow = 10n ** digitExponent;
let digits = 0n;
let exponent = digitExponent + alignedTarget.e;
const overflowCtx = {
get scale() {
return -exponent;
},
get precision() {
return length(digits);
}
};
while (remainder > 0n && !overflow(overflowCtx)) {
exponent--;
const numCtx = numberContext(n < 0n ? -1n : 1n, digitExponent, options);
while (remainder > 0n && !numCtx.overflow()) {
numCtx.intVal *= 10n;
numCtx.exponent--;
remainder *= 10n;
digits *= 10n;
if (remainder < iDivisor * pow)
if (remainder < d * pow)
continue;
for (let n = 9n; n > 0n; n--) {
const amount = iDivisor * n * pow;
for (let nn = 9n; nn > 0n; nn--) {
const amount = d * nn * pow;
if (remainder < amount)
continue;
digits += n;
numCtx.intVal += nn;
remainder -= amount;

@@ -355,30 +327,19 @@ break;

}
let lost = !remainder;
while (overflow(overflowCtx) && digits) {
exponent++;
digits /= 10n;
lost = true;
}
if (divisor.signum() !== this.signum())
digits = -digits;
return new _Num(
digits,
exponent,
useFrac && lost ? Frac.valueOf(this, divisor, overflow) : void 0
);
numCtx.round(remainder);
return numCtx.toNum();
}
/** pow() for fraction */
#pow(numerator, denominator, options) {
const sign = numerator >= 0n === denominator >= 0n ? 1n : -1n;
let n = abs(numerator);
let d = abs(denominator);
static #pow(base, num, denom, options) {
if (!num)
return ONE;
if (!base.n)
return ZERO;
const sign = num >= 0n === denom >= 0n ? 1n : -1n;
let n = abs(num);
let d = abs(denom);
const m = n / d;
n %= d;
if (!m && !n)
return ONE;
if (!this.i)
return this;
let a = new _Num(this.i ** m, this.e * m);
let a = new _Frac(base.n ** m, base.d ** m);
if (n % d) {
if (this.i < 0n)
if (base.n < 0n)
return null;

@@ -388,20 +349,15 @@ const g = gcd(n, d);

d /= g;
a = a.multiply(
this.#nthRoot(
new _Num(d, 0n),
parseOFOption(options),
shouldUseFrac(options)
).pow(new _Num(n, 0n))
);
a = a.multiply(_Frac.#nthRoot(base, d, options).pow(_Frac.numOf(n)));
}
if (sign >= 0n)
return a;
return ONE.#div(a, parseOFOption(options), shouldUseFrac(options));
return ONE.divide(a);
}
#nthRoot(n, overflow, useFrac) {
const iN = n.abs().#trunc();
static #nthRoot(base, n, options) {
const iN = abs(n);
const powOfTen = 10n ** iN;
const decimalLength = this.#scale();
const [i, e] = base.#toNum();
const decimalLength = -e;
const mod = decimalLength % iN;
let remainder = this.#simplify().i;
let remainder = i;
if (mod)

@@ -412,16 +368,11 @@ remainder *= 10n ** (iN - mod);

const pow = powOfTen ** digitExponent;
let digits = 0n;
let exponent = digitExponent - decimalLength / iN - (mod ? 1n : 0n);
const overflowCtx = {
get scale() {
return -exponent;
},
get precision() {
return length(digits);
}
};
while (remainder > 0n && !overflow(overflowCtx)) {
exponent--;
const numCtx = numberContext(
1n,
digitExponent - decimalLength / iN - (mod ? 1n : 0n),
options
);
while (remainder > 0n && !numCtx.overflow()) {
numCtx.intVal *= 10n;
numCtx.exponent--;
remainder *= powOfTen;
digits *= 10n;
table.prepare();

@@ -432,143 +383,77 @@ for (let nn = 9n; nn > 0n; nn--) {

continue;
digits += nn;
numCtx.intVal += nn;
remainder -= amount;
table.set(digits);
table.set(numCtx.intVal);
break;
}
}
while (overflow(overflowCtx) && digits) {
exponent++;
digits /= 10n;
}
const a = new _Num(digits, exponent);
if (n.i >= 0n)
numCtx.round(remainder);
const a = _Frac.numOf(...numCtx.toNum());
if (i >= 0n)
return a;
return ONE.#div(a, overflow, useFrac);
return ONE.divide(a);
}
#scale() {
return -this.#simplify().e;
}
#precision() {
let n = this.i;
while (!(n % 10n))
n /= 10n;
return length(n);
}
#simplify() {
if (!this.e)
return this;
const newE = this.e + length(this.i) - this.#precision();
this.#updateExponent(min(newE, 0n));
return this;
}
#trunc() {
return !this.e ? this.i : this.i / this.d;
}
#alignExponent(other) {
if (this.e === other.e)
return;
if (this.e > other.e) {
this.#updateExponent(other.e);
} else {
other.#updateExponent(this.e);
}
}
#updateExponent(exponent) {
if (this.e === exponent)
return;
const diff = this.e - exponent;
if (diff > 0)
this.i *= 10n ** diff;
else
this.i /= 10n ** -diff;
this.e = exponent;
this.d = 10n ** -exponent;
}
static div(dividend, divisor, overflow, useFrac) {
return dividend.#div(divisor, overflow, useFrac);
}
};
var ZERO = new Num(0n, 0n);
var ONE = new Num(1n, 0n);
// src/inf.mts
var Inf = class {
constructor(sign) {
this.inf = true;
this.s = sign;
}
signum() {
return this.s;
}
negate() {
return this.s === 1 ? N_INF : INF;
}
add(augend) {
return !augend.inf || this === augend ? this : null;
}
subtract(subtrahend) {
return this.add(subtrahend.negate());
}
multiply(multiplicand) {
return !multiplicand.signum() ? null : multiplicand.signum() === this.s ? INF : N_INF;
}
divide(divisor) {
return divisor.inf ? null : divisor.signum() >= 0n === this.s >= 0 ? INF : N_INF;
}
modulo() {
return null;
}
pow(n) {
if (n.inf)
return n.s < 0 ? ZERO : INF;
if (!n.signum())
return ONE;
if (n.signum() < 0n)
return ZERO;
if (this.s < 0) {
const hasFrac = n.modulo(ONE).compareTo(ZERO);
if (hasFrac)
return INF;
const binary = !n.modulo(new Num(2n, 0n)).compareTo(ZERO);
if (binary)
return INF;
var ZERO = Frac.numOf(0n);
var ONE = Frac.numOf(1n);
var INF = new Frac(1n, 0n);
var N_INF = new Frac(-1n, 0n);
function parseOptions(options) {
const { overflow, roundingMode } = options ?? {};
return {
overflow: overflow ?? DEF_OPT,
roundingMode: roundingMode ?? 0 /* trunc */
};
}
function numberContext(sign, initExponent, options) {
const { overflow, roundingMode } = parseOptions(options);
const ctx = {
intVal: 0n,
exponent: initExponent,
overflow: () => overflow(overflowCtx),
toNum() {
const intVal = sign >= 0 ? this.intVal : -this.intVal;
return this.exponent >= 0n ? [intVal * 10n ** this.exponent, 0n] : [intVal, this.exponent];
},
round(remainder) {
const nextDigits = [];
while (overflow(overflowCtx) && (ctx.intVal || !nextDigits.length)) {
ctx.exponent++;
nextDigits.push(ctx.intVal % 10n);
ctx.intVal /= 10n;
}
if (roundingMode === 0 /* trunc */)
return;
if (!remainder && !nextDigits.some((r) => r))
return;
switch (roundingMode) {
case 1 /* round */: {
const last = nextDigits.pop();
if (last >= 5n && (sign > 0n || last > 5n || remainder || nextDigits.some((r) => r)))
ctx.intVal++;
break;
}
case 2 /* floor */:
if (sign < 0n)
ctx.intVal++;
break;
case 3 /* ceil */:
if (sign > 0n)
ctx.intVal++;
break;
default:
break;
}
}
return this;
}
sqrt() {
return this.s < 0 ? null : INF;
}
nthRoot(n) {
return n.inf ? ONE : n.compareTo(ONE) === 0 ? this : n.signum() < 0 ? ZERO : INF;
}
scaleByPowerOfTen(n) {
return n.inf ? n.s > 0 ? this : null : this;
}
compareTo(n) {
return n.inf && this.s === n.s ? 0 : this.s > 0 ? 1 : -1;
}
abs() {
return INF;
}
trunc() {
return this;
}
round() {
return this;
}
ceil() {
return this;
}
floor() {
return this;
}
toString() {
return String(this.toNum());
}
toNum() {
return this.s === 1 ? Infinity : -Infinity;
}
};
var INF = new Inf(1);
var N_INF = new Inf(-1);
};
const overflowCtx = {
get scale() {
return -ctx.exponent;
},
get precision() {
return length(ctx.intVal);
}
};
return ctx;
}

@@ -580,3 +465,3 @@ // src/index.mts

return null;
if (value instanceof Num || value instanceof Inf)
if (value instanceof Frac)
return value;

@@ -588,3 +473,5 @@ if (value === Infinity)

const prop = parsePrimValue(value);
return prop && new Num(prop.intValue, prop.exponent ?? 0n);
if (!prop)
return null;
return Frac.numOf(prop.intValue, prop.exponent ?? 0n);
}

@@ -643,4 +530,3 @@ function parsePrimValue(value) {

subtract(subtrahend) {
const b = valueOf(subtrahend).#p;
return this.#val(b && this.#p?.subtract(b));
return this.add(valueOf(subtrahend).negate());
}

@@ -655,5 +541,5 @@ /** Returns a BigNum whose value is (this × multiplicand). */

*/
divide(divisor, options) {
divide(divisor) {
const b = valueOf(divisor).#p;
return this.#val(b && this.#p?.divide(b, options));
return this.#val(b && this.#p?.divide(b));
}

@@ -729,3 +615,3 @@ /**

if (this.#p.inf)
return this.#p.toNum();
return this.#p.signum() > 0 ? Infinity : -Infinity;
const str = this.toString();

@@ -743,3 +629,4 @@ const num = Number(str);

export {
BigNum
BigNum,
RoundingMode
};
{
"name": "@bignum/core",
"version": "0.7.0",
"version": "0.8.0",
"description": "Arbitrary-precision decimal arithmetic with BigInt.",

@@ -5,0 +5,0 @@ "type": "module",

@@ -46,25 +46,6 @@ # @bignum/core

### BigNum.prototype.divide(divisor, [options]): BigNum
### BigNum.prototype.divide(divisor): BigNum
Returns a BigNum whose value is (this / divisor).
An object can be given as an option.
Options:
| Name | Type | Description |
| :---------------------- | :------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
| overflow | `(context)=>boolean` | You can specify an overflow test function. By default, if there are decimals and the number of precisions exceeds 20, it is considered an overflow. |
| ~~maxDp~~ | bigint | **Deprecated**. The maximum number of decimal places. |
| ~~maxDecimalPrecision~~ | bigint | **Deprecated**. The maximum number of precision when having decimals. |
- `context` parameter
An object that contains the following properties:
| Name | Type | Description |
| :-------- | :----- | :---------------------------- |
| scale | bigint | The number of decimal places. |
| precision | bigint | The number of precision. |
### BigNum.prototype.modulo(divisor): BigNum

@@ -78,7 +59,7 @@

### BigNum.prototype.pow(n, [options]): BigNum
### BigNum.prototype.pow(n, [options: MathOption]): BigNum
Returns a BigNum whose value is (this \*\* n).
An object can be given as an option. It's the same option for `divide()`. This is used in negative, or fraction pows.
An object can be given as an option. This is used in negative, or fraction pows. See [MathOption](#type-mathoption).

@@ -89,3 +70,3 @@ ### BigNum.prototype.scaleByPowerOfTen(n): BigNum

### BigNum.prototype.sqrt([options]): BigNum
### BigNum.prototype.sqrt([options: MathOption]): BigNum

@@ -96,5 +77,5 @@ Returns an approximation to the square root of this BigNum.

An object can be given as an option. It's the same option for `divide()`.
An object can be given as an option. See [MathOption](#type-mathoption).
### BigNum.prototype.nthRoot(n, [options]): BigNum
### BigNum.prototype.nthRoot(n, [options: MathOption]): BigNum

@@ -106,3 +87,3 @@ Returns an approximation to the `n`th root of this BigNum.

An object can be given as an option. It's the same option for `divide()`.
An object can be given as an option. See [MathOption](#type-mathoption).

@@ -145,2 +126,29 @@ ### BigNum.prototype.abs(): BigNum

### type MathOption
Options:
| Name | Type | Description |
| :----------- | :---------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------- |
| overflow | `(context)=>boolean` | You can specify an overflow test function. By default, if there are decimals and the number of precisions exceeds 20, it is considered an overflow. |
| roundingMode | [RoundingMode](#enum-roundingmode).trunc` | Specifies a rounding behavior for numerical operations capable of discarding precision. |
- `context` parameter
An object that contains the following properties:
| Name | Type | Description |
| :-------- | :----- | :---------------------------- |
| scale | bigint | The number of decimal places. |
| precision | bigint | The number of precision. |
### enum RoundingMode
The following enumerated values are available:
- `RoundingMode.trunc`
- `RoundingMode.round`
- `RoundingMode.floor`
- `RoundingMode.ceil`
## 🛸 Prior Art

@@ -147,0 +155,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc