0

I need to break down a 32bit float variable (IEEE 754) into 4 bytes, to send them out via MODBUS. I need to maintain the same bitwise structure as with IEEE 754 standard, I just want that structure sliced in 4 bytes.

My first thought was to use the bit shift operator:

*word_1_h = (uint8_t) (number>>8) & 0xFF;
*word_1_l = (uint8_t) number> & 0xFF;
*word_2_h = (uint8_t) (number>>24) & 0xFF;
*word_2_l = (uint8_t) (number>>16) & 0xFF;

However the compiler returned an error:

error: invalid operands to binary >> (have 'float' and 'int')

Then I tried a different approach:

{
    if(float & (1<<cnt)) 32bit_int |= (1<<cnt);
    else 32bit_int &= ~(1<<cnt);
}

This also threw an error:

error: invalid operands to binary & (have 'float' and 'int')

This is my function:

void MIC488_LL_float_splice(float number, uint8_t * word_1_h, uint8_t * word_1_l, uint8_t * word_2_h, uint8_t * word_2_l)
{
    //Konwersja 2 rejestrów (4 bajty) na liczbę 32 bitową (DINT, DWORD, FLOAT).
    //RejestrX HI <-> Bajt1
    //RejestrX LO <-> Bajt0
    //RejestrX+1 HI <-> Bajt3
    //RejestrX+1 LO <-> Bajt2

    //Liczba_32_bit = Bajt3<<24 + Bajt2<<16 + Bajt1<<8 + Bajt0
    //lub Liczba_32_bit = RejestrX + Rejestr(X + 1)<<16
    //uint32_t temp = 0;

    /*for(uint8_t cnt=0;cnt<32;cnt++)
    {
        if(number & (1<<cnt)) temp |= (1<<cnt);
        else temp &= ~(1<<cnt);
    }*/

    *word_1_h = (uint8_t) (number>>8) & 0xFF;
    *word_1_l = (uint8_t) number> & 0xFF;
    *word_2_h = (uint8_t) (number>>24) & 0xFF;
    *word_2_l = (uint8_t) (number>>16) & 0xFF;
}

So in result I can't convert the float to a binary variable. Is there any sensible way to do this?

Marek Ant
  • 67
  • 7

1 Answers1

2

Type float per se does not support bit shift operators; they are defined for integral types only.

You can, however, define a union-type such that a float type and an uint8_t-array get placed on the same memory location:

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>

typedef union {
    float floatValue;
    uint8_t bin[sizeof(float)];
} floatOrBytes_t;

int main() {

    floatOrBytes_t f;
    f.floatValue = 3.15;
    for (size_t i = 0; i<sizeof(f.bin); i++) {
        uint8_t val = f.bin[i];
        printf("(%zu):%" PRIu8 "\n",i,val);
    }
    return 0;
}
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58