convert binary floating and doubles in IEEE-754 format.

Hi. I’m new to elixir, so this could be obvious. I’m reading and writing to a device that uses a binary line format. The format is fixed. It also has integer fields, but they are easy to interpret. Floats and doubles are a bit harder, so I’m wondering and hoping that this is a problem that’s already been solved.

Here’s an example of what I’m looking at:

SSSSSSSSSSSSIIIIIIIIFFFFDDDDDDDD

Where S…S is a string descriptor.
IIII is an integer that I unpack with ((i1 <<< 32) + (i2 <<< 16) + (i3 <<< 8) + i4)

The ones I’m struggling with are FFFF (32 bit float) and DDDDDDDD (double prec float).

I know I can look at the IEEE-754 spec and figure this out, but I’m thinking there might be a solution already. For example in python given the FFFF, I can use struct.unpack(FFFF) to get the floating point value.

This should totally do it for you, unless you have to deal with NaN and infinties…

iex(1)> bin = <<1.22::float>>         
<<63, 243, 133, 30, 184, 81, 235, 133>>
iex(2)> <<x :: float>> = bin
<<63, 243, 133, 30, 184, 81, 235, 133>>
iex(3)> x
1.22
iex(4)> bin = <<1.22::float-size(32)>>
<<63, 156, 40, 246>>
2 Likes

Thanks. That’s just what I was looking for. NaN and infinity should be caught before they get on the line, so I think we’re good.

Just remember that binary pattern matching also supports integers, so instead of manual addition and shifts you can do:

<<describe::binary-size(12), i1::little-integer-32, i2::little-integer-32, f1::float-32, f2::float-64>> = input

That is why I love working with binary data in Erlang. It is just so enormously easy.

5 Likes

Thank you very much. That’s very helpful.

probably not an issue, but if things go south don’t forget to check the endianness (there are extra decorators for that if you need it).

1 Like

I figured out I needed big-integer instead of little. Is there a good list of all the decorators? I looked briefly and didn’t find one.

It is in docs for <<>>/1.

2 Likes