ESC
Type to search...
S
Soli Docs

Decimal Type

Exact decimal arithmetic for financial calculations. Avoid floating-point precision issues with native Decimal support.

Why Decimal?

Floating-point numbers have precision issues:

# Float - imprecise (binary floating point)
let a = 0.1 + 0.2;
print(a);  # 0.30000000000000004 ❌

# Decimal - exact (base-10)
let a: Decimal(2) = 0.10D + 0.20D;
print(a);  # 0.30 ✓

Syntax

let price: Decimal(2) = 19.99D;      # Currency (2 decimals)
let rate: Decimal(4) = 0.0675D;      # Rates (4 decimals)
let percent: Decimal(2) = 50.00D;   # Percentages (2 decimals)
let amount: Decimal(2) = 0.00D;       # Zero with precision

Precision

The number in Decimal(N) specifies fixed decimal places:

Decimal(2)

Currency, dollars/cents

19.99D
Decimal(4)

Rates, percentages

0.0675D
Decimal(0)

Whole numbers only

100.00D

Operations

Operation Example Result
Addition 10.00D + 5.00D 15.00D
Subtraction 10.00D - 5.00D 5.00D
Multiplication 10.00D * 2 20.00D
Division 10.00D / 3 3.33D (rounded)
Modulo 10.00D % 3 1.00D

Precision Methods

let rate: Decimal(4) = 0.0675D;
let rounded: Decimal(2) = rate.prec(2);  # → 0.07D

# Standard library functions
round(19.999D, 2)           # → 20.00D
floor(19.99D)                # → 19.00D
ceil(19.01D)                 # → 20.00D
abs(-19.99D)                 # → 19.99D

Standard Library Functions

# Conversions
decimal("19.99", 2)         # → 19.99D (from string)
float(19.99D)               # → 19.99 (to float)
str(19.99D)                 # → "19.99"

# Math
sqrt(4.00D)                 # → 2.00D
pow(2.00D, 3)               # → 8.00D

# Formatting
format(19.99D, "$#,##0.00")  # → "$19.99"

# Comparisons
min(19.99D, 20.00D)         # → 19.99D
max(19.99D, 20.00D)         # → 20.00D

Financial Example

let price: Decimal(2) = 99.99D;
let tax_rate: Decimal(4) = 0.0800D;
let quantity: Int = 3;

let subtotal: Decimal(2) = price * quantity;
let tax: Decimal(2) = round(subtotal * tax_rate, 2);
let total: Decimal(2) = subtotal + tax;

print("Subtotal: $" + str(subtotal));   # $299.97
print("Tax: $" + str(tax));            # $24.00
print("Total: $" + str(total));        # $323.97

Model Fields

class Product extends Model
    price: Decimal(2),
    cost: Decimal(2),
    tax_rate: Decimal(4),

    def profit -> Decimal(2)
        self.price - self.cost
    end
end

class Order extends Model
    subtotal: Decimal(2),
    tax: Decimal(2),
    total: Decimal(2),

    def calculate_total -> Decimal(2)
        self.subtotal + self.tax
    end
end

Migrations

create_collection("products", [
    {"name": "price", "type": "decimal(2)"},
    {"name": "cost", "type": "decimal(2)"},
    {"name": "discount_rate", "type": "decimal(4)"}
]);

Best Practices

  • Use Decimal(2) for all monetary values
  • Use Decimal(4) for rates and percentages
  • Round final results, not intermediate calculations
  • ✓ class="text-green-400 mt- Specify precision in literals: 100.00D, not 100D