typia
Version:
Superfast runtime validators with only one line
49 lines (48 loc) • 1.9 kB
JavaScript
//#region src/internal/_decimal.ts
const _decimalDecompose = (value) => {
if (Number.isFinite(value) === false) return null;
const [mantissa = "0", exponentText = "0"] = value.toString().split("e");
const negative = mantissa.startsWith("-");
const unsigned = negative ? mantissa.slice(1) : mantissa;
const point = unsigned.indexOf(".");
const decimals = point === -1 ? 0 : unsigned.length - point - 1;
const digits = BigInt(unsigned.replace(".", ""));
return {
coefficient: negative ? -digits : digits,
exponent: Number(exponentText) - decimals
};
};
const _decimalDivide = (value, divisor) => {
const dividend = _decimalDecompose(value);
if (dividend === null || divisor.coefficient === BigInt(0)) return null;
const exponent = dividend.exponent - divisor.exponent;
return exponent >= 0 ? {
numerator: dividend.coefficient * _decimalPower(exponent),
denominator: divisor.coefficient
} : {
numerator: dividend.coefficient,
denominator: divisor.coefficient * _decimalPower(-exponent)
};
};
const _decimalIntegerStep = (value) => {
const decimal = _decimalDecompose(value);
if (decimal === null || decimal.coefficient <= BigInt(0)) return null;
if (decimal.exponent >= 0) return {
coefficient: decimal.coefficient * _decimalPower(decimal.exponent),
exponent: 0
};
const denominator = _decimalPower(-decimal.exponent);
return {
coefficient: decimal.coefficient / _decimalGcd(decimal.coefficient, denominator),
exponent: 0
};
};
const _decimalToNumber = (value) => Number(`${value.coefficient}e${value.exponent}`);
const _decimalPower = (exponent) => BigInt(10) ** BigInt(exponent);
const _decimalGcd = (x, y) => {
while (y !== BigInt(0)) [x, y] = [y, x % y];
return x < BigInt(0) ? -x : x;
};
//#endregion
export { _decimalDecompose, _decimalDivide, _decimalGcd, _decimalIntegerStep, _decimalPower, _decimalToNumber };
//# sourceMappingURL=_decimal.mjs.map