Skip to Content
docs

BigDecimal Reference

AaveKit represents all decimal numbers using the BigDecimal type to ensure high-precision arithmetic for financial computations. Whenever you interact with balances, rates, or amounts in the SDK, they are returned as BigDecimal instances.

import { bigDecimal, BigDecimal, RoundingMode } from "@aave/react";

Key Features

  • Arbitrary precision arithmetic
  • Safe conversion from various numeric types
  • Display formatting with adaptive precision
  • Static utility methods for common operations
  • Type-safe operations that return BigDecimal instances

BigDecimal is immutable: methods always return a new instance. It is based on big.js and behaves the same in Node.js and browsers.

Creating BigDecimals

TypeScript
// From string (recommended for precision)
const a = bigDecimal("123.456789");

// From number
const b = bigDecimal(123.456);

// From bigint
const c = bigDecimal(123456789n);

Arithmetic Operations

All arithmetic operations return new BigDecimal instances, making them safe for immutable workflows.

Addition

TypeScript
const a = bigDecimal("100");
const b = bigDecimal("50");

a.plus(b); // BigDecimal('150')
a.add(b); // Alias for .plus()

Subtraction

TypeScript
const a = bigDecimal("100");
const b = bigDecimal("30");

a.minus(b); // BigDecimal('70')
a.sub(b); // Alias for .minus()

Multiplication

TypeScript
const a = bigDecimal("10");
const b = bigDecimal("5");

a.times(b); // BigDecimal('50')
a.mul(b); // Alias for .times()

Division

TypeScript
const a = bigDecimal("100");
const b = bigDecimal("3");

a.div(b); // BigDecimal('33.333...')

// Division by zero throws
bigDecimal("10").div("0"); // Throws: ±Infinity
bigDecimal("0").div("0"); // Throws: NaN

Modulo

TypeScript
const a = bigDecimal("10");
const b = bigDecimal("3");

a.mod(b); // BigDecimal('1')

Power

TypeScript
const a = bigDecimal("2");

a.pow(3); // BigDecimal('8')
a.pow(-1); // BigDecimal('0.5')

// Range: -1e+6 to 1e+6 inclusive

Square Root

TypeScript
const a = bigDecimal("16");

a.sqrt(); // BigDecimal('4')

// Negative numbers throw
bigDecimal("-1").sqrt(); // Throws: NaN

Absolute Value

TypeScript
const a = bigDecimal("-123.45");

a.abs(); // BigDecimal('123.45')

Negation

TypeScript
const a = bigDecimal("123.45");

a.neg(); // BigDecimal('-123.45')

Comparison Methods

All comparison methods are inherited from big.js:

TypeScript
const a = bigDecimal("100");
const b = bigDecimal("50");

a.gt(b); // true  - greater than
a.gte(b); // true  - greater than or equal
a.lt(b); // false - less than
a.lte(b); // false - less than or equal
a.eq(b); // false - equal to
a.cmp(b); // 1     - compare (-1, 0, or 1)

Rounding & Precision

Rounding Modes

TypeScript
enum RoundingMode {
  Down = 0, // Towards zero (truncate)
  HalfUp = 1, // Nearest neighbor; away from zero if equidistant
  HalfEven = 2, // Nearest neighbor; towards even if equidistant
  Up = 3, // Away from zero
}

Round to Decimal Places

TypeScript
const a = bigDecimal("123.456789");

a.round(2, RoundingMode.HalfUp); // BigDecimal('123.46')
a.round(0, RoundingMode.Down); // BigDecimal('123')
a.round(); // BigDecimal('123') - defaults to 0 dp

Round to Significant Digits

TypeScript
const a = bigDecimal("123.456789");

a.prec(4, RoundingMode.HalfUp); // BigDecimal('123.5')
a.prec(2, RoundingMode.Down); // BigDecimal('120')

Scaling

Multiply by 10^decimals (commonly used for on-chain conversions):

TypeScript
const amount = bigDecimal("1.5");

// Scale up (e.g., ETH to wei)
amount.rescale(18); // BigDecimal('1500000000000000000')

// Scale down (e.g., wei to ETH)
const wei = bigDecimal("1500000000000000000");
wei.rescale(-18); // BigDecimal('1.5')

Display Formatting

Adaptive Precision Display

The toDisplayString method formats numbers based on their magnitude:

