int to float conversion

M

Mike

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.

Any help greatly appreciated.

Mike
 
M

Mark A. Odell

"Mike" said:
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

Why use a function?

int myInt = 1234567;
int myFloat = myInt;

Done. There's your int to float conversion for free. What? Got an int packed
into bytes, first unpack the int into an int variable then assign it to a
float variable.
 
M

Mike

Mark A. Odell said:
"Mike" said:
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

Why use a function?

int myInt = 1234567;
int myFloat = myInt;

Done. There's your int to float conversion for free. What? Got an int packed
into bytes, first unpack the int into an int variable then assign it to a
float variable.

Thanks for replying - I did say I tried type casting already.

When I use 0xAA (-86) as my value for each of the 4 bytes I get a
float value of -1.4317e9, but when I use Hex Workshop it shows the
correct value as -3.0316488e-013.

I know that to calculate the int from a float the following is used:

nValue = (-1)^s * 2^(exponent-127) * mantissa

the 32 bits in the long are represented as follows:

s | exponent | mantisa
1bit | 8bits | 23 bits

I just dont know how to do the reverse ...
 
M

Mark A. Odell

"Mike" said:
Thanks for replying - I did say I tried type casting already. When I use
0xAA (-86) as my value for each of the 4 bytes I get a float value of
-1.4317e9, but when I use Hex Workshop it shows the correct value as
-3.0316488e-013.
I know that to calculate the int from a float the following is used: nValue
= (-1)^s * 2^(exponent-127) * mantissa the 32 bits in the long are
represented as follows:
s | exponent | mantisa
1bit | 8bits | 23 bits
I just dont know how to do the reverse ...

I clearly don't understand the problem. First, floating point is not portable.
So, don't depend on a floating point bit representation to mean the same thing
on another machine. For portablility you could sprintf() the float into a string
and then convert the string back into a float later but I wouldn't try packing
the float bytes into an int for transport over any sort of communication
link.
 
J

Jarno A Wuolijoki

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.
 
J

Joe Wright

Mike said:
Mark A. Odell said:
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

Why use a function?

int myInt = 1234567;
int myFloat = myInt;

Done. There's your int to float conversion for free. What? Got an int packed
into bytes, first unpack the int into an int variable then assign it to a
float variable.


Thanks for replying - I did say I tried type casting already.

When I use 0xAA (-86) as my value for each of the 4 bytes I get a
float value of -1.4317e9, but when I use Hex Workshop it shows the
correct value as -3.0316488e-013.

I know that to calculate the int from a float the following is used:

nValue = (-1)^s * 2^(exponent-127) * mantissa

the 32 bits in the long are represented as follows:

s | exponent | mantisa
1bit | 8bits | 23 bits

I just dont know how to do the reverse ...

You might have it slightly wrong. Consider..

10101010 10101010 10101010 10101010
Exp = 85 (-41)
11010111
Man = .10101010 10101010 10101010
-3.03164883e-13

The mantissa is actually 24 bits. Because (except in the case of
0.0) the high order bit of the normalized mantissa is always 1, its
position in the representation can be used by the low order of the
exponent. So we have 33 bits something like..

s
eeeeeeee
mmmmmmmmmmmmmmmmmmmmmmmm

My view of it has the mantissa a fraction (the . before the first m)
and the offset of the exponent to be 126 (not 127).

Have fun.
 
N

Neil Kurzman

Try

union
{
float aFloat;
byte theBytes[4];
} IntOrFloat;

IntOrFloat.theBytes[0] = pData[0];
ect.... // be sure the bytes are in the right order

or
float aFloat;
byte *pBytes;

pBytes = (byte *)&aFloat;
pBytes[0] = pData[0];
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,141
Messages
2,570,818
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top