refactor: replace ignored numeric literals with constants

This commit is contained in:
2026-09-28 16:37:01 +03:00
committed by ksv741
parent a970eaaf7a
commit b78c215ff1
60 changed files with 510 additions and 283 deletions
+37 -21
View File
@@ -1,3 +1,19 @@
export const DECIMAL_RADIX = 10n;
const SIGN_LENGTH = 1;
const NEGATIVE_SIGN = -1n;
const POSITIVE_SIGN = 1n;
const ZERO_UNITS = 0n;
const EQUAL = 0;
const GREATER_THAN = 1;
const LESS_THAN = -1;
const INTEGER_SCALE = 0;
const MIN_WHOLE_DIGITS = 1;
const DIGITS_START = 0;
const PREVIOUS_DIGIT_OFFSET = 1;
const DIGIT_STEP = 1;
const ROUNDING_DIVISOR = 2n;
export type Decimal = { scale: number; value: bigint };
export function decimalFromString(value: string): Decimal {
@@ -6,9 +22,9 @@ export function decimalFromString(value: string): Decimal {
throw new Error('Invalid decimal string');
}
const negative = value.startsWith('-');
const [whole, fraction = ''] = (negative ? value.slice(1) : value).split('.');
const [whole, fraction = ''] = (negative ? value.slice(SIGN_LENGTH) : value).split('.');
return {
value: (negative ? -1n : 1n) * BigInt(`${whole}${fraction}`),
value: (negative ? NEGATIVE_SIGN : POSITIVE_SIGN) * BigInt(`${whole}${fraction}`),
scale: fraction.length,
};
}
@@ -17,8 +33,8 @@ export function add(left: Decimal, right: Decimal): Decimal {
const scale = Math.max(left.scale, right.scale);
return {
value:
left.value * 10n ** BigInt(scale - left.scale) +
right.value * 10n ** BigInt(scale - right.scale),
left.value * DECIMAL_RADIX ** BigInt(scale - left.scale) +
right.value * DECIMAL_RADIX ** BigInt(scale - right.scale),
scale,
};
}
@@ -32,37 +48,37 @@ export function multiply(left: Decimal, right: Decimal): Decimal {
}
export function isZero(value: Decimal): boolean {
return value.value === 0n;
return value.value === ZERO_UNITS;
}
export function compare(left: Decimal, right: Decimal): number {
const difference = subtract(left, right).value;
return difference === 0n ? 0 : difference > 0n ? 1 : -1;
return difference === ZERO_UNITS ? EQUAL : difference > ZERO_UNITS ? GREATER_THAN : LESS_THAN;
}
export function formatDecimal({ value, scale }: Decimal): string {
if (value === 0n) return '0';
const sign = value < 0n ? '-' : '';
if (scale === 0) return `${sign}${value < 0n ? -value : value}`;
const digits = (value < 0n ? -value : value)
if (value === ZERO_UNITS) return '0';
const sign = value < ZERO_UNITS ? '-' : '';
if (scale === INTEGER_SCALE) return `${sign}${value < ZERO_UNITS ? -value : value}`;
const digits = (value < ZERO_UNITS ? -value : value)
.toString()
.padStart(scale + 1, '0');
const whole = digits.slice(0, -scale) || '0';
.padStart(scale + MIN_WHOLE_DIGITS, '0');
const whole = digits.slice(DIGITS_START, -scale) || '0';
const rawFraction = digits.slice(-scale);
let fractionEnd = rawFraction.length;
while (rawFraction.charAt(fractionEnd - 1) === '0') fractionEnd -= 1;
const fraction = rawFraction.slice(0, fractionEnd);
while (rawFraction.charAt(fractionEnd - PREVIOUS_DIGIT_OFFSET) === '0') fractionEnd -= DIGIT_STEP;
const fraction = rawFraction.slice(DIGITS_START, fractionEnd);
const fractionalPart = fraction ? '.' + fraction : '';
return `${sign}${whole}${fractionalPart}`;
}
// Round half away from zero; callers choose presentation precision explicitly.
export function divide(left: Decimal, right: Decimal, scale: number): Decimal {
if (right.value === 0n) throw new Error('Division by zero');
const numerator = left.value * 10n ** BigInt(right.scale + scale);
const denominator = right.value * 10n ** BigInt(left.scale);
const sign = (numerator < 0n) !== (denominator < 0n) ? -1n : 1n;
const n = numerator < 0n ? -numerator : numerator;
const d = denominator < 0n ? -denominator : denominator;
return { value: sign * ((n + d / 2n) / d), scale };
if (right.value === ZERO_UNITS) throw new Error('Division by zero');
const numerator = left.value * DECIMAL_RADIX ** BigInt(right.scale + scale);
const denominator = right.value * DECIMAL_RADIX ** BigInt(left.scale);
const sign = (numerator < ZERO_UNITS) !== (denominator < ZERO_UNITS) ? NEGATIVE_SIGN : POSITIVE_SIGN;
const n = numerator < ZERO_UNITS ? -numerator : numerator;
const d = denominator < ZERO_UNITS ? -denominator : denominator;
return { value: sign * ((n + d / ROUNDING_DIVISOR) / d), scale };
}