Since the lrint function seems to be unavailable in Alchemy's C library - along with all the other rounding functions that ought to be in math.h* - any suggestions on fast rounding of a double to an integer? Is casting, subtracting, comparing and incrementing the only way?
*When I try to use these functions it compiles just fine, but I get "Undefined sym: _rint" (or similar) when I try to use the resulting .swc in Flash.
Simple rounding of a double to an integer:
int round(double d) { return (int)(d + 0.5); }
I once made this implementation of lrintf, designed to reproduce IEEE behaviour (where .5 is rounded to the nearest even number):
extern long lrintf(float f)
{
/* Implements the default IEEE 754-1985 rounding mode */
long * fp = (void *)&f;
int sign = (*fp) >> 31;
int exponent = 23 + 0x7f - (((*fp) >> 23) & 0xff);
unsigned int fraction = ((*fp) & 0x7fffff) | 0x800000;
long result = fraction >> exponent;
-- exponent;
if (fraction & (1 << exponent)) { // fraction >= 0.5
if (!(fraction & ~(-1 << exponent))) // fraction == 0.5
if (!(result & 1)) // result is even
return sign ? -result : result;
++ result;
}
return sign ? -result : result;
}
Those constants (31, 23, 0x7f) are specific to the float datatype.
You can identify what functions are available by passing avm2-libc/lib/avm2-libc.l.bc through llvm-dis and examining the definitions in the resulting .ll file.
North America
Europe, Middle East and Africa
Asia Pacific