@0xtorch/big-decimal
Version:
An arbitrary precision Decimal type for TypeScript that extends BigInt.
73 lines • 2.76 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createBigDecimal = void 0;
const createBigDecimal = (value, decimals) => {
if (typeof value === 'string') {
return createBigDecimalFromString(value, decimals);
}
if (typeof value === 'number') {
return createBigDecimalFromString(value.toString(), decimals);
}
return createBigDecimalFromBigint(value, decimals);
};
exports.createBigDecimal = createBigDecimal;
const createBigDecimalFromString = (value, decimals) => {
const splitedValue = value.replaceAll(' ', '').split(/[eE]/);
const baseValue = splitedValue[0];
const exponent = splitedValue[1];
const isNegative = baseValue.startsWith('-');
const absText = isNegative ? baseValue.slice(1) : baseValue;
const numberText = absText
.replaceAll('+', '')
.replaceAll(',', '')
.replaceAll('_', '');
const [intText, decimalText] = numberText.split('.');
const numberRegExp = /^\d+$/;
if (!numberRegExp.test(intText) ||
(decimalText !== undefined &&
decimalText.length > 0 &&
!numberRegExp.test(decimalText))) {
throw new Error(`Invalid decimal format value: ${baseValue}`);
}
const formattedDecimalText = decimalText !== undefined && decimalText.length > 0
? decimalText.replace(/0+$/, '')
: '';
const formattedDecimals = formattedDecimalText.length;
const adjustedDecimalText = adjustDecimalText(decimals, formattedDecimalText, formattedDecimals);
const valueBn = BigInt(`${isNegative ? '-' : ''}${intText}${adjustedDecimalText}`);
const baseDecimals = decimals === undefined ? formattedDecimals : decimals;
if (exponent === undefined) {
return {
value: valueBn,
decimals: baseDecimals,
};
}
const exponentNumber = Number(exponent);
const decimalsWithExponent = baseDecimals - exponentNumber;
return decimalsWithExponent < 0
? {
value: valueBn * 10n ** BigInt(-decimalsWithExponent),
decimals: 0,
}
: {
value: valueBn,
decimals: decimalsWithExponent,
};
};
const adjustDecimalText = (decimals, formattedDecimalText, formattedDecimals) => {
if (decimals === undefined) {
return formattedDecimalText;
}
if (decimals > formattedDecimals) {
return formattedDecimalText.padEnd(decimals, '0');
}
if (decimals < formattedDecimals) {
return formattedDecimalText.slice(0, decimals);
}
return formattedDecimalText;
};
const createBigDecimalFromBigint = (value, decimals) => ({
value,
decimals: decimals ?? 0,
});
//# sourceMappingURL=createBigDecimal.js.map