Union - convert int to Float

Hi,
Not sure what is happening, but i am tryign to convert int values to float using union with the following code:

#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>

float tmpfloat;

union u_tag {
int b[2];
float fval;
} u;

void setup()
{   Serial.begin(9600);     // TX0/RX0 serial monitor
}

void loop() { 

    u.b[0] = 12456;
    u.b[1] = 3652;
       
    tmpfloat = u.fval;

    Serial.println("Result Converted to Float: ");
    Serial.println(u.b[0]);
    Serial.println(u.b[1]);
    Serial.println(tmpfloat);

  delay(5000);

}

But the printout result of the Serial.println(tmpfloat) as following:

Result Converted to Float: 
12456                 
3652
0.00                         //Note: this is the result of Serial.println(tmpfloat);

Any idea why this is happening, what is wrong with how i am using union or Serial.print?

You cannot just stick a couple of ints together and expect a float to come out, sadly, it doesn’t work that way. :cry:

The Arduino reference has a page about floats at Arduino Reference, you might find it “interesting” reading – floats can be difficult to understand.

To convert an integer to a float is easy:

void setup() {
    int fred = 12345;
    float wilma = (float)fred;

   Serial.begin(9600);
   Serial.println(fred);
   Serial.println(wilma);
}

void loop() {
}

The output will be:

12345
12345.00

What exactly are you trying to achieve? I suspect you want to set up the union with 12456 and 3652 in the int part, and get a float of 12456.3652 out as the float? If so, that’s unfortunately never going to give you what you want, the internal representation of an int and a float are completely different.

Demo:

void setup() {
  int hiPart = 12456;
  int loPart = 3652;
  union {
    float f;
    byte i[4];
  } both;

  both.f = 12456.3652;

  Serial.begin(9600);
  Serial.println(hiPart, HEX);
  Serial.println(loPart, HEX);

  for (byte j = 0; j < 4; j++)
    Serial.print(both.i[j], HEX);

  Serial.println();
}

void loop() {
}

Result:

30A8
E44
76A14246

So you can see, the internals of the two integers and the “desired” float are not even slightly the same.

I think the Arduino uses IEEE 32 bit floats, have a look at IEEE 754 - Wikipedia for details of that number format and you will see it’s not so simple as jamming a couple of ints together. Sorry.

HTH

Cheers,
Norm.

1 Like

Hi Norm,

Thanks for the answer i will give it a try.
What i am trying to do is to read 2 Modbus registers and convert the stored values combined into a float.
the strange thing that it is working fine with Arduino in Arduino IDE.
But getting Zero using values as i showed up with TI TM4C board and Platform IO, not sure why, but will try your suggestion and share the result afterwards.

Regards,

Hi Norm,

I figured how to make union work, in the union definition, change int b[2] to uint16_t b[2] and it will give readings, the problem it seems that if you define type as int, it will not be 16 bit which will cause the problem.

so the union should be like this:

union u_tag {
uint16_t b[2];
float fval;
} u;

Regards,

You can do this too to ensure 16 bit integers:

#include <stdint.h> at the top of the sketch.

union u_tag {
  int16_t b[2];
  float fval;
} u;

If you need unsigned instead, use uint16_t.

However, given how a float is stored in the variable fval, I’m surprised that you are getting any valid results. Unless, of course, the two ints being returned from the Modbus are actually not ints at all but two halves of the flosting point value.

Cheers,
Norm.