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 }