0

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
  • 35,906
  • 32
  • 172
  • 287

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
  • 24,420
  • 5
  • 70
  • 79
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
  • 326,504
  • 69
  • 892
  • 1,159
Veedrac
  • 54,508
  • 14
  • 106
  • 164
  • 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