Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get float in bytes?

I am using the HIDAPI to send some data to a USB device. This data can be sent only as byte array and I need to send some float numbers inside this data array. I know floats have 4 bytes. So I thought this might work:

float f = 0.6;
char data[4];

data[0] = (int) f >> 24;
data[1] = (int) f >> 16;
data[2] = (int) f >> 8;
data[3] = (int) f;

And later all I had to do is:

g = (float)((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]) );

But testing this shows me that the lines like data[0] = (int) f >> 24; returns always 0. What is wrong with my code and how may I do this correctly (i.e. break a float inner data in 4 char bytes and rebuild the same float later)?


EDIT:

I was able to accomplish this with the following codes:

float f = 0.1;
unsigned char *pc;
pc = (unsigned char*)&f;

// 0.6 in float
pc[0] = 0x9A;
pc[1] = 0x99;
pc[2] = 0x19;
pc[3] = 0x3F;

std::cout << f << std::endl; // will print 0.6

and

*(unsigned int*)&f = (0x3F << 24) | (0x19 << 16) | (0x99 << 8) | (0x9A << 0);

I know memcpy() is a "cleaner" way of doing it, but this way I think the performance is somewhat better.

like image 794
Michel Feinstein Avatar asked Jan 08 '14 20:01

Michel Feinstein


People also ask

Is float always 4 bytes?

Yes it has 4 bytes only but it is not guaranteed.

Why size of float is 4 bytes?

The size of a float or other data types for that matter is dependent upon the system. It has to do with the hardware architecture and the compiler. This float, 10498.429 , would also be 4 bytes in memory. If a given computer system had a float size of 4 bytes then all floats are 4 bytes.


1 Answers

You can do it like this:

char data[sizeof(float)];


float f = 0.6f;

memcpy(data, &f, sizeof f);    // send data


float g;

memcpy(&g, data, sizeof g);    // receive data

In order for this to work, both machines need to use the same floating point representations.


As was rightly pointed out in the comments, you don't necessarily need to do the extra memcpy; instead, you can treat f directly as an array of characters (of any signedness). You still have to do memcpy on the receiving side, though, since you may not treat an arbitrary array of characters as a float! Example:

unsigned char const * const p = (unsigned char const *)&f;
for (size_t i = 0; i != sizeof f; ++i)
{
    printf("Byte %zu is %02X\n", i, p[i]);
    send_over_network(p[i]);
}
like image 101
Kerrek SB Avatar answered Oct 06 '22 18:10

Kerrek SB