in MsCorePkg/Library/MathLib/MathLib.c [15:76]
unsigned char _BitScanReverse (
unsigned long * Index,
unsigned long Mask
);
unsigned char _BitScanReverse64 (
unsigned long * Index,
unsigned __int64 Mask
);
#endif
/**
Find sine of a provided double in radians
@param[in] angle to calculate in radians
@retval the result (double)
**/
double
EFIAPI
sin_d(
IN CONST double angleInRadians
){
double radians = angleInRadians;
double previousValue = radians; //x0
INT16 multiply = -1; //we subtract first possibly faster
UINT32 iterationCount = 5; //
double top; //x^3
UINT64 denom = 3*2; //3!
double value;
//Using taylor series expansions
//https://en.wikipedia.org/wiki/Trigonometric_functions#Series_definitions
//so far seems comparable performance to the build in sin function from math.h
//first range modify it to be within 0 and 2 pi
while (radians > 2* MU_PI){
radians -= 2*MU_PI;
}
while (radians < -2* MU_PI){
radians += 2*MU_PI;
}
//compute the first iteration
//Formula is sum over N to infinity with x being the radians
// -1^n x^(2n+1)
//----------------
// (2n+1)!
top = radians * radians * radians; //x^3
value = previousValue - (top/denom);
//iterate 7 iterations
for (; iterationCount <= 19; iterationCount += 2) {
previousValue = value;
denom *= iterationCount * (iterationCount-1); //n * n-1 * (previous computed n-2!)
top *= radians * radians; // x^2 * (previous computed x^n-2)
multiply *= -1; //invert the sign
//could be possibly faster to not use multiply but a conditional move?
value = previousValue + (multiply*top/denom);
}
//checking for convergence provides neglieble speedup and a drop in accuracy.
return value;
}