cairo-fp
v1.0.0
Published
Fixed-point math library for Cairo and Starknet
Readme
cairo-fp
A fixed-point math library in 64.64 and 32.32 representation built for Cairo & Starknet.
Credits
This project is a fork and enhancement of Cubit by Unstoppable Games, Inc. The original library laid the foundation for fixed-point arithmetic in Cairo and we are grateful for their pioneering work.
Original Authors: Unstoppable Games, Inc. / Influence
Cubit itself was the successor to cairo-math-64x61.
What's New in cairo-fp
- DeFi Primitives: Interest calculations, AMM pool math, ratio utilities
- Cube Root (
cbrt): Essential for 3-asset pool calculations - Enhanced Precision Tests: DeFi-typical value ranges validated
- Gas Benchmarks: Documented gas costs for all operations
- JavaScript Utilities: Off-chain computation helpers for frontend integration
- Modern Toolchain: Updated for Cairo 2.15+ and Scarb
Installation
Add to your Scarb.toml:
[dependencies]
cairo_fp = { git = "https://github.com/ametel01/cairo-fp" }Fixed-Point Number Formats
| Format | Type | Range | Precision |
|--------|------|-------|-----------|
| 64.64 | f128::Fixed | -2^64 to 2^64 | ~1e-20 |
| 32.32 | f64::Fixed | -2^32 to 2^32 | ~1e-9 |
A signed 64.64-bit fixed-point number is a fraction where the numerator is a signed 128-bit integer and the denominator is 2^64. The denominator is implicit, eliminating storage overhead.
Usage
use cairo_fp::f128::types::fixed::{Fixed, FixedTrait};
// Create fixed-point numbers
let a = FixedTrait::new_unscaled(5, false); // 5.0
let b = FixedTrait::new(9223372036854775808, false); // 0.5 (0.5 * 2^64)
// Arithmetic
let sum = a + b; // 5.5
let product = a * b; // 2.5
let quotient = a / b; // 10.0
// Math functions
let exp_val = a.exp(); // e^5
let ln_val = a.ln(); // ln(5)
let sqrt_val = a.sqrt(); // sqrt(5)
let pow_val = a.pow(b); // 5^0.5Core Library
All functions are available under cairo_fp::f64 or cairo_fp::f128.
Operators
| Operator | Trait |
|----------|-------|
| +, += | Add, AddEq |
| -, -= | Sub, SubEq |
| *, *= | Mul, MulEq |
| /, /= | Div, DivEq |
| ==, != | PartialEq |
| >, >=, <, <= | PartialOrd |
Math Functions (math::ops)
| Function | Description | Gas (f128) |
|----------|-------------|------------|
| ceil | Round up to nearest integer | ~34k |
| floor | Round down to nearest integer | ~34k |
| round | Round to nearest integer | ~34k |
| sqrt | Square root | ~33k |
| cbrt | Cube root | ~217-363k |
| exp | Natural exponential (e^x) | ~176k |
| exp2 | Base-2 exponential (2^x) | ~17k |
| ln | Natural logarithm | ~40k |
| log2 | Base-2 logarithm | ~190k |
| log10 | Base-10 logarithm | ~201k |
| pow | Power function | ~75-362k |
Trigonometry (math::trig)
| Function | Fast Version | Description |
|----------|--------------|-------------|
| sin | sin_fast | Sine |
| cos | cos_fast | Cosine |
| tan | tan_fast | Tangent |
| asin | asin_fast | Inverse sine |
| acos | acos_fast | Inverse cosine |
| atan | atan_fast | Inverse tangent |
Hyperbolic (math::hyp)
sinh,cosh,tanhasinh,acosh,atanh
DeFi Primitives
Interest Calculations (math::interest)
use cairo_fp::f128::math::interest::{compound_interest, continuous_interest, linear_interpolate};
let principal = FixedTrait::new_unscaled(1000, false);
let rate = FixedTrait::new(922337203685477580, false); // 5% = 0.05
let periods = FixedTrait::new_unscaled(12, false);
let amount = compound_interest(principal, rate, periods);AMM Pool Math (math::pool)
use cairo_fp::f128::math::pool::{constant_product_price, liquidity_share, geometric_mean};
let reserve_a = FixedTrait::new_unscaled(1000000, false);
let reserve_b = FixedTrait::new_unscaled(2000000, false);
let price = constant_product_price(reserve_a, reserve_b);
let k = geometric_mean(reserve_a, reserve_b);Ratio Utilities (math::ratio)
use cairo_fp::f128::math::ratio::{proportion, percentage_change, weighted_average};
let change = percentage_change(old_price, new_price);JavaScript Utilities
For frontend integration, use the JS utilities to convert between JavaScript numbers and Cairo fixed-point representation:
import f128 from 'cairo-fp/src/f128/utils.js';
// Convert JS number to Fixed
const fixed = f128.toFixed(3.14159);
// { mag: 57952155664616982739n, sign: false }
// Convert Fixed back to JS number
const num = f128.fromFixed(fixed);
// 3.14159
// DeFi math helpers
const result = f128.exp(0.05); // e^0.05
const sqrt = f128.sqrt(2); // sqrt(2)
const cbrt = f128.cbrt(27); // cbrt(27) = 3Run JS tests:
bun testDevelopment
# Build
scarb build
# Run Cairo tests
snforge test
# Run JS tests
bun testGas Benchmarks
See inline documentation in src/f128/math/defi_precision.cairo and src/f64/math/defi_precision.cairo for detailed gas costs.
License
Original Cubit License: MIT © Unstoppable Games, Inc.
