implemented arctan
This commit is contained in:
parent
3e5648de87
commit
e4ad37623b
@ -1297,19 +1297,39 @@ void project_decn_into_0_2pi(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// K. Shirriff, "Reversing Sinclair's amazing 1974 calculator hack - half the ROM of the HP-35"
|
||||||
|
// http://files.righto.com/calculator/sinclair_scientific_simulator.html
|
||||||
#define SIN Tmp2Decn
|
#define SIN Tmp2Decn
|
||||||
#define COS Tmp3Decn
|
#define COS Tmp3Decn
|
||||||
#define THETA Tmp4Decn
|
#define THETA Tmp4Decn
|
||||||
void sincos_decn(void) {
|
void sincos_decn(const uint8_t sincos_arctan) {
|
||||||
project_decn_into_0_2pi();
|
const uint8_t is_negative = AccDecn.exponent < 0;
|
||||||
|
if (sincos_arctan) {
|
||||||
copy_decn(&THETA, &AccDecn);
|
set_dec80_zero(&THETA);
|
||||||
copy_decn(&COS, &DECN_1);
|
if (is_negative) negate_decn(&AccDecn);
|
||||||
set_dec80_zero(&SIN);
|
copy_decn(&COS, &AccDecn);
|
||||||
// 0.0 00 05
|
copy_decn(&SIN, &DECN_1);
|
||||||
SIN.lsu[2] = 5;
|
} else {
|
||||||
negate_decn(&SIN);
|
project_decn_into_0_2pi();
|
||||||
while (THETA.exponent >= 0) {
|
copy_decn(&THETA, &AccDecn);
|
||||||
|
copy_decn(&COS, &DECN_1);
|
||||||
|
set_dec80_zero(&SIN);
|
||||||
|
// 0.0 00 05
|
||||||
|
SIN.lsu[2] = 5;
|
||||||
|
negate_decn(&SIN);
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
if (sincos_arctan) {
|
||||||
|
// THETA is in AccDecn from previous iteration
|
||||||
|
if (COS.exponent < 0) {
|
||||||
|
if (is_negative) negate_decn(&AccDecn);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (THETA.exponent < 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
// COS = COS - SIN / 10000
|
// COS = COS - SIN / 10000
|
||||||
copy_decn(&AccDecn, &COS);
|
copy_decn(&AccDecn, &COS);
|
||||||
copy_decn(&BDecn, &SIN);
|
copy_decn(&BDecn, &SIN);
|
||||||
@ -1329,32 +1349,36 @@ void sincos_decn(void) {
|
|||||||
shift_right(&BDecn);
|
shift_right(&BDecn);
|
||||||
add_decn();
|
add_decn();
|
||||||
copy_decn(&SIN, &AccDecn);
|
copy_decn(&SIN, &AccDecn);
|
||||||
// THETA = THETA - 0.0 00 1
|
// THETA = THETA -/+ 0.0 00 1
|
||||||
copy_decn(&AccDecn, &THETA);
|
copy_decn(&AccDecn, &THETA);
|
||||||
set_dec80_zero(&BDecn);
|
set_dec80_zero(&BDecn);
|
||||||
BDecn.lsu[2] = 10;
|
BDecn.lsu[2] = 10;
|
||||||
negate_decn(&BDecn);
|
if (!sincos_arctan) negate_decn(&BDecn);
|
||||||
add_decn();
|
add_decn();
|
||||||
copy_decn(&THETA, &AccDecn);
|
copy_decn(&THETA, &AccDecn);
|
||||||
}
|
} while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sin_decn(void) {
|
void sin_decn(void) {
|
||||||
sincos_decn();
|
sincos_decn(0);
|
||||||
copy_decn(&AccDecn, &SIN);
|
copy_decn(&AccDecn, &SIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cos_decn(void) {
|
void cos_decn(void) {
|
||||||
sincos_decn();
|
sincos_decn(0);
|
||||||
copy_decn(&AccDecn, &COS);
|
copy_decn(&AccDecn, &COS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tan_decn(void) {
|
void tan_decn(void) {
|
||||||
sincos_decn();
|
sincos_decn(0);
|
||||||
copy_decn(&AccDecn, &SIN);
|
copy_decn(&AccDecn, &SIN);
|
||||||
copy_decn(&BDecn, &COS);
|
copy_decn(&BDecn, &COS);
|
||||||
div_decn();
|
div_decn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void arctan_decn(void) {
|
||||||
|
sincos_decn(1);
|
||||||
|
}
|
||||||
#undef SIN
|
#undef SIN
|
||||||
#undef COS
|
#undef COS
|
||||||
#undef THETA
|
#undef THETA
|
||||||
|
@ -86,10 +86,10 @@ 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 arctan_decn(void);
|
||||||
void to_degree_decn(void);
|
void to_degree_decn(void);
|
||||||
void to_radian_decn(void);
|
void to_radian_decn(void);
|
||||||
|
|
||||||
@ -110,6 +110,13 @@ void decn_to_str_complete(const dec80* x);
|
|||||||
void build_decn_at(dec80* dest, const char* signif_str, exp_t exponent);
|
void build_decn_at(dec80* dest, const char* signif_str, exp_t exponent);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define PRINT_DEC80(n, v) \
|
||||||
|
printf(n " %d %5d: ", v.exponent < 0, get_exponent(&v)); \
|
||||||
|
for (int i = 0; i < DEC80_NUM_LSU; i++) { \
|
||||||
|
printf("%02d ", v.lsu[i]); \
|
||||||
|
} \
|
||||||
|
fputc('\n', stdout);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,6 +53,12 @@ static void tan_test(
|
|||||||
trig_test(tan_decn, [](bmp::mpfr_float x) -> bmp::mpfr_float {return tan(x);}, a_str, a_exp, rtol, atol);
|
trig_test(tan_decn, [](bmp::mpfr_float x) -> bmp::mpfr_float {return tan(x);}, a_str, a_exp, rtol, atol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void atan_test(
|
||||||
|
const char* a_str, int a_exp, double rtol=5e-3, double atol=1e-3)
|
||||||
|
{
|
||||||
|
trig_test(arctan_decn, [](bmp::mpfr_float x) -> bmp::mpfr_float {return atan(x);}, a_str, a_exp, rtol, atol);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const char * const pi = "3.141592653589793239";
|
const char * const pi = "3.141592653589793239";
|
||||||
const char * const pi_threequarters = "2.356194490192344929";
|
const char * const pi_threequarters = "2.356194490192344929";
|
||||||
@ -145,3 +151,19 @@ TEST_CASE("tan") {
|
|||||||
tan_test("2.5", 0);
|
tan_test("2.5", 0);
|
||||||
tan_test("3.0", 0);
|
tan_test("3.0", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("arctan") {
|
||||||
|
atan_test("0.001", 0);
|
||||||
|
atan_test("-0.001", 0);
|
||||||
|
atan_test("0.7", 0);
|
||||||
|
atan_test("-0.7", 0);
|
||||||
|
atan_test("0.1", 0);
|
||||||
|
atan_test("-0.1", 0);
|
||||||
|
atan_test("1.0", 0);
|
||||||
|
atan_test("-1.0", 0);
|
||||||
|
atan_test("2.0", 0);
|
||||||
|
atan_test("-2.0", 0);
|
||||||
|
atan_test("3.0", 0);
|
||||||
|
atan_test("-3.0", 0);
|
||||||
|
atan_test("0", 0, -1);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user