1

I am working on transfter an 32bit float number from one platform to the other. Well it is only allowed to pass 16bit unsinged int member to the transfter register. I am thinking that I can then seperate the 32bit float into two 16bit and then conver to 32bit on the other side again.

(I am using C language)

Like:

float A = 3.14
uint16_t B = A & 0xffff;
uint16_t C = A & 0xffff0000;

float D = C<<16 & B;

Obevious this is not correct as float data will be converted to unsigned int when it is assigned. So how shall I do it usually? there shall be some quite mature methods to do similiar thing

Thanks

thundium
  • 995
  • 4
  • 12
  • 30
  • Just to mention some keywords if you want to do some further research: That's called type-punning or reinterpreting. – mafso Sep 24 '14 at 11:25

1 Answers1

5

You can use a union for this, e.g.:

typedef union {
    float f;
    uint16_t a[2];
} U;

U u;

u.f = 3.14f;

printf("%g -> %#x %#x\n", u.f, u.a[0], u.a[1]);

LIVE DEMO

Note: strictly speaking this is undefined behaviour, but it's such a widely used technique that it is unlikely to fail. Alternatively you can take a safer, but potentially somewhat less efficient approach, and just use memcpy, like this:

float f = 3.14f;
uint16_t a[2];
memcpy(a, &f, sizeof(a));
printf("%g -> %#x %#x\n", f, a[0], a[1]);

LIVE DEMO

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • 1
    although this is commonly used it is undefined behaviour to read another union member than the one that was written. – vlad_tepesch Sep 24 '14 at 08:52
  • @vlad_tepesch: yes, thanks, just adding a note about this to the answer. – Paul R Sep 24 '14 at 08:55
  • 2
    Perhaps better use an intermediate uint32_t and manually mask out/merge the 16-bit pieces to help account for byte-order differences. The number is being transferred between "platforms" after all. – doynax Sep 24 '14 at 09:16
  • 2
    The undefined behaviour was just an accident. It was implementation-defined in C90, explicitly undefined in C99, but fixed with TC3 (see [DR 283](http://www.open-std.org/JTC1/SC22/WG14/www/docs/dr_283.htm)) and C11. The standard is a little vague here (there are some links in the similar defect report [DR 236](http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_236.htm) to the committee's discussion, why it's difficult to define it more explicitly), but the intent is quite clear and compilers have always supported it. – mafso Sep 24 '14 at 11:21