Search code examples
rustcastingfloating-pointtype-conversion

How to convert a `f64` to a `f32`?


How can I convert a f64 into the closest f32?

There is neither a From nor a TryFrom implementation, presumably because such implementations are only provided for lossless conversions. I also searched for references to f32 in the f64 docs and vice versa, and found nothing.

    let double: f64 = 0.;

    // doesn't work
    // let single: f32 = double.into();
    // let single: f32 = double.try_into().unwrap();

Solution

  • In this case, we can use the as keyword for casting. It is usually not desired for integer conversions because "casting from a larger integer to a smaller integer (e.g. u32 -> u8) will truncate", and this is usually not wanted. For f64 to f32, however, it's very sensible:

    Casting from an f64 to an f32 will produce the closest possible f32

    • if necessary, rounding is according to roundTiesToEven mode
    • on overflow, infinity (of the same sign as the input) is produced

    Rust Reference

        let double: f64 = 42.;
        dbg!(double as f32);
    
    [src/main.rs:13] double as f32 = 42.0
    

    If an overflow to infinity is not desired and you want to panic instead, the simplest solution might be to check for is_finite:

    fn f64_to_f32(x: f64) -> f32 {
        let y = x as f32;
        assert_eq!(
            x.is_finite(),
            y.is_finite(),
            "f32 overflow during conversion"
        );
        y
    }
    
    fn main() {
        dbg!(f64_to_f32(42_f64));
        // dbg!(f64_to_f32(f64::MAX / 10.)); // panics
        dbg!(f64_to_f32(f64::NAN));
        dbg!(f64_to_f32(f64::INFINITY));
        dbg!(f64_to_f32(f64::NEG_INFINITY));
    }
    
    [src/main.rs:2] f64_to_f32(42_f64) = 42.0
    [src/main.rs:4] f64_to_f32(f64::NAN) = NaN
    [src/main.rs:5] f64_to_f32(f64::INFINITY) = inf
    [src/main.rs:6] f64_to_f32(f64::NEG_INFINITY) = -inf