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_MANT)-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 ulongBitsToFloat(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.