On 4 May 2004, Mike wrote:
I am trying to calculate a 32bit float value from 4 int values.
I sucessfully calcluated a 32bit long value:
LONG l32BitData = pData[3];
l32BitData <<= 8;
l32BitData |= (byte)pData[2];
l32BitData <<= 8;
l32BitData |= (byte)pData[1];
l32BitData <<= 8;
l32BitData |= (byte)pData[0];
But when I use type casting I (unsuprisingly) get the wrong value of
float.
Does anyone know a good way of calculating this? An IntToFloat()
function would be perfect or a description of the steps required to
calculate this. I have read how to calculate an intiger value from a
float but the required maths to do the reverse is beyond me.
You mean like the intBitsToFloat method in Java?
#include <math.h>
#define BITS_MANT 23
#define BITS_EXP 8
#define MASK_EXP ((1UL<<BITS_EXP )-1)
#define MASK_MANT ((1UL<<BITS_MAN T)-1)
#define MASK_S (1UL<<BITS_EXP+ BITS_MANT)
#define MINEXP 0
#define MAXEXP ((1UL<<BITS_EXP )-1)
#define HIDDEN_BIT (1UL<<BITS_MANT )
#define MAGIC_EXP (MAXEXP/2+BITS_MANT)
float ulongBitsToFloa t(unsigned long v) {
unsigned long ex = v>>BITS_MANT & MASK_EXP;
unsigned long man = v & MASK_MANT;
float mulby = pow(2, (long)ex-(long)MAGIC_EXP );
if (ex==MAXEXP) return v&MASK_S ? -FLT_MAX : FLT_MAX;
if (ex==MINEXP) mulby *= 2; else man |= HIDDEN_BIT;
return v&MASK_S ? man*-mulby : man*mulby;
}
I haven't written it the other way around yet. It's a bit harder,
but probably should go like:
tear apart the sign
init exponent to MAGIC_EXP
shift the value till it's in the "magic" range or exponent gets clamped.
deal with queer values
combine (unsigned long)f, exponent and sign.
Alternatively you could of course just peek at the object
representation of the float value if you don't need to move
the data around different machines (as the representations
may differ). This is done by casting a pointer to the data
into char * and accessing (sizeof data) bytes thru it.