TypeScript
const large = bigDecimal("1234.5678");
const small = bigDecimal("0.0001234");

// For numbers >= 1: preserves integer digits, controls decimal precision
large.toDisplayString(6); // '1234.57' (all integer digits + 2 decimals)

// For numbers < 1: uses significant figures
small.toDisplayString(3); // '0.000123' (3 significant figures)

Formatting Options

TypeScript
const num = bigDecimal("123.456789");

// Basic precision
num.toDisplayString(5);
// '123.46'

// With rounding mode
num.toDisplayString(4, { rounding: RoundingMode.Down });
// '123.4'

// With minimum fraction digits
num.toDisplayString(3, { minFractionDigits: 4 });
// '123.4568' (enforces 4 decimal places)

// Trim trailing zeros
num.toDisplayString(10, { trimTrailingZeros: true });
// '123.456789' (no trailing zeros)

// Combined options
bigDecimal("100.5000").toDisplayString(5, {
  minFractionDigits: 2,
  trimTrailingZeros: true,
});
// '100.5' (trimTrailingZeros runs after minFractionDigits, so trailing zeros are removed even below the minimum)

Examples by Number Type

TypeScript
// Large numbers: preserves all integer digits
bigDecimal("1234567.89").toDisplayString(10);
// '1234567.89'

// Small decimals: significant figures
bigDecimal("0.00001234").toDisplayString(3);
// '0.0000123'

// Zero handling
bigDecimal("0").toDisplayString(5);
// '0'

bigDecimal("0").toDisplayString(3, { minFractionDigits: 2 });
// '0.00'

Conversion Methods

To String

TypeScript
const a = bigDecimal("123.456");

a.toString(); // '123.456'
a.toJSON(); // '123.456' (used by JSON.stringify)

a.toFixed(); // '123.456' (fixed-point notation)
a.toFixed(2); // '123.46' (2 decimal places)
a.toFixed(2, RoundingMode.Down); // '123.45' (with rounding mode)

a.toExponential(); // '1.23456e+2'
a.toExponential(2); // '1.23e+2' (2 decimal places)

a.toPrecision(); // '123.456'
a.toPrecision(2); // '1.2e+2' (2 significant digits)
a.toPrecision(4, RoundingMode.Down); // '123.4' (4 sig digits)

To Number (Approximate)

Convert to JavaScript number with safe clamping:

TypeScript
const safe = bigDecimal("123.456");
safe.toApproximateNumber(); // 123.456

// Handles extreme values
const huge = bigDecimal("1e500");
huge.toApproximateNumber(); // Number.MAX_VALUE (clamped)

const tiny = bigDecimal("1e-500");
tiny.toApproximateNumber(); // 0 (subnormal → zero)

const negHuge = bigDecimal("-1e500");
negHuge.toApproximateNumber(); // -Number.MAX_VALUE (clamped)

Use Cases

  • Displaying approximate values in UI
  • Interfacing with APIs requiring number types
  • When precision loss is acceptable

This loses precision. Use BigDecimal operations for exact calculations.

Static Utility Methods

Type Guard

TypeScript
const value: unknown = bigDecimal("123");

if (BigDecimal.isBigDecimal(value)) {
  // value is BigDecimal
  value.plus("10");
}

Min/Max

TypeScript
const a = bigDecimal("100");
const b = bigDecimal("50");
const c = bigDecimal("75");

BigDecimal.min(a, b, c); // BigDecimal('50')
BigDecimal.max(a, b, c); // BigDecimal('100')

// Minimum two arguments required
BigDecimal.min(a, b); // BigDecimal('50')

Best Practices

  1. Use string literals for precision:

    TypeScript
    // Good
    const amount = bigDecimal("0.1");
    
    // Risky (0.1 already has floating-point error)
    const amount = bigDecimal(0.1);
    
  2. Chain operations for clarity:

    TypeScript
    const result = bigDecimal("100")
      .times("1.05") // Apply 5% increase
      .round(2, RoundingMode.HalfUp);
    
  3. Store monetary values as BigDecimal:

    TypeScript
    interface Transaction {
      amount: BigDecimal; // not number
      currency: string;
    }
    
  4. Use toDisplayString() for UI formatting:

    TypeScript
    // Adaptive precision for display
    const formatted = balance.toDisplayString(6);