Search code examples
rusttype-conversion

What is the correct way to convert an i128 to an f64


I would like to convert an i128 to an f64.

I know that I can silently cast with as.

let nb: i128 = 1337;
let converted = nb as f64;

But it doesn't give me the opportunity to handle any error.

Is there a way to do something similar to

let nb: i128 = 1337;
let converted: f64 = nb.try_into()?;

Where I can handle the error, if the converted value doesn't fit into an f64 ?


Solution

  • There is no standard f64::try_from(i128).
    You can make your own function relying on a check after the reciprocal as coercion.

    fn try_to_f64(v: i128) -> Result<f64, &'static str> {
        let attempt = v as f64;
        (attempt as i128 == v)
            .then_some(attempt)
            .ok_or("precision loss in i128 to f64 conversion")
    }
    
    fn main() {
        for v in [
            123_456_789,
            123_456_789_123,
            123_456_789_123_456,
            123_456_789_123_456_789,
        ] {
            println!("{} ~~> {:?}", v, try_to_f64(v));
        }
    }
    /*
    123456789 ~~> Ok(123456789.0)
    123456789123 ~~> Ok(123456789123.0)
    123456789123456 ~~> Ok(123456789123456.0)
    123456789123456789 ~~> Err("precision loss in i128 to f64 conversion")
    */