Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I decode f16 to f32 using only the stable standard library?

I need to convert stored half floats (16 bit) to standard 32 bit floats. I currently use the code below, but it relies on libc. I want to use only std and it should work on stable Rust.

#[inline]
fn decode_f16(half: u16) -> f32 {
    let exp: u16 = half >> 10 & 0x1f;
    let mant: u16 = half & 0x3ff;
    let val: f32 = if exp == 0 {
        ffi::c_ldexpf(mant as f32, -24)
    } else if exp != 31 {
        ffi::c_ldexpf(mant as f32 + 1024f32, exp as isize - 25)
    } else if mant == 0 {
        ::std::f32::INFINITY
    } else {
        ::std::f32::NAN
    };
    if half & 0x8000 != 0 {
        -val
    } else {
        val
    }
}
like image 630
Pyfisch Avatar asked Mar 15 '16 10:03

Pyfisch


1 Answers

You can just replace ffi::c_ldexpf(x, y) with x * (2.0).powi(y). This works on all u16s, according to my exhaustive test.

like image 102
Veedrac Avatar answered Oct 22 '22 16:10

Veedrac