mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 13:12:37 -05:00
Add arcsin, arccos and arctan to calculator
Change-Id: I9aaded58718ae410239678abe6cf6196286bc7f8
This commit is contained in:
parent
9aa6a35b3f
commit
bfcd8270c9
2 changed files with 123 additions and 2 deletions
|
|
@ -1028,12 +1028,13 @@ static double myLn (double a) {
|
||||||
|
|
||||||
/* -----------------------------------------------------------------------
|
/* -----------------------------------------------------------------------
|
||||||
transcendFunc uses CORDIC (COordinate Rotation DIgital Computer) method
|
transcendFunc uses CORDIC (COordinate Rotation DIgital Computer) method
|
||||||
transcendFunc can do sin,cos,log,exp
|
transcendFunc can do sin,cos,log,exp,asin,acos,atan
|
||||||
input parameter is angle
|
input parameter is angle
|
||||||
----------------------------------------------------------------------- */
|
----------------------------------------------------------------------- */
|
||||||
static void transcendFunc(char* func, double* tt, int* ttPower)
|
static void transcendFunc(char* func, double* tt, int* ttPower)
|
||||||
{
|
{
|
||||||
double t = (*tt)*M_PI/180; int tPower = *ttPower;
|
double t = (*tt);
|
||||||
|
int tPower = *ttPower;
|
||||||
int sign = 1;
|
int sign = 1;
|
||||||
int n = 50; /* n <=50, tables are all <= 50 */
|
int n = 50; /* n <=50, tables are all <= 50 */
|
||||||
int j;
|
int j;
|
||||||
|
|
@ -1050,6 +1051,113 @@ static void transcendFunc(char* func, double* tt, int* ttPower)
|
||||||
*ttPower = 0;
|
*ttPower = 0;
|
||||||
calStatus = cal_normal;
|
calStatus = cal_normal;
|
||||||
|
|
||||||
|
/* Powerscale */
|
||||||
|
while (tPower > 0){
|
||||||
|
t *= 10;
|
||||||
|
tPower--;
|
||||||
|
}
|
||||||
|
while (tPower < 0) {
|
||||||
|
t /= 10;
|
||||||
|
tPower++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Vectoring mode */
|
||||||
|
if(func[0] == 'a' || func[0] == 'A') {
|
||||||
|
if(func[1] == 's' || func[1] == 'S') { /* arcsin */
|
||||||
|
/* arcsin input must be in [-1, 1] */
|
||||||
|
if(t < -1.0 || t > 1.0) {
|
||||||
|
calStatus = cal_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Avoid division by zero */
|
||||||
|
if(t == 1.0) {
|
||||||
|
*tt = 90.0; /* arcsin(1) = 90° */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(t == -1.0) {
|
||||||
|
*tt = -90.0; /* arcsin(-1) = -90° */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Vectoring mode */
|
||||||
|
/* Start with vector (sqrt(1-t^2), t) and find its angle */
|
||||||
|
double magnitude = mySqrt(1.0 - t*t);
|
||||||
|
x = magnitude;
|
||||||
|
y = t;
|
||||||
|
z = 0.0;
|
||||||
|
|
||||||
|
/* Vectoring mode: drive y to 0 */
|
||||||
|
for (j = 1; j < n + 2; j++) {
|
||||||
|
if(y >= 0) {
|
||||||
|
/* Rotate clockwise (negative direction) */
|
||||||
|
xt = x + y * cordicTable[j-1][0];
|
||||||
|
yt = y - x * cordicTable[j-1][0];
|
||||||
|
zt = z - cordicTable[j-1][1];
|
||||||
|
} else {
|
||||||
|
/* Rotate anticlockwise (positive direction) */
|
||||||
|
xt = x - y * cordicTable[j-1][0];
|
||||||
|
yt = y + x * cordicTable[j-1][0];
|
||||||
|
zt = z + cordicTable[j-1][1];
|
||||||
|
}
|
||||||
|
x = xt;
|
||||||
|
y = yt;
|
||||||
|
z = zt;
|
||||||
|
}
|
||||||
|
*tt = z * 180/M_PI * -1; /* Convert to degrees and invert sign */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(func[1] == 'c' || func[1] == 'C') { /* arccos */
|
||||||
|
/* arccos input must be in [-1, 1] */
|
||||||
|
if(t < -1.0 || t > 1.0) {
|
||||||
|
calStatus = cal_error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* For arccos: use arcsin relationship: arccos(t) = π/2 - arcsin(t) */
|
||||||
|
double arcsin_input = t;
|
||||||
|
int arcsin_power = 0;
|
||||||
|
|
||||||
|
/* Save current function context */
|
||||||
|
char original_func[3];
|
||||||
|
strncpy(original_func, func, 3);
|
||||||
|
|
||||||
|
transcendFunc("asin", &arcsin_input, &arcsin_power);
|
||||||
|
|
||||||
|
if (calStatus == cal_error) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* arccos(t) = 90° - arcsin(t) */
|
||||||
|
/* arcsin_input now contains arcsin(t) in degrees */
|
||||||
|
double arccos_degrees = 90.0 - arcsin_input;
|
||||||
|
*tt = arccos_degrees;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(func[1] == 't' || func[1] == 'T') { /* arctan */
|
||||||
|
/* start with x=1, y=input, z=0 and drive y to 0 */
|
||||||
|
x = 1.0;
|
||||||
|
y = t;
|
||||||
|
z = 0.0;
|
||||||
|
|
||||||
|
/* Vectoring mode: drive y to 0 */
|
||||||
|
for (j=1; j<n+2; j++){
|
||||||
|
if(y < 0) {
|
||||||
|
/* Rotate anticlockwise */
|
||||||
|
xt = x - y*cordicTable[j-1][0];
|
||||||
|
yt = y + x*cordicTable[j-1][0];
|
||||||
|
zt = z + cordicTable[j-1][1];
|
||||||
|
} else {
|
||||||
|
/* Rotate clockwise */
|
||||||
|
xt = x + y*cordicTable[j-1][0];
|
||||||
|
yt = y - x*cordicTable[j-1][0];
|
||||||
|
zt = z - cordicTable[j-1][1];
|
||||||
|
}
|
||||||
|
x = xt; y = yt; z = zt;
|
||||||
|
}
|
||||||
|
*tt = z * 180/M_PI * -1; /* Convert back to degrees and invert sign */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( func[0] =='s' || func[0] =='S'|| func[0] =='t' || func[0] =='T')
|
if( func[0] =='s' || func[0] =='S'|| func[0] =='t' || func[0] =='T')
|
||||||
sign = SIGN(t);
|
sign = SIGN(t);
|
||||||
else {
|
else {
|
||||||
|
|
@ -1058,6 +1166,9 @@ static void transcendFunc(char* func, double* tt, int* ttPower)
|
||||||
}
|
}
|
||||||
t = ABS(t);
|
t = ABS(t);
|
||||||
|
|
||||||
|
/* Jump to radians for rotation mode */
|
||||||
|
t = t * M_PI / 180;
|
||||||
|
|
||||||
while (tPower > 0){
|
while (tPower > 0){
|
||||||
t *= 10;
|
t *= 10;
|
||||||
tPower--;
|
tPower--;
|
||||||
|
|
@ -1290,6 +1401,15 @@ static void oneOperand(void)
|
||||||
case sci_tan:
|
case sci_tan:
|
||||||
transcendFunc("tan", &result, &power);
|
transcendFunc("tan", &result, &power);
|
||||||
break;
|
break;
|
||||||
|
case sci_asin:
|
||||||
|
transcendFunc("asin", &result, &power);
|
||||||
|
break;
|
||||||
|
case sci_acos:
|
||||||
|
transcendFunc("acos", &result, &power);
|
||||||
|
break;
|
||||||
|
case sci_atan:
|
||||||
|
transcendFunc("atan", &result, &power);
|
||||||
|
break;
|
||||||
case sci_fac:
|
case sci_fac:
|
||||||
if (power<0 || power>8 || result<0 )
|
if (power<0 || power>8 || result<0 )
|
||||||
calStatus = cal_error;
|
calStatus = cal_error;
|
||||||
|
|
|
||||||
|
|
@ -743,6 +743,7 @@ Pavlo Rudy
|
||||||
Yannic Schmidt
|
Yannic Schmidt
|
||||||
Hairo R. Carela
|
Hairo R. Carela
|
||||||
Sergio Delgado
|
Sergio Delgado
|
||||||
|
Cameron John Peck
|
||||||
|
|
||||||
The libmad team
|
The libmad team
|
||||||
The wavpack team
|
The wavpack team
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue