1

I am writing a C program that communicates over modbus TCP. I send the float 3.14 on my modbus client, with a hexadecimal representation of 0x4048F5C3. My C code is correctly receiving the modbus packet, and now I just need to reinterpret the unsigned char *buffer as a float so I can get the value 3.14. Here is my code

int main()
{
    setup_modbus_tcp();
    unsigned char buffer[4] = { 0x00, 0x00, 0x00, 0x00 };
    get_modbus_data(buffer, 4);
        //Buffer now holds { 0x40, 0x48, 0xF5, 0xC3 };
    float value = *(float *)buffer;
        //value is now -490.564453
}

Now, I can tell that this problem is because of endianness, because if I swap endianness so that the buffer looks like this:

{ 0xC3, 0xF5, 0x48, 0x40 };

then everything works fine. But this feels a little bit messy. Do I have to swap endianness? Or is there a way that I can specify endianness when I do:

float value = *(float *)buffer;
DJMcMayhem
  • 7,285
  • 4
  • 41
  • 61
  • Either you have to swap all bytes or you send the float as a printed ASCII string. – Paul Ogilvie Apr 11 '16 at 15:21
  • Even after byte-swapping: Are you shure the representation is identical? – too honest for this site Apr 11 '16 at 15:28
  • @Olaf Yes, after byte swapping, it's definitely correct. There is a minor difference because of floating point precision, but other than that it's right. – DJMcMayhem Apr 11 '16 at 17:14
  • Either the encoding is the same or not. If they are the same, they have the same precision, otherwise they have a different encoding. Mind that C does not enforce a specific floating point format/encoding, but only defines relevant decimal paramters. – too honest for this site Apr 11 '16 at 17:21

1 Answers1

2

The buffer must be handled manually, this includes changes to endianness. A function can always be used that converts the buffer to a floating point format.

float value = Convert( buffer );

To add, you way of converting the buffer is incorrect:

float value = *(float *)buffer;

An array of unsigned chars cannot be simply to a float type, as it causes undefined behavior. The memory must be copied to an object of type float:

float value;
memcpy( &value , buffer , sizeof( value ) );  //assumes endianness has already been handled
2501
  • 25,460
  • 4
  • 47
  • 87