@hastom/fixed-point
Version:
Light lib for fixed point math made around native bigint
68 lines (67 loc) • 2.31 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.fpFromInt = exports.fpFromDecimal = void 0;
const FixedPoint_1 = require("./FixedPoint");
const math_1 = require("./math");
const pow10 = (base, exp) => base * (10n ** exp);
const numberToDecimalString = (src, precision) => {
if (!Number.isFinite(src)) {
throw Error('Invalid number');
}
let result;
if (Math.log10(src) <= 6) {
result = src.toLocaleString('en', { minimumFractionDigits: precision, useGrouping: false });
}
else if (src - Math.trunc(src) === 0) {
result = src.toLocaleString('en', { maximumFractionDigits: 0, useGrouping: false });
}
else {
throw Error('Not enough precision for a number value. Use string value instead');
}
return result;
};
const fpFromDecimal = (src, dstPrecision) => {
const _dstPrecision = BigInt(dstPrecision);
if (typeof src === 'bigint') {
return new FixedPoint_1.FixedPoint(pow10(src, _dstPrecision), _dstPrecision);
}
let decimalString = typeof src === 'number' ? numberToDecimalString(src, dstPrecision) : src;
let isNegative = false;
while (decimalString.startsWith('-')) {
isNegative = !isNegative;
decimalString = decimalString.slice(1);
}
if (decimalString === '.') {
throw Error('Invalid number');
}
const parts = decimalString.split('.');
if (parts.length > 2) {
throw Error('Invalid number');
}
let whole = parts[0];
let frac = parts[1];
if (!whole) {
whole = '0';
}
if (!frac) {
frac = '0';
}
if (frac.length > dstPrecision) {
throw Error('Invalid number');
}
while (frac.length < dstPrecision) {
frac += '0';
}
let base = pow10(BigInt(whole), _dstPrecision) + BigInt(frac);
if (isNegative) {
base = -base;
}
return new FixedPoint_1.FixedPoint(base, _dstPrecision);
};
exports.fpFromDecimal = fpFromDecimal;
const fpFromInt = (src, srcPrecision, dstPrecision) => {
const _srcPrecision = BigInt(srcPrecision);
const _dstPrecision = BigInt(dstPrecision);
return new FixedPoint_1.FixedPoint((0, math_1.toPrecision)(BigInt(src), _dstPrecision, _srcPrecision), _dstPrecision);
};
exports.fpFromInt = fpFromInt;