unsigned char _BitScanReverse()

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;
}