nautechsystems/nautilus_trader · error
Overflow when scaling f64 to fixed-point u64
Error message
Overflow when scaling f64 to fixed-point u64
What it means
f64_to_fixed_u64 converts a non-negative float to raw fixed-point u64, scaling the rounded value by 10^(FIXED_PRECISION - precision). The checked_mul panics with this message when the scaled value exceeds u64::MAX. Callers must ensure the value is finite and non-negative and within range.
Source
Thrown at crates/model/src/types/fixed.rs:921
/// # 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,
clippy::cast_sign_loss,
reason = "f64 to fixed-point conversion is inherently lossy; callers validate range and finiteness"
)]
pub fn f64_to_fixed_u64(value: f64, precision: u8) -> u64 {
check_fixed_precision(precision).expect_display(FAILED);
let pow1 = 10_u64.pow(u32::from(precision));
let pow2 = 10_u64.pow(u32::from(FIXED_PRECISION - precision));
let rounded = (value * pow1 as f64).round() as u64;
rounded
.checked_mul(pow2)
.expect("Overflow when scaling f64 to fixed-point u64")
}
/// Converts an `f64` value to a raw fixed-point `u128` representation with a specified precision.
///
/// Callers are expected to validate that `value` is finite and non-negative; non-finite
/// and negative 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,
clippy::cast_sign_loss,
reason = "f64 to fixed-point conversion is inherently lossy; callers validate range and finiteness"
)]View on GitHub (pinned to 18893faf8b)
Solutions
- Pre-check that value * 10^FIXED_PRECISION fits in u64 and reject or clamp otherwise.
- Use f64_to_fixed_u128 for larger magnitudes.
- Route values that can be negative through the signed variant f64_to_fixed_i64 instead.
Example fix
// before let raw = f64_to_fixed_u64(huge_value, precision); // panics // after let max = u64::MAX as f64 / 10f64.powi(FIXED_PRECISION); assert!(value.is_finite() && value >= 0.0 && value <= max); let raw = f64_to_fixed_u64(value, precision);
Defensive patterns
Strategy: validation
Validate before calling
const MAX: f64 = u64::MAX as f64 / 10f64.powi(FIXED_PRECISION); assert!(value.is_finite() && (0.0..=MAX).contains(&value)); let raw = f64_to_fixed_u64(value, precision);
Type guard
fn fits_u64_fixed(value: f64) -> bool {
value.is_finite() && (0.0..=u64::MAX as f64 / 10f64.powi(FIXED_PRECISION)).contains(&value)
} Prevention
- Ensure negative values go to the signed (i64) conversion path, never the unsigned one.
- Clamp cumulative totals before converting.
- Unit-test the exact overflow threshold for your precision settings.
When it happens
Trigger: Calling f64_to_fixed_u64 with a value whose scaled magnitude exceeds u64::MAX (~1.8e19 at precision 0); the dedicated test test_f64_to_fixed_u64_overflow_panics exercises exactly this.
Common situations: Large unsigned quantities from feeds or computed values (e.g. cumulative volumes in base units), or accidental negative/infinite values cast to u64 before the multiplication overflow check.
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 i64
- Overflow when scaling f64 to fixed-point i128
- 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/7d0a8ab5e8baf546.
Report an issue: GitHub.