3

I can't figure out exactly how these binary matrix files are formatted, other than the 2 little-endian 32-bit unsigned integers in the header. Supposedly the following is a 3x3 identity matrix:

0300 0000 0300 0000 0000 803f 0000 0000
0000 0000 0000 0000 0000 803f 0000 0000
0000 0000 0000 0000 0000 803f 

And the following is a 3x2 matrix with arbitrary numbers whose value I'm not certain of:

0300 0000 0200 0000 0000 803f 0000 4040
0000 a040 0000 0040 0000 8040 0000 c040

Basically, is there an encoding where 0000 803f can translate to a value of 1 while 0000 0000 translates to 0 for each of the matrix values?

2 Answers 2

3

You've correctly identified the first four bytes as the header or matrix shape.

If you were to remove those shape bytes and realign the rest of the hex string, the identify matrix becomes very clear:

0000 803f 0000 0000 0000 0000
0000 0000 0000 803f 0000 0000
0000 0000 0000 0000 0000 803f 

We can easily see here that the text aligns to the shape of an identity matrix, a cell is four bytes, and the value of 0000 803f represents 1.

This just happens to be the IEEE 754 encoding of 1.0. This is either something you can recognise with some experience or have python show you:

In [1]: import struct

In [3]: struct.unpack('f', "0000803f".decode('hex'))
Out[3]: (1.0,)
2
  • 1
    Note that this code implicitly depends on the endianness and size of float of the host system. To always decode little-endian binary32 floats, use the format string '<f' instead of 'f'.
    – Rhymoid
    Nov 12, 2016 at 20:50
  • @Rhymoid +1 however I assumed the code that writes the file does the native as well, so @f is what you'd want.
    – NirIzr
    Nov 12, 2016 at 21:27
2

Oh, I just figured it out. I can interpret each of the following 4 byte values after the header as 32-bit signed floating point values in little-endian format. 0000 803f would be equivalent to 1.0f.

I determined this in node.js using a DataView:

const u = new Uint8Array(4);
const d = new DataView(u.buffer);

u[0] = 0x00;
u[1] = 0x00;
u[2] = 0x80;
u[3] = 0x3f;

// interpret 4 bytes at offset of 0 bytes as little-endian 32-bit float
// DataView.prototype.getFloat32(byteOffset[, littleEndian])
console.log(d.getFloat32(0, true));
// outputs 1
3
  • 1
    Yes. I was just answering that :(
    – NirIzr
    Nov 12, 2016 at 19:53
  • @NirIzr sorry about that. These files were for a class assignment and my professor didn't bother explaining how the files were formatted. You may finish answering and I'll upvote you for the trouble. Nov 12, 2016 at 19:54
  • Yes, I was going to answer anyway, just dropped the 010editor colorful images :P
    – NirIzr
    Nov 12, 2016 at 20:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.