using combining is clean and easy
union
{
float f;
unsigned int ul;
unsigned char uc [4];
} myfloatun;
myfloatun.f = somenum;
printf ("0x% 08X \ n", myfloatun.ul);
Much safer from a compiler point of view than pointers. Memcpy works great too.
EDIT
Good, good, here are full-featured examples. Yes, you should use unions with caution if you do not follow how this compiler allocates the union and the pads or evens out that it can break, and therefore some / many say it is dangerous to use unions in this way. However, are alternatives considered safe?
Doing some C ++ readings has its problems with unions, and unification may very simply not work. If you really meant C ++, not C, this is probably bad. If you said kleenex and meant fabrics, then this might work.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef union
{
float f;
unsigned char uc [4];
} FUN;
void charRepresentation (unsigned char * uc, float f)
{
Fun fun;
fun.f = f;
uc [0] = fun.uc [3];
uc [1] = fun.uc [2];
uc [2] = fun.uc [1];
uc [3] = fun.uc [0];
}
void floatRepresentation (unsigned char * uc, float * f)
{
Fun fun;
fun.uc [3] = uc [0];
fun.uc [2] = uc [1];
fun.uc [1] = uc [2];
fun.uc [0] = uc [3];
* f = fun.f;
}
int main ()
{
unsigned int ra;
float test;
char result [4];
Fun fun;
if (sizeof (fun)! = 4)
{
printf ("It aint gonna work! \ n");
return (1);
}
test = 4.7567F;
charRepresentation (result, test);
for (ra = 0; ra <4; ra ++) printf ("0x% 02X", (unsigned char) result [ra]); printf ("\ n");
test = 1.0F;
charRepresentation (result, test);
for (ra = 0; ra <; ra ++) printf ("0x% 02X", (unsigned char) result [ra]); printf ("\ n");
test = 2.0F;
charRepresentation (result, test);
for (ra = 0; ra <4; ra ++) printf ("0x% 02X", (unsigned char) result [ra]); printf ("\ n");
test = 3.0F;
charRepresentation (result, test);
for (ra = 0; ra <4; ra ++) printf ("0x% 02X", (unsigned char) result [ra]); printf ("\ n");
test = 0.0F;
charRepresentation (result, test);
for (ra = 0; ra <4; ra ++) printf ("0x% 02X", (unsigned char) result [ra]); printf ("\ n");
test = 0.15625F;
charRepresentation (result, test);
for (ra = 0; ra <4; ra ++) printf ("0x% 02X", (unsigned char) result [ra]); printf ("\ n");
result [0] = 0x3E;
result [1] = 0xAA;
result [2] = 0xAA;
result [3] = 0xAB;
floatRepresentation (result, & test);
printf ("% f \ n", test);
return 0;
}
And the result looks like this:
gcc fun.c -o fun
./fun
0x40 0x98 0x36 0xE3
0x3F 0x80 0x00 0x00
0x40 0x00 0x00 0x00
0x40 0x40 0x00 0x00
0x00 0x00 0x00 0x00
0x3E 0x20 0x00 0x00
0.333333
You can check manually or look at this website, since I took examples directly from it, the result is as expected.
http://en.wikipedia.org/wiki/Single_precision
What you never want to do is point to a memory with a pointer to look at it with a different type. I never understood why this practice is used so often, especially for structures.
int broken_code (void)
{
float test;
unsigned char * result
test = 4.567;
result = (unsigned char *) & test;
// do something with result here
test = 1.2345;
// do something with result here
return 0;
}
This code will work 99% of the time, but not in 100% of cases. It will fail when you least expect it and at the worst of times, like the day after your most important customer receives it. Its an optimizer that eats your lunch with this coding style. Yes, I know that most of you do this, and they have been taught and probably never burned ... It just makes him more painful when he finally happens, because now you know that he can and failed (with popular compilers like gcc on regular computers like PCs).
After this method failed when using this method to test fpu, programmatically creating specific floating point numbers / patterns, I switched to an allied approach, which so far has never worked. By definition, elements in a union have the same piece of storage, and the compiler and optimizer are not confused with respect to two elements in this shared storage that ... are in the same shared storage. Using the code above, you rely on the assumption that non-register memory is saved for each use of the variables, and all variables are written back to this memory before the next line of code. Great if you never optimize or use a debugger. The optimizer in this case does not know that the result and the test have the same piece of memory, and this is the root of the problem / error. To make a game with a pointer, you have to fall into anything, like a union, you still need to know how the compiler aligns and pillows, you still have to deal with content.
The problem is that the compiler does not know that two elements have the same memory space. For a specific trivial example above, I observed how the compiler optimizes the assignment of a number to a floating point variable, since this value / variable is never used. The address for storing this variable is used, and if you tell printf the result data *, the compiler will not optimize the result pointer and thus will not optimize the address for testing, and thus will not optimize the storage for the test, but in this simple example it may have happened when the numbers 4.567 and 1.2345 never get into the compiled program. I also see that the compiler allocates storage for the test, but assigns numbers to the floating-point register, and then never uses this register and does not copy the contents of this register to the storage that it assigned. The reasons why this is unsuccessful for less trivial examples may be more difficult to fulfill, which is often associated with the allocation and eviction of registers, changing the line of code and its operation, changing the other and breaking it.
Memcpy,
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void charRepresentation (unsigned char * uc, float * f)
{
memcpy (uc, f, 4);
}
void floatRepresentation (unsigned char * uc, float * f)
{
memcpy (f, uc, 4);
}
int main ()
{
unsigned int ra;
float test;
unsigned char result [4];
ra = 0;
if (sizeof (test)! = 4) ra ++;
if (sizeof (result)! = 4) ra ++;
if (ra)
{
printf ("It aint gonna work \ n");
return (1);
}
test = 4.7567F;
charRepresentation (result, & test);
printf ("0x% 02X", (unsigned char) result [3]);
printf ("0x% 02X", (unsigned char) result [2]);
printf ("0x% 02X", (unsigned char) result [1]);
printf ("0x% 02X \ n", (unsigned char) result [0]);
test = 0.15625F;
charRepresentation (result, & test);
printf ("0x% 02X", (unsigned char) result [3]);
printf ("0x% 02X", (unsigned char) result [2]);
printf ("0x% 02X", (unsigned char) result [1]);
printf ("0x% 02X \ n", (unsigned char) result [0]);
result [3] = 0x3E;
result [2] = 0xAA;
result [1] = 0xAA;
result [0] = 0xAB;
floatRepresentation (result, & test);
printf ("% f \ n", test);
return 0;
}
gcc fcopy.c -o fcopy
./fcopy
0x40 0x98 0x36 0xE3
0x3E 0x20 0x00 0x00
0.333333
I'm going to deal with the burning ones with my comments and depending on which side of the argument you decide to be included. Memcpy is probably your safest route. You still need to know the compiler well and manage your content. The compiler should not spoil memcpy, it should store registers in memory before calling and execute in order.