summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOphir LOJKINE <pere.jobs@gmail.com>2012-10-19 22:25:54 +0200
committerFrank Gevaerts <frank@gevaerts.be>2012-10-19 23:05:25 +0200
commite86991f484f29891b969e851680f66e1948542fa (patch)
tree7fb652879f9ee863cb07a605102f426bdc499ddf
parent9b8a6642e2abb15ec063f72d155792b1d17beb2c (diff)
downloadrockbox-e86991f484f29891b969e851680f66e1948542fa.tar.gz
rockbox-e86991f484f29891b969e851680f66e1948542fa.zip
Implements exponential and logarithm in calculator plugin
exponential implementation uses the series e^x = 1 + x + x^2/2 + x^3/6 + ... natural logarithm uses ln(a) = 2 * ( (a-1)/(a+1) + 1/3 * ((a-1)/(a+1))^3 +... ) log10 uses log10(a) = ln(a)/ln(10) Change-Id: I7303404b2b5a2bf60aad0706ca964a7cea19a27c Reviewed-on: http://gerrit.rockbox.org/333 Reviewed-by: Frank Gevaerts <frank@gevaerts.be>
-rw-r--r--apps/plugins/calculator.c75
1 files changed, 74 insertions, 1 deletions
diff --git a/apps/plugins/calculator.c b/apps/plugins/calculator.c
index 9e9aa220bf..1e07d23a2e 100644
--- a/apps/plugins/calculator.c
+++ b/apps/plugins/calculator.c
@@ -823,6 +823,41 @@ static double mySqrt(double square)
823 823
824 return root; 824 return root;
825} 825}
826
827/*Uses the sequence sum(x^k/k!) that tends to exp(x)*/
828static double myExp (double x) {
829 unsigned int k=0;
830 double res=0, xPow=1,fact=1,toAdd;
831
832 do {
833 toAdd = xPow/fact;
834 res += toAdd;
835 xPow *= x; //xPow = x^k
836 k++;
837 fact*=k; //fact = k!
838 } while (ABS(toAdd) > MINIMUM && xPow<1e302);
839 return res;
840}
841
842/*myLn : uses the series ln⁡(a) = 2 * ∑(1/(2n+1) * ((a-1)/(a+1))^(2k+1) )*/
843static double myLn (double a) {
844 unsigned int k=1;
845 double res=0,xPow,xSquare,fract=1,toAdd;
846
847 xPow = (a-1)/(a+1);
848 xSquare = xPow*xPow;
849
850 do {
851 toAdd = fract*xPow;
852 res += toAdd;
853 xPow *= xSquare; // ((a-1)/(a+1))^k
854 k+=2;
855 fract=1./k;
856 } while (ABS(toAdd) > MINIMUM);
857 return res * 2;
858}
859
860
826/* ----------------------------------------------------------------------- 861/* -----------------------------------------------------------------------
827 transcendFunc uses CORDIC (COordinate Rotation DIgital Computer) method 862 transcendFunc uses CORDIC (COordinate Rotation DIgital Computer) method
828 transcendFunc can do sin,cos,log,exp 863 transcendFunc can do sin,cos,log,exp
@@ -951,6 +986,7 @@ Handles all one operand calculations
951static void oneOperand(void) 986static void oneOperand(void)
952{ 987{
953 int k = 0; 988 int k = 0;
989
954 if (buttonGroup == basicButtons){ 990 if (buttonGroup == basicButtons){
955 switch(CAL_BUTTON){ 991 switch(CAL_BUTTON){
956 case btn_sqr: 992 case btn_sqr:
@@ -1024,6 +1060,40 @@ static void oneOperand(void)
1024 } 1060 }
1025 } 1061 }
1026 break; 1062 break;
1063 case sci_exp:
1064 /*Uses the sequence (1+a/n)^n -> exp(a) */
1065 if (power>3 || result > 1e3) calStatus = cal_error;
1066 else {
1067 while(power < 0) {
1068 result /= 10;
1069 power++;
1070 }
1071 while (power > 0){
1072 power--;
1073 result*=10;
1074 }
1075 result = myExp(result);
1076 calStatus = cal_normal;
1077 }
1078 break;
1079 case sci_ln:
1080 if (result<=0) calStatus = cal_error;
1081 else {
1082 //ln(a*10^n) = ln(a) + n*ln(10), with ln(10) ≈ 2.30
1083 result = myLn(result) + power * 2.302585092994046;
1084 power=0;
1085 calStatus = cal_normal;
1086 }
1087 break;
1088 case sci_log:
1089 if (result<=0) calStatus = cal_error;
1090 else {
1091 //log10(a+10^n) = ln(a)/ln(10) + n, with ln(10) ≈ 2.30
1092 result = myLn(result)/2.302585092994046 + power;
1093 power=0;
1094 calStatus = cal_normal;
1095 }
1096 break;
1027 default: 1097 default:
1028 calStatus = cal_toDo; 1098 calStatus = cal_toDo;
1029 break; /* just for the safety */ 1099 break; /* just for the safety */
@@ -1601,7 +1671,10 @@ static void sciButtonsProcess(void){
1601 calStatus = cal_normal; 1671 calStatus = cal_normal;
1602 break; 1672 break;
1603 1673
1604 case sci_xy: break; 1674 case sci_xy:
1675 /*Not implemented yet
1676 Maybe it could use x^y = exp(y*ln(x))*/
1677 break;
1605 1678
1606 case sci_sci: 1679 case sci_sci:
1607 buttonGroup = basicButtons; 1680 buttonGroup = basicButtons;