Go to notes and algorithms index. ~ Go to home page.

arc_sine()


Integer Version.

This function looks a Heath Robinson but it did do the job. I've not gotten around to a pretty-up rewrite so you'll have to take it or leave it :) It uses formulae to emulate the arc sine function rather than a look-up table (so it is probably a fair bit slower, but will use a bit less memory).


long arc_sine( long v_sine )
   {
   // supply the sine in 4096ths  (i.e. 4096 = one)
   // This version only finds angles for positive sines.
   // Jon P

   long result;
   
   #if DIAGNOSTICS_REQUIRED
      if ( v_sine < 0 ) err_dis( 476 );
   #endif
   
   if ( v_sine >= 4092 )
      {
      // angle range from 999 to 1024...
      switch( v_sine )
         {
         case 4092:
            return 996;
         case 4093:
            return 999;
         case 4094:
            return 1004;
         case 4095:
            return 1010;
         case 4096:
            return 1024;
         #if DIAGNOSTICS_REQUIRED
            default:
              err_dis( 475 );
              return 1024;
         #endif
         }   
      }
   else
      {
      result = 1370000 / ( 5129 - v_sine );
      //... 1324 for v_sine=4095.  1324 for v_sine=4096.  267 for v_sine=0
   
      result += 29300 / ( 4141 - v_sine );
      //.... 636 for v_sine=4095.   651 for v_sine=4096.    7 for v_sine=0
   
      // totals:  1960 for v_sine=4095    1975 for v_sine=4096   274 for v_sine=0

      if ( v_sine > 4057 )
         {
         // fix angle range from 934 to 993 approx  (sine range 4057 to 4091)...
         result -= 1625;
         result += ( -5324 * ( v_sine - 4057 )) >> 12;
         result += 3737;
         return result >> 2;
         }
      else
         {
         if ( v_sine > 3910 )
            { // ### this range needs more work... it is +-3 out
            // fix angle range from 827 to 934 approx...
            result -= 1251;
            result += ( 1821 * ( v_sine - 3911 )) >> 12;
            result += 3309 + 4;
            return result >> 2;
            }
         else
            {
            if ( v_sine >= 3117 )
               {
               // fix angle range from 563 to 827 approx...
               result -= 708;
               result += ( 2624 * ( v_sine - 3117 )) >> 12;  //(4428-1804)
               result += 2255;
               return result >> 2;
               }
            else
               {
               //apply the normal ramp
               result -= 274;
               // offset:  1686 for v_sine=4095    1701 for v_sine=4096   0 for v_sine=0
               result += ( 9571 * v_sine ) >> 14;  //2393
               result >>= 2;
            
               if ( v_sine >= 744 && v_sine <= 2987 )
                  {
                  // fix angle range from 119 to 532 approx...
                  result-= 2;
                  }
               return result;
               }
            }
         }
      }
   #if DIAGNOSTICS_REQUIRED
      err_dis( 477 );
   #endif
   }