This appears to get roughly the same results as sin(x):
__gshared double[512+1] QuarterSinTab;
void init(){
const auto res = QuarterSinTab.length-1;
for(int i = 0; i < res; i++)
QuarterSinTab[i] = sin(PI*(0.5*i/cast(double)res));
QuarterSinTab[$-1] = sin(PI*0.5);
}
auto fastQuarterLookup(double x){
const ulong mantissa = cast(ulong)( (x - floor(x)) *
(cast(double)(1UL<<54)) );
const double sign = cast(double)(1 -
cast(int)((mantissa>>52)&2));
const ulong phase =
(mantissa^((1UL<<53)-((mantissa>>52)&1)))&((1UL<<53) -1);
const uint quarterphase = (phase>>43)&511;
const double frac =
cast(double)(phase&((1UL<<43)-1))*cast(double)(1.0/(1UL<<43));
return sign*((1.0-frac)*QuarterSinTab[quarterphase] +
frac*QuarterSinTab[quarterphase+1]);
}
Ola.