# float to fixed

G

#### Gernot Frisch

// 2 questions:
// On my gp2x (arm?) this code does not work (works on x86 and on
arm-pocketpc)

static inline sll dbl2sll(double dbl)
{
union {
double d;
unsigned u[2];
ull _ull;
sll _sll;
} in, retval;
register unsigned exp;

/* Move into memory as args might be passed in regs */
in.d = dbl;
/* Leading 1 is assumed by IEEE */
retval.u[1] = 0x40000000;

/* Unpack the mantissa into the unsigned long */
retval.u[1] |= (in.u[1] << 10) & 0x3ffffc00;
retval.u[1] |= (in.u[0] >> 22) & 0x000003ff;
retval.u[0] = in.u[0] << 10;

/* Extract the exponent and align the decimals */
exp = (in.u[1] >> 20) & 0x7ff;
if (exp)
retval._ull >>= 1053 - exp;
else
return 0L;

/* Negate if negative flag set */
if (in.u[1] & 0x80000000)
retval._sll = -retval._sll;

return retval._sll;
}

// but this does:
static inline sll dbl2sll(double dbl)
{
return (sll)(dbl * (double)(1LL<<32LL));
}

// 2.nd question
// is there a faster way instead of what I did (2nd function) to
convert an float/double to 32.32 fixed point?

--
-Gernot
int main(int argc, char** argv) {printf
("%silto%c%cf%cgl%ssic%ccom%c", "ma", 58, 'g', 64, "ba", 46, 10);}

________________________________________
Looking for a good game? Do it yourself!
GLBasic - you can do
www.GLBasic.com

J

#### John Ratliff

Gernot said:
// 2 questions:
// On my gp2x (arm?) this code does not work (works on x86 and on
arm-pocketpc)

static inline sll dbl2sll(double dbl)
{
union {
double d;
unsigned u[2];
ull _ull;
sll _sll;
} in, retval;
register unsigned exp;

/* Move into memory as args might be passed in regs */
in.d = dbl;
/* Leading 1 is assumed by IEEE */
retval.u[1] = 0x40000000;

/* Unpack the mantissa into the unsigned long */
retval.u[1] |= (in.u[1] << 10) & 0x3ffffc00;
retval.u[1] |= (in.u[0] >> 22) & 0x000003ff;
retval.u[0] = in.u[0] << 10;

/* Extract the exponent and align the decimals */
exp = (in.u[1] >> 20) & 0x7ff;
if (exp)
retval._ull >>= 1053 - exp;
else
return 0L;

/* Negate if negative flag set */
if (in.u[1] & 0x80000000)
retval._sll = -retval._sll;

return retval._sll;
}

You are assuming portability where none is guaranteed. Using unions in
this way is implementation dependent. The fact that it works on x86 and
powerpc is a coincidence.
// but this does:
static inline sll dbl2sll(double dbl)
{
return (sll)(dbl * (double)(1LL<<32LL));
}

This looks pretty good from a platform-independent standpoint.
// 2.nd question
// is there a faster way instead of what I did (2nd function) to
convert an float/double to 32.32 fixed point?

Sorry, this I do not know.

--John Ratliff

A

#### Andrew Koenig

You are assuming portability where none is guaranteed. Using unions in
this way is implementation dependent. The fact that it works on x86 and
powerpc is a coincidence.

Not to mention that the ordering of the bits in an IEEE floating-point
number is also implementation dependent.