implemented sin, cos, theta for all real numbers
This commit is contained in:
parent
2caedc9a45
commit
3e5648de87
@ -68,9 +68,9 @@ static const uint8_t num_digits_display = 16;
|
|||||||
dec80 AccDecn;
|
dec80 AccDecn;
|
||||||
__idata dec80 BDecn;
|
__idata dec80 BDecn;
|
||||||
__idata dec80 TmpDecn; //used by add_decn() and mult_decn()
|
__idata dec80 TmpDecn; //used by add_decn() and mult_decn()
|
||||||
__idata dec80 Tmp2Decn; //used by recip_decn() and ln_decn()
|
__idata dec80 Tmp2Decn; //used by recip_decn() and ln_decn() and sincos_decn()
|
||||||
__xdata dec80 Tmp3Decn; //used by recip_decn() and ln_decn()
|
__xdata dec80 Tmp3Decn; //used by recip_decn() and ln_decn() and sincos_decn()
|
||||||
__xdata dec80 Tmp4Decn; //used by div_decn() and pow_decn()
|
__xdata dec80 Tmp4Decn; //used by div_decn() and pow_decn() and sincos_decn()
|
||||||
|
|
||||||
__xdata char Buf[DECN_BUF_SIZE];
|
__xdata char Buf[DECN_BUF_SIZE];
|
||||||
|
|
||||||
@ -84,6 +84,7 @@ const dec80 DECN_LN_10 = {
|
|||||||
0, {23, 2, 58, 50, 92, 99, 40, 45, 68}
|
0, {23, 2, 58, 50, 92, 99, 40, 45, 68}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 2 pi
|
||||||
const dec80 DECN_2PI = {
|
const dec80 DECN_2PI = {
|
||||||
0, {62, 83, 18, 53, 7, 17, 95, 86, 48}
|
0, {62, 83, 18, 53, 7, 17, 95, 86, 48}
|
||||||
};
|
};
|
||||||
@ -93,7 +94,6 @@ const dec80 DECN_1RAD = {
|
|||||||
1, {57, 29, 57, 79, 51, 30, 82, 32, 9}
|
1, {57, 29, 57, 79, 51, 30, 82, 32, 9}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void copy_decn(dec80* const dest, const dec80* const src){
|
void copy_decn(dec80* const dest, const dec80* const src){
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
@ -1263,34 +1263,53 @@ void pow_decn(void) {
|
|||||||
exp_decn();
|
exp_decn();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sincos_decn(void) {
|
// see W.E. Egbert, "Personal Calculator Algorithms II: Trigonometric functions"
|
||||||
#define SIN Tmp2Decn
|
void project_decn_into_0_2pi(void) {
|
||||||
#define COS Tmp3Decn
|
const uint8_t is_negative = (AccDecn.exponent < 0);
|
||||||
#define STP Tmp4Decn
|
exp_t exponent;
|
||||||
|
|
||||||
remove_leading_zeros(&AccDecn);
|
remove_leading_zeros(&AccDecn);
|
||||||
|
if (is_negative) {
|
||||||
// TODO: implement scaling to 0..2pi
|
negate_decn(&AccDecn);
|
||||||
|
}
|
||||||
|
exponent = get_exponent(&AccDecn);
|
||||||
copy_decn(&BDecn, &DECN_2PI);
|
copy_decn(&BDecn, &DECN_2PI);
|
||||||
if (compare_magn() == 1) {
|
if (compare_magn() > 0) {
|
||||||
set_dec80_NaN(&AccDecn);
|
do {
|
||||||
set_dec80_NaN(&BDecn);
|
do {
|
||||||
return;
|
copy_decn(&BDecn, &DECN_2PI);
|
||||||
}
|
BDecn.exponent = exponent;
|
||||||
set_dec80_zero(&BDecn);
|
if (compare_magn() >= 0) {
|
||||||
if (compare_magn() == -1) {
|
negate_decn(&BDecn);
|
||||||
set_dec80_NaN(&AccDecn);
|
add_decn();
|
||||||
set_dec80_NaN(&BDecn);
|
} else {
|
||||||
return;
|
break;
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
exponent--;
|
||||||
|
} while (exponent >= 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
copy_decn(&STP, &AccDecn);
|
if (is_negative) {
|
||||||
|
negate_decn(&AccDecn);
|
||||||
|
copy_decn(&BDecn, &DECN_2PI);
|
||||||
|
add_decn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SIN Tmp2Decn
|
||||||
|
#define COS Tmp3Decn
|
||||||
|
#define THETA Tmp4Decn
|
||||||
|
void sincos_decn(void) {
|
||||||
|
project_decn_into_0_2pi();
|
||||||
|
|
||||||
|
copy_decn(&THETA, &AccDecn);
|
||||||
copy_decn(&COS, &DECN_1);
|
copy_decn(&COS, &DECN_1);
|
||||||
set_dec80_zero(&SIN);
|
set_dec80_zero(&SIN);
|
||||||
// 0.0 00 05
|
// 0.0 00 05
|
||||||
SIN.lsu[2] = 5;
|
SIN.lsu[2] = 5;
|
||||||
negate_decn(&SIN);
|
negate_decn(&SIN);
|
||||||
while (STP.exponent >= 0) {
|
while (THETA.exponent >= 0) {
|
||||||
// COS = COS - SIN / 10000
|
// COS = COS - SIN / 10000
|
||||||
copy_decn(&AccDecn, &COS);
|
copy_decn(&AccDecn, &COS);
|
||||||
copy_decn(&BDecn, &SIN);
|
copy_decn(&BDecn, &SIN);
|
||||||
@ -1310,13 +1329,13 @@ void sincos_decn(void) {
|
|||||||
shift_right(&BDecn);
|
shift_right(&BDecn);
|
||||||
add_decn();
|
add_decn();
|
||||||
copy_decn(&SIN, &AccDecn);
|
copy_decn(&SIN, &AccDecn);
|
||||||
// STP = STP - 0.0 00 1
|
// THETA = THETA - 0.0 00 1
|
||||||
copy_decn(&AccDecn, &STP);
|
copy_decn(&AccDecn, &THETA);
|
||||||
set_dec80_zero(&BDecn);
|
set_dec80_zero(&BDecn);
|
||||||
BDecn.lsu[2] = 10;
|
BDecn.lsu[2] = 10;
|
||||||
negate_decn(&BDecn);
|
negate_decn(&BDecn);
|
||||||
add_decn();
|
add_decn();
|
||||||
copy_decn(&STP, &AccDecn);
|
copy_decn(&THETA, &AccDecn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1338,6 +1357,17 @@ void tan_decn(void) {
|
|||||||
}
|
}
|
||||||
#undef SIN
|
#undef SIN
|
||||||
#undef COS
|
#undef COS
|
||||||
|
#undef THETA
|
||||||
|
|
||||||
|
void to_degree_decn(void) {
|
||||||
|
copy_decn(&BDecn, &DECN_1RAD);
|
||||||
|
mult_decn();
|
||||||
|
}
|
||||||
|
|
||||||
|
void to_radian_decn(void) {
|
||||||
|
copy_decn(&BDecn, &DECN_1RAD);
|
||||||
|
div_decn();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void set_str_error(void){
|
static void set_str_error(void){
|
||||||
|
@ -86,9 +86,12 @@ void exp_decn(void);
|
|||||||
void exp10_decn(void);
|
void exp10_decn(void);
|
||||||
void pow_decn(void);
|
void pow_decn(void);
|
||||||
|
|
||||||
|
void project_decn_into_0_2pi(void);
|
||||||
void sin_decn(void);
|
void sin_decn(void);
|
||||||
void cos_decn(void);
|
void cos_decn(void);
|
||||||
void tan_decn(void);
|
void tan_decn(void);
|
||||||
|
void to_degree_decn(void);
|
||||||
|
void to_radian_decn(void);
|
||||||
|
|
||||||
//Buf should hold at least 18 + 4 + 5 + 1 = 28
|
//Buf should hold at least 18 + 4 + 5 + 1 = 28
|
||||||
#define DECN_BUF_SIZE 28
|
#define DECN_BUF_SIZE 28
|
||||||
|
@ -81,6 +81,16 @@ TEST_CASE("sin") {
|
|||||||
sin_test(pi_quarted, 0);
|
sin_test(pi_quarted, 0);
|
||||||
sin_test(pi_halfed, 0);
|
sin_test(pi_halfed, 0);
|
||||||
sin_test(pi_threequarters, 0);
|
sin_test(pi_threequarters, 0);
|
||||||
|
sin_test("1000.0", 0);
|
||||||
|
sin_test("-0.5", 0);
|
||||||
|
sin_test("-1.5", 0);
|
||||||
|
sin_test("-2.0", 0);
|
||||||
|
sin_test("-2.5", 0);
|
||||||
|
sin_test("-3.0", 0);
|
||||||
|
sin_test("-9.0", 0);
|
||||||
|
sin_test("-18.0", 0);
|
||||||
|
sin_test("-27.0", 0);
|
||||||
|
sin_test("-1000.0", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("cos") {
|
TEST_CASE("cos") {
|
||||||
@ -104,6 +114,16 @@ TEST_CASE("cos") {
|
|||||||
cos_test(pi_quarted, 0);
|
cos_test(pi_quarted, 0);
|
||||||
cos_test(pi_halfed, 0, -1);
|
cos_test(pi_halfed, 0, -1);
|
||||||
cos_test(pi_threequarters, 0);
|
cos_test(pi_threequarters, 0);
|
||||||
|
cos_test("1000.0", 0);
|
||||||
|
cos_test("-0.5", 0);
|
||||||
|
cos_test("-1.5", 0);
|
||||||
|
cos_test("-2.0", 0);
|
||||||
|
cos_test("-2.5", 0);
|
||||||
|
cos_test("-3.0", 0);
|
||||||
|
cos_test("-9.0", 0);
|
||||||
|
cos_test("-18.0", 0);
|
||||||
|
cos_test("-27.0", 0);
|
||||||
|
cos_test("-1000.0", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user