nautechsystems/nautilus_trader · error
Overflow when scaling f64 to fixed-point i64
Error message
Overflow when scaling f64 to fixed-point i64
What it means
f64_to_fixed_i64 converts a float to raw fixed-point i64 by first rounding at the requested precision and then multiplying by 10^(FIXED_PRECISION - precision). A checked_mul is used and panics with this message when the scaled value exceeds i64 range. The library prefers a loud panic over silent precision loss.
Source
Thrown at crates/model/src/types/fixed.rs:870
///
/// # Panics
///
/// Panics if `precision` exceeds [`FIXED_PRECISION`], or if scaling the rounded value
/// overflows the raw integer range.
#[must_use]
#[expect(
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
reason = "f64 to fixed-point conversion is inherently lossy; callers validate range and finiteness"
)]
pub fn f64_to_fixed_i64(value: f64, precision: u8) -> i64 {
check_fixed_precision(precision).expect_display(FAILED);
let pow1 = 10_i64.pow(u32::from(precision));
let pow2 = 10_i64.pow(u32::from(FIXED_PRECISION - precision));
let rounded = (value * pow1 as f64).round() as i64;
rounded
.checked_mul(pow2)
.expect("Overflow when scaling f64 to fixed-point i64")
}
/// Converts an `f64` value to a raw fixed-point `i128` representation with a specified precision.
///
/// Callers are expected to validate that `value` is finite and within range; non-finite
/// values saturate at the integer bounds during the float-to-integer cast.
///
/// # Panics
///
/// Panics if `precision` exceeds [`FIXED_PRECISION`], or if scaling the rounded value
/// overflows the raw integer range.
#[must_use]
#[expect(
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
reason = "f64 to fixed-point conversion is inherently lossy; callers validate range and finiteness"
)]
pub fn f64_to_fixed_i128(value: f64, precision: u8) -> i128 {View on GitHub (pinned to 18893faf8b)
Solutions
- Validate |value| * 10^FIXED_PRECISION fits in i64 before calling, or clamp inputs to the representable range.
- Use f64_to_fixed_i128 for large magnitudes.
- Reduce the value magnitude (e.g. express in different units) or lower precision needs.
Example fix
// before
let raw = f64_to_fixed_i64(1e19, 0); // panics
// after
let raw = if value.abs() > f64::from(i64::MAX) / 10f64.powi(FIXED_PRECISION) {
return Err(...);
} else {
f64_to_fixed_i64(value, precision)
}; Defensive patterns
Strategy: validation
Validate before calling
const MAX: f64 = i64::MAX as f64 / 10f64.powi(FIXED_PRECISION); assert!(value.is_finite() && value.abs() <= MAX, "value out of i64 fixed range"); let raw = f64_to_fixed_i64(value, precision);
Type guard
fn fits_i64_fixed(value: f64) -> bool {
value.is_finite() && value.abs() <= i64::MAX as f64 / 10f64.powi(FIXED_PRECISION)
} Prevention
- Validate magnitudes at the ingestion boundary (feeds, CSVs, APIs).
- Use i128 variants for anything that can approach 1e18.
- Add boundary unit tests for the largest values your domain produces.
When it happens
Trigger: Calling f64_to_fixed_i64(value, precision) with a value whose magnitude, after scaling to FIXED_PRECISION raw digits, exceeds i64::MAX/i64::MIN — e.g. f64_to_fixed_i64(1e18, 0) or any value near 9.3e18 with positive precision.
Common situations: Pricing or sizing data loaded from external feeds with unrealistically large magnitudes; unit tests probing the overflow boundary; precision configuration that leaves too little headroom in i64.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Overflow when scaling f64 to fixed-point i128
- Overflow when scaling f64 to fixed-point u64
- Overflow when scaling f64 to fixed-point u128
- Fixed-point scale fits QuantityRaw
- Overflow occurred when multiplying `Quantity`
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/58bd644c03865346.
Report an issue: GitHub.