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