mirror of
https://github.com/reactos/reactos.git
synced 2025-06-28 22:29:43 +00:00
[CRT]
Implement sin() in C. Code is actually 99% identical to cos. Note: We are using even exponents for sin, too, as this results in higher precision than using uneven exponents. svn path=/branches/ros-amd64-bringup/; revision=45294
This commit is contained in:
parent
80be387663
commit
01afdbbe91
4 changed files with 90 additions and 23 deletions
|
@ -162,6 +162,7 @@
|
|||
</if>
|
||||
<if property="ARCH" value="amd64">
|
||||
<file>cos.c</file>
|
||||
<file>sin.c</file>
|
||||
<directory name="amd64">
|
||||
<file>alldiv.S</file>
|
||||
<file>atan.S</file>
|
||||
|
@ -178,7 +179,6 @@
|
|||
<file>log.S</file>
|
||||
<file>log10.S</file>
|
||||
<file>pow.S</file>
|
||||
<file>sin.S</file>
|
||||
<file>sqrt.S</file>
|
||||
<file>sqrtf.S</file>
|
||||
<file>tan.S</file>
|
||||
|
|
|
@ -72,7 +72,6 @@
|
|||
<file>log.S</file>
|
||||
<file>log10.S</file>
|
||||
<file>pow.S</file>
|
||||
<file>sin.S</file>
|
||||
<file>sqrt.S</file>
|
||||
<file>tan.S</file>
|
||||
</directory>
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
* PURPOSE: Implementation of sin
|
||||
* FILE: lib/sdk/crt/math/amd64/sin.S
|
||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ndk/amd64/asm.h>
|
||||
#include <ndk/amd64/asmmacro.S>
|
||||
|
||||
.intel_syntax noprefix
|
||||
|
||||
|
||||
.proc sin
|
||||
UNIMPLEMENTED sin
|
||||
ret
|
||||
|
||||
.endproc
|
89
reactos/lib/sdk/crt/math/sin.c
Normal file
89
reactos/lib/sdk/crt/math/sin.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS CRT
|
||||
* FILE: lib/crt/math/sin.c
|
||||
* PURPOSE: Generic C Implementation of sin
|
||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
#define PRECISION 9
|
||||
#define M_PI 3.141592653589793238462643
|
||||
|
||||
static double sin_off_tbl[] = {0.0, -M_PI/2., 0, -M_PI/2.};
|
||||
static double sin_sign_tbl[] = {1,-1,-1,1};
|
||||
|
||||
double
|
||||
sin(double x)
|
||||
{
|
||||
int quadrant;
|
||||
double x2, result;
|
||||
|
||||
/* Calculate the quadrant */
|
||||
quadrant = x * (2./M_PI);
|
||||
|
||||
/* Get offset inside quadrant */
|
||||
x = x - quadrant * (M_PI/2.);
|
||||
|
||||
/* Normalize quadrant to [0..3] */
|
||||
quadrant = (quadrant - 1) & 0x3;
|
||||
|
||||
/* Fixup value for the generic function */
|
||||
x += sin_off_tbl[quadrant];
|
||||
|
||||
/* Calculate the negative of the square of x */
|
||||
x2 = - (x * x);
|
||||
|
||||
/* This is an unrolled taylor series using <PRECISION> iterations
|
||||
* Example with 4 iterations:
|
||||
* result = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8!
|
||||
* To save multiplications and to keep the precision high, it's performed
|
||||
* like this:
|
||||
* result = 1 - x^2 * (1/2! - x^2 * (1/4! - x^2 * (1/6! - x^2 * (1/8!))))
|
||||
*/
|
||||
|
||||
/* Start with 0, compiler will optimize this away */
|
||||
result = 0;
|
||||
|
||||
#if (PRECISION >= 10)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*20);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 9)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 8)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 7)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 6)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12);
|
||||
result *= x2;
|
||||
#endif
|
||||
#if (PRECISION >= 5)
|
||||
result += 1./(1.*2*3*4*5*6*7*8*9*10);
|
||||
result *= x2;
|
||||
#endif
|
||||
result += 1./(1.*2*3*4*5*6*7*8);
|
||||
result *= x2;
|
||||
|
||||
result += 1./(1.*2*3*4*5*6);
|
||||
result *= x2;
|
||||
|
||||
result += 1./(1.*2*3*4);
|
||||
result *= x2;
|
||||
|
||||
result += 1./(1.*2);
|
||||
result *= x2;
|
||||
|
||||
result += 1;
|
||||
|
||||
/* Apply correct sign */
|
||||
result *= sin_sign_tbl[quadrant];
|
||||
|
||||
return result;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue