1

What's the most straightforward way to convert a hex string into a float? (without using 3rd party crates).

Does Rust provide some equivalent to Python's struct.unpack('!f', bytes.fromhex('41973333'))


See this question for Python & Java, mentioning for reference.

Community
  • 1
  • 1
ideasman42
  • 42,413
  • 44
  • 197
  • 320

2 Answers2

5

This is quite easy without external crates:

fn main() {
    // Hex string to 4-bytes, aka. u32
    let bytes = u32::from_str_radix("41973333", 16).unwrap();

    // Reinterpret 4-bytes as f32:
    let float = unsafe { std::mem::transmute::<u32, f32>(bytes) };

    // Print 18.9
    println!("{}", float);
}

Playground link.

mcarton
  • 27,633
  • 5
  • 85
  • 95
4

There's f32::from_bits which performs the transmute in safe code. Note that transmuting is not the same as struct.unpack, since struct.unpack lets you specify endianness and has a well-defined IEEE representation.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Veedrac
  • 58,273
  • 15
  • 112
  • 169
  • 2
    The endianness issue can easily be dealt with with [`{from,to}_{be,le}`](https://doc.rust-lang.org/std/primitive.u32.html#method.from_be). `f32::from_bits` also has the advantage to deal with NaN values correctly. – mcarton Apr 30 '17 at 17:50
  • @mcarton It's not entirely certain that `from_bits` handles NaN more correctly; it's just more conservative. Whether signalling NaNs can actually cause unsafe behaviour is still under debate. – Veedrac Apr 30 '17 at 19:10
  • @mcarton `from_bits` is now exactly equivalent to a `transmute`. https://github.com/rust-lang/rust/pull/46012 – Veedrac Dec 01 '17 at 02:51