If you don't want to union it you can pack RGB values into a float using something this, which avoids encountering NANs etc:

Code:

float packARGB(int a, int r, int g, int b)
{
return ldexp(0.5 + r/512.f+ g/131072.f+ b/33554430.f), a>>2);
}
void unpackARGB(float f, int &a, int &r, int &g, int &b)
{
f = frexp(f, a);
a <<= 2;
r = (int)(f*512.f) & 0xFF;
g = (int)(f*131072.f) & 0xFF;
b = (int)(f*33554430.f) & 0xFF;
}

Assuming I got it right (untested code above) it packs the alpha into the exponent, and the rgb into the significand. It drops a few least significant bits here and there (1 of blue and 2 of alpha), but this could be lessened by using the sign bit as well etc.

Edit: It seems that I lost sight of the fact that you want to __start__ with a float, chop that up into ARGB values, and then reconstruct the float out of that. The above code still works great for that, and you can use a huge range of values for the initial float value. It does however mean that you can probably ignore the comment about the sign bit. If your numbers aren't negative then that obviously needn't come into it. You can probably drop the shift left and right on *a* as well.