Skip navigation
chocotaco22
Currently Being Moderated

Fast rounding

Dec 8, 2009 8:53 PM

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.

 
Replies
  • Currently Being Moderated
    Dec 18, 2009 6:31 AM   in reply to chocotaco22

    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.

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points