Skip to content

Latest commit

Β 

History

History
237 lines (181 loc) Β· 4.71 KB

File metadata and controls

237 lines (181 loc) Β· 4.71 KB

Decimal Arithmetic - Quick Reference Card

πŸ“₯ Import

import { Decimal } from '@/src/utils/arithmetic';
import { formatSorobanValue, toSorobanValue } from '@/src/utils/number_scaler';

🎨 Create Decimals

// From string
const a = Decimal.fromString("123.45", 7);

// From Soroban i128
const b = Decimal.fromSoroban(12345600000n, 7);

// From constructor (scaled integer)
const c = new Decimal("12345600000", 7);

βž• Arithmetic

const a = Decimal.fromString("100", 7);
const b = Decimal.fromString("25", 7);

a.add(b)    // 125
a.sub(b)    // 75
a.mul(b)    // 2500
a.div(b)    // 4

πŸ“Š Comparison

a.equals(b)  // false
a.lt(b)      // false (less than)
a.lte(b)     // false (less than or equal)
a.gt(b)      // true (greater than)
a.gte(b)     // true (greater than or equal)
a.compareTo(b) // 1 (returns -1, 0, or 1)

πŸ’± Conversions

// To Soroban
const soroban = decimal.toSoroban();  // bigint

// Format for display
const ui = decimal.format(2);        // "1,234.56"
const detailed = decimal.format(7);  // "1,234.5600000"

// Get raw value
const raw = decimal.toString();      // "12345600000"

πŸ”§ Utility Functions

// Format Soroban value
formatSorobanValue(12345600000n, 2)  // "1,234.56"

// User input β†’ Soroban
toSorobanValue("123.45")  // 1234500000n

// Percentage
percentageOf(10000000n, "10")  // 1000000n (10% of 1.0)

🎯 Common Patterns

Trade Settlement

const basePrice = Decimal.fromString("1234.56", 7);
const final = basePrice
  .add(Decimal.fromString("0.50", 7))
  .sub(Decimal.fromString("0.23", 7));
console.log(final.format(2));  // "1,234.83"

Accumulate Deposits

let balance = Decimal.fromString("0", 7);
for (const deposit of deposits) {
  balance = balance.add(Decimal.fromString(deposit, 7));
}

Calculate Fee (2.5%)

const amount = Decimal.fromString("100", 7);
const rate = Decimal.fromString("2.5", 7);
const hundred = Decimal.fromString("100", 7);
const fee = amount.mul(rate).div(hundred);

Price Change %

const current = Decimal.fromSoroban(currentPrice, 7);
const previous = Decimal.fromSoroban(previousPrice, 7);
const hundred = Decimal.fromString("100", 7);
const change = current.sub(previous).div(previous).mul(hundred);

🚫 Don't Do This

// ❌ Don't use Number
const bad = Number(value) + Number(other);

// ❌ Don't use toFixed
const bad = value.toFixed(2);

// ❌ Don't mix scales
const a = new Decimal("100", 7);
const b = new Decimal("100", 6);
a.add(b);  // Throws error!

// ❌ Don't divide by zero
a.div(Decimal.fromString("0", 7));  // Throws error!

βœ… Do This Instead

// βœ… Use Decimal
const good = Decimal.fromString(value, 7)
  .add(Decimal.fromString(other, 7));

// βœ… Use format
const good = decimal.format(2);

// βœ… Same scale
const a = new Decimal("100", 7);
const b = new Decimal("100", 7);
a.add(b);  // βœ…

// βœ… Check before divide
if (!divisor.equals(Decimal.fromString("0", 7))) {
  result = dividend.div(divisor);
}

🎨 Component Usage

PayoutBreakdown

<PayoutBreakdown
  basePrice={12345600000n}
  adjustments={[
    { label: "Bonus", amount: 5000000n, type: "addition" },
    { label: "Fee", amount: 2000000n, type: "deduction" }
  ]}
  precision={2}
/>

PricePanel

<PricePanel
  price={12345600000n}
  previousPrice={12000000000n}
  assetName="Coffee Beans"
  precision={2}
/>

πŸ“ Constants

import { SOROBAN_DECIMALS, SOROBAN_SCALE_FACTOR } from '@/src/utils/number_scaler';

SOROBAN_DECIMALS     // 7
SOROBAN_SCALE_FACTOR // 10_000_000

πŸ› Common Errors

"Invalid decimal value"

// ❌ Wrong
new Decimal("12.34", 7)

// βœ… Right
Decimal.fromString("12.34", 7)

"Scale mismatch"

// ❌ Wrong
const a = new Decimal("100", 7);
const b = new Decimal("100", 6);
a.add(b);

// βœ… Right (same scale)
const a = new Decimal("100", 7);
const b = new Decimal("100", 7);
a.add(b);

"Division by zero"

// ❌ Wrong
a.div(Decimal.fromString("0", 7));

// βœ… Right (check first)
const zero = Decimal.fromString("0", 7);
if (!divisor.equals(zero)) {
  result = a.div(divisor);
}

πŸŽ“ Learn More

  • Full Guide: DECIMAL_PRECISION.md
  • Examples: examples/decimal-usage-examples.ts
  • Tests: src/utils/__tests__/arithmetic.test.ts

πŸ§ͺ Test Your Code

npm test arithmetic.test.ts
npm test -- --coverage

πŸŽ‰ Remember

Before: 0.1 + 0.2 = 0.30000000000000004 ❌

After: Decimal.fromString("0.1").add(Decimal.fromString("0.2")).format() = "0.30" βœ…


Keep this card handy while coding! πŸ“Œ