modify code to use accumulator architecture to minimize pointer usage

This commit is contained in:
Jeff Wang 2019-05-01 03:51:29 -04:00
parent 96c762aeed
commit 6399cbf44f
8 changed files with 339 additions and 276 deletions

2
.gitignore vendored
View File

@ -1,7 +1,9 @@
*.hex
*.bak
CMakeLists.txt.user
build*/*
.project
.cproject
*.kdev4
.settings/*

View File

@ -7,6 +7,8 @@
#include "decn/decn.h"
#include "utils.h"
#include "calc.h"
#define STACK_SIZE 4 //must be a power of 2
#define STACK_X 0
@ -29,7 +31,7 @@ void push_decn(const char* signif_str, exp_t exponent, uint8_t no_lift){
if (!no_lift){
StackPtr--;
}
build_dec80(&stack(STACK_X), signif_str, exponent);
set_x(signif_str, exponent);
}
void clear_x(void){
@ -37,7 +39,8 @@ void clear_x(void){
}
void set_x(const char* signif_str, exp_t exponent){
build_dec80(&stack(STACK_X), signif_str, exponent);
build_dec80(signif_str, exponent);
copy_decn(&stack(STACK_X), &AccDecn);
}
__xdata dec80* get_x(void){
@ -47,11 +50,14 @@ __xdata dec80* get_y(void){
return &stack(STACK_Y);
}
static void do_binary_op(void (*f_ptr)(dec80*, const dec80*)){
static void do_binary_op(void (*f_ptr)(void)){
if (decn_is_nan(&stack(STACK_Y)) || decn_is_nan(&stack(STACK_X))){
set_dec80_NaN(&stack(STACK_Y));
} else {
f_ptr(&stack(STACK_Y), &stack(STACK_X));
copy_decn(&AccDecn, &stack(STACK_Y));
copy_decn(&BDecn, &stack(STACK_X));
f_ptr();
copy_decn(&stack(STACK_Y), &AccDecn);
}
pop();
}

View File

@ -7,13 +7,16 @@
#include "../utils.h"
#include "decn.h"
#define EXTRA_CHECKS
//#define DEBUG
//#define DEBUG_COMPARE_MAGN
//#define DEBUG_ADD
//#define DEBUG_MULT
//#define DEBUG_MULT_ALL //even more verbose
//#define DEBUG_DIV
// #define DEBUG
// #define DEBUG_COMPARE_MAGN
// #define DEBUG_ADD
// #define DEBUG_MULT
// #define DEBUG_MULT_ALL //even more verbose
// #define DEBUG_DIV
#ifndef DESKTOP
//#undef EXTRA_CHECKS
@ -34,14 +37,14 @@
#define assert(x)
#endif
#include "decn.h"
#ifdef DESKTOP
static const uint8_t num_digits_display = DEC80_NUM_LSU*2;
#else
static const uint8_t num_digits_display = 16;
#endif
__idata dec80 AccDecn, BDecn;
void copy_decn(dec80* dest, const dec80* src){
uint8_t i;
@ -149,7 +152,7 @@ static void remove_leading_zeros(dec80* x){
set_exponent(x, exponent, is_negative);
}
void build_dec80(dec80* dest, const char* signif_str, exp_t exponent){
void build_dec80(const char* signif_str, exp_t exponent){
enum {
SIGN_ZERO,
SIGN_ZERO_SEEN_POINT,
@ -175,7 +178,7 @@ void build_dec80(dec80* dest, const char* signif_str, exp_t exponent){
//check first digit
if (signif_str[0] == '\0'){
set_dec80_zero(dest);
set_dec80_zero(&AccDecn);
return;
} else if (signif_str[0] == '-'){
curr_sign = SIGN_NEG_ZERO;
@ -194,14 +197,14 @@ void build_dec80(dec80* dest, const char* signif_str, exp_t exponent){
#ifdef DEBUG
printf(" ERROR: multiple '.'s in string\n");
#endif
set_dec80_NaN(dest);
set_dec80_NaN(&AccDecn);
return;
}
#endif
} else if (signif_str[i] >= '1' && signif_str[i] <= '9'){
if (nibble_i < DEC80_NUM_LSU*2){
if (nibble_i & 1) { //odd
dest->lsu[nibble_i/2] = save_nibble * 10 + (signif_str[i] - '0');
AccDecn.lsu[nibble_i/2] = save_nibble * 10 + (signif_str[i] - '0');
} else {
save_nibble = signif_str[i] - '0';
}
@ -233,7 +236,7 @@ void build_dec80(dec80* dest, const char* signif_str, exp_t exponent){
if (!IS_ZERO(curr_sign)){ //non-zero value
if (nibble_i < DEC80_NUM_LSU*2){
if (nibble_i & 1) { //odd
dest->lsu[nibble_i/2] = save_nibble * 10 + 0;
AccDecn.lsu[nibble_i/2] = save_nibble * 10 + 0;
} else {
save_nibble = 0;
}
@ -257,7 +260,7 @@ void build_dec80(dec80* dest, const char* signif_str, exp_t exponent){
} else if (signif_str[i] == '\0'){ //done
if (IS_ZERO(curr_sign)){
//zero
set_dec80_zero(dest);
set_dec80_zero(&AccDecn);
return;
} else {
//not zero
@ -265,11 +268,11 @@ void build_dec80(dec80* dest, const char* signif_str, exp_t exponent){
//write out saved nibble, if it exists
// (saved while nibble_i even, nibble_i then incremented to odd)
if (nibble_i & 1){ //odd
dest->lsu[nibble_i/2] = save_nibble * 10;
AccDecn.lsu[nibble_i/2] = save_nibble * 10;
nibble_i++; //increment for zeroing out
}
//zero out any old data
zero_remaining_dec80(dest, nibble_i/2);
zero_remaining_dec80(&AccDecn, nibble_i/2);
// adjust exponent for left-aligned significand input
// or for number of digits past decimal point
if (num_lr_points > 0){ //left count exists
@ -282,7 +285,7 @@ void build_dec80(dec80* dest, const char* signif_str, exp_t exponent){
printf(" overflow (new_exp, exp)=(%d,%d)\n",
new_exponent, exponent);
#endif
set_dec80_NaN(dest);
set_dec80_NaN(&AccDecn);
return;
}
#endif
@ -297,7 +300,7 @@ void build_dec80(dec80* dest, const char* signif_str, exp_t exponent){
printf(" underflow (new_exp, exp)=(%d,%d)\n",
new_exponent, exponent);
#endif
set_dec80_NaN(dest);
set_dec80_NaN(&AccDecn);
return;
}
#endif
@ -307,15 +310,15 @@ void build_dec80(dec80* dest, const char* signif_str, exp_t exponent){
}
exponent = new_exponent;
//set negative bit
set_exponent(dest, exponent, IS_NEG(curr_sign));
set_exponent(&AccDecn, exponent, IS_NEG(curr_sign));
//normalize
remove_leading_zeros(dest);
remove_leading_zeros(&AccDecn);
#ifdef DEBUG
printf(" num_lr_points (%d), new_exp (%d), sign (%d), exp (%d)\n",
num_lr_points, new_exponent, curr_sign, exponent);
printf(" ");
for (i = 0; i < DEC80_NUM_LSU; i++){
printf("%02d,", dest->lsu[i]);
printf("%02d,", AccDecn.lsu[i]);
}
printf("\n");
#endif
@ -390,14 +393,14 @@ void negate_decn(dec80* x){
(x->exponent) ^= xor_val;
}
int8_t compare_magn(const dec80* a, const dec80* b){ //a<b: -1, a==b: 0, a>b: 1
static int8_t compare_magn(void){ //returns a<b: -1, a==b: 0, a>b: 1
uint8_t a_i, b_i;
exp_t a_exp=0, b_exp=0;
int8_t a_signif_b = 0; //a<b: -1, a==b: 0, a>b: 1
static __xdata dec80 a_tmp, b_tmp;
//copy
copy_decn(&a_tmp, a);
copy_decn(&b_tmp, b);
copy_decn(&a_tmp, &AccDecn);
copy_decn(&b_tmp, &BDecn);
//normalize
remove_leading_zeros(&a_tmp);
remove_leading_zeros(&b_tmp);
@ -445,35 +448,35 @@ int8_t compare_magn(const dec80* a, const dec80* b){ //a<b: -1, a==b: 0, a>b: 1
return a_signif_b;
}
int8_t compare_decn(const dec80* a, const dec80* b){ //a<b: -1, a==b: 0, a>b: 1
static int8_t compare_decn(void){ //returns a<b: -1, a==b: 0, a>b: 1
int8_t is_neg;
//handle zero special cases
if (decn_is_zero(a) && decn_is_zero(b)){
if (decn_is_zero(&AccDecn) && decn_is_zero(&BDecn)){
return 0;
} else if (decn_is_zero(a)){
if (b->exponent < 0){
} else if (decn_is_zero(&AccDecn)){
if (BDecn.exponent < 0){
return 1;
} else {
return -1;
}
} else if (decn_is_zero(b)){
if (a->exponent < 0){
} else if (decn_is_zero(&BDecn)){
if (AccDecn.exponent < 0){
return -1;
} else {
return 1;
}
}
//handle cases where signs differ
if (a->exponent < 0 && b->exponent > 0){
if (AccDecn.exponent < 0 && BDecn.exponent > 0){
return -1;
} else if (a->exponent > 0 && b->exponent < 0){
} else if (AccDecn.exponent > 0 && BDecn.exponent < 0){
return 1;
}
//signs must now be the same, either both pos, or both neg
is_neg = (a->exponent < 0 ? -1 : 1);
is_neg = (AccDecn.exponent < 0 ? -1 : 1);
return is_neg * compare_magn(a, b);
return is_neg * compare_magn();
}
//WARNING: for add_decn() and sub_mag() functions only
@ -513,8 +516,8 @@ static void sub_mag(dec80* acc, const dec80* x){
}
#ifdef DEBUG_ADD
extern char Buf[DECN_BUF_SIZE];
decn_to_str_complete(buf, &tmp);
printf(" incr_exp tmp: %s\n", buf);
decn_to_str_complete(Buf, &tmp);
printf(" incr_exp tmp: %s\n", Buf);
#endif
//do subtraction
for (i = DEC80_NUM_LSU - 1; i >=0; i--){
@ -532,128 +535,128 @@ static void sub_mag(dec80* acc, const dec80* x){
assert(carry == 0); //shouldn't be carry out if |acc| > |x|
}
void add_decn(dec80* acc, const dec80* x){
void add_decn(void){
static __xdata dec80 tmp;
int8_t rel;
uint8_t carry = 0;
int8_t i;
//check if zero
if (decn_is_zero(x)){
if (decn_is_zero(&BDecn)){
return;
} else if (decn_is_zero(acc)){
copy_decn(acc, x);
} else if (decn_is_zero(&AccDecn)){
copy_decn(&AccDecn, &BDecn);
return;
}
//handle cases where signs differ
if (acc->exponent < 0 && x->exponent >= 0){
if (AccDecn.exponent < 0 && BDecn.exponent >= 0){
// -acc, +x
rel = compare_magn(acc, x);
rel = compare_magn();
if (rel == 1){
#ifdef DEBUG_ADD
printf("|-acc| > |+x|\n");
#endif
sub_mag(acc, x);
sub_mag(&AccDecn, &BDecn);
return;
} else if (rel == -1){
#ifdef DEBUG_ADD
printf("|-acc| < |+x|\n");
#endif
copy_decn(&tmp, x);
sub_mag(&tmp, acc);
copy_decn(acc, &tmp);
copy_decn(&tmp, &BDecn);
sub_mag(&tmp, &AccDecn);
copy_decn(&AccDecn, &tmp);
return;
} else { //equal
#ifdef DEBUG_ADD
printf("|-acc| == |+x|\n");
#endif
set_dec80_zero(acc);
set_dec80_zero(&AccDecn);
return;
}
} else if (acc->exponent >= 0 && x->exponent < 0){
} else if (AccDecn.exponent >= 0 && BDecn.exponent < 0){
// +acc, -x
rel = compare_magn(acc, x);
rel = compare_magn();
if (rel == 1){
#ifdef DEBUG_ADD
printf("|+acc| > |-x|\n");
#endif
sub_mag(acc, x);
sub_mag(&AccDecn, &BDecn);
return;
} else if (rel == -1){
#ifdef DEBUG_ADD
printf("|+acc| < |-x|\n");
#endif
copy_decn(&tmp, x);
sub_mag(&tmp, acc);
copy_decn(acc, &tmp);
copy_decn(&tmp, &BDecn);
sub_mag(&tmp, &AccDecn);
copy_decn(&AccDecn, &tmp);
return;
} else { //equal
#ifdef DEBUG_ADD
printf("|+acc| == |-x|\n");
#endif
set_dec80_zero(acc);
set_dec80_zero(&AccDecn);
return;
}
}
//signs must now be the same, begin adding
copy_decn(&tmp, x);
copy_decn(&tmp, &BDecn);
//normalize
remove_leading_zeros(acc);
remove_leading_zeros(&AccDecn);
remove_leading_zeros(&tmp);
#ifdef DEBUG_ADD
extern char Buf[DECN_BUF_SIZE];
decn_to_str_complete(buf, acc);
printf(" rem_leading_zeros acc: %s\n", buf);
decn_to_str_complete(buf, &tmp);
printf(" rem_leading_zeros tmp: %s\n", buf);
decn_to_str_complete(Buf, &AccDecn);
printf(" rem_leading_zeros acc: %s\n", Buf);
decn_to_str_complete(Buf, &tmp);
printf(" rem_leading_zeros tmp: %s\n", Buf);
#endif
if (get_exponent(acc) > get_exponent(&tmp)){
_incr_exp(&tmp, get_exponent(acc));
} else if (get_exponent(acc) < get_exponent(&tmp)){
if (get_exponent(&AccDecn) > get_exponent(&tmp)){
_incr_exp(&tmp, get_exponent(&AccDecn));
} else if (get_exponent(&AccDecn) < get_exponent(&tmp)){
//shift significand and adjust exponent to match
for (i = 0; i < get_exponent(&tmp) - get_exponent(acc); i++){
shift_right(acc);
for (i = 0; i < get_exponent(&tmp) - get_exponent(&AccDecn); i++){
shift_right(&AccDecn);
}
set_exponent(acc, get_exponent(&tmp), (acc->exponent < 0));
set_exponent(&AccDecn, get_exponent(&tmp), (AccDecn.exponent < 0));
}
#ifdef DEBUG_ADD
extern char Buf[DECN_BUF_SIZE];
decn_to_str_complete(buf, acc);
printf(" incr_exp acc: %s\n", buf);
decn_to_str_complete(buf, &tmp);
printf(" incr_exp tmp: %s\n", buf);
decn_to_str_complete(Buf, &AccDecn);
printf(" incr_exp acc: %s\n", Buf);
decn_to_str_complete(Buf, &tmp);
printf(" incr_exp tmp: %s\n", Buf);
#endif
//do addition
for (i = DEC80_NUM_LSU - 1; i >= 0; i--){
uint8_t digit100 = acc->lsu[i] + tmp.lsu[i] + carry;
acc->lsu[i] = digit100 % 100;
uint8_t digit100 = AccDecn.lsu[i] + tmp.lsu[i] + carry;
AccDecn.lsu[i] = digit100 % 100;
carry = digit100 / 100;
assert(carry < 100);
}
//may need to rescale number
if (carry > 0){
exp_t curr_exp = get_exponent(acc);
rel = (acc->exponent < 0); //is_neg?
exp_t curr_exp = get_exponent(&AccDecn);
rel = (AccDecn.exponent < 0); //is_neg?
#ifdef DEBUG_ADD
printf(" carry out: %d", carry);
#endif
//shift right
if (carry < 10){
shift_right(acc);
acc->lsu[0] += carry*10; //carry gets shifted into most significant digit
shift_right(&AccDecn);
AccDecn.lsu[0] += carry*10; //carry gets shifted into most significant digit
curr_exp++;
} else {
shift_right(acc);
shift_right(acc);
acc->lsu[0] = carry;
shift_right(&AccDecn);
shift_right(&AccDecn);
AccDecn.lsu[0] = carry;
curr_exp+=2;
}
//track sign
set_exponent(acc, curr_exp, rel); //rel==is_neg?
set_exponent(&AccDecn, curr_exp, rel); //rel==is_neg?
}
}
void mult_decn(dec80* acc, const dec80* x){
void mult_decn(void){
static __xdata dec80 tmp; //copy of x
static __xdata dec80 acc_tmp; //holds sum
int8_t i, j;
@ -661,23 +664,23 @@ void mult_decn(dec80* acc, const dec80* x){
uint8_t is_neg;
exp_t new_exponent;
//initialize values
copy_decn(&tmp, x);
copy_decn(&tmp, &BDecn);
set_dec80_zero(&acc_tmp);
//normalize
remove_leading_zeros(acc);
remove_leading_zeros(&AccDecn);
remove_leading_zeros(&tmp);
//store new sign
#ifdef EXP16
if ((acc->exponent & 0x8000) ^ (tmp.exponent & 0x8000)){ //signs differ
if ((AccDecn.exponent & 0x8000) ^ (tmp.exponent & 0x8000)){ //signs differ
#else
if ((acc->exponent & 0x80) ^ (tmp.exponent & 0x80)){ //signs differ
if ((AccDecn.exponent & 0x80) ^ (tmp.exponent & 0x80)){ //signs differ
#endif
is_neg = 1;
} else {
is_neg = 0;
}
//calculate new exponent
new_exponent = get_exponent(acc) + get_exponent(&tmp);
new_exponent = get_exponent(&AccDecn) + get_exponent(&tmp);
#ifdef DEBUG_MULT
printf("\n new exponent: %d:", new_exponent);
#endif
@ -685,7 +688,7 @@ void mult_decn(dec80* acc, const dec80* x){
for (i = DEC80_NUM_LSU - 1; i >= 0; i--){
//partial product
for (j = DEC80_NUM_LSU - 1; j >= 0; j--){
uint16_t digit100 = acc_tmp.lsu[j] + (tmp.lsu[i] * acc->lsu[j]) + carry;
uint16_t digit100 = acc_tmp.lsu[j] + (tmp.lsu[i] * AccDecn.lsu[j]) + carry;
acc_tmp.lsu[j] = digit100 % 100;
carry = digit100 / 100;
assert(carry < 100);
@ -694,7 +697,7 @@ void mult_decn(dec80* acc, const dec80* x){
printf("\n%d:", i);
printf("\n acc:");
for (j = 0; j < DEC80_NUM_LSU; j++){
printf(" %3d", acc->lsu[j]);
printf(" %3d", AccDecn.lsu[j]);
}
printf("\n x:");
for (j = 0; j < DEC80_NUM_LSU; j++){
@ -737,24 +740,25 @@ void mult_decn(dec80* acc, const dec80* x){
if (new_exponent < DEC80_MAX_EXP && new_exponent > DEC80_MIN_EXP){
set_exponent(&acc_tmp, new_exponent, is_neg);
} else {
set_dec80_NaN(acc);
set_dec80_NaN(&AccDecn);
return;
}
//copy back to acc
copy_decn(acc, &acc_tmp);
copy_decn(&AccDecn, &acc_tmp);
//normalize
remove_leading_zeros(acc);
remove_leading_zeros(&AccDecn);
}
void div_decn(dec80* acc, const dec80* x){
static __xdata dec80 tmp; //copy of x, holds current 1/x estimate
void div_decn(void){
static __xdata dec80 curr_recip; //copy of x, holds current 1/x estimate
static __xdata dec80 x_copy; //holds copy of original x
static __xdata dec80 acc_copy; //holds copy of original acc
uint8_t i;
exp_t initial_exp;
//check divide by zero
#ifdef EXTRA_CHECKS
if (decn_is_zero(x)){
set_dec80_NaN(acc);
if (decn_is_zero(&BDecn)){
set_dec80_NaN(&AccDecn);
#ifdef DESKTOP
printf("error division by 0\n");
#endif
@ -762,9 +766,11 @@ void div_decn(dec80* acc, const dec80* x){
}
#endif
//store copy of acc for final multiply by 1/x
copy_decn(&acc_copy, acc);
copy_decn(&acc_copy, &AccDecn);
//store copy of x
copy_decn(&x_copy, &BDecn);
//get initial estimate for 1/x, by negating exponent, and setting signif. to 1
initial_exp = get_exponent(x);
initial_exp = get_exponent(&BDecn);
#ifdef DEBUG_DIV
printf("exponent %d", initial_exp);
#endif
@ -773,41 +779,45 @@ void div_decn(dec80* acc, const dec80* x){
#ifdef DEBUG_DIV
printf(" -> %d\n", initial_exp);
#endif
set_exponent(&tmp, initial_exp, (x->exponent < 0)); //set exponent, copy sign
tmp.lsu[0] = 10; //1 with implicit point
set_exponent(&curr_recip, initial_exp, (BDecn.exponent < 0)); //set exponent, copy sign
curr_recip.lsu[0] = 10; //1 with implicit point
for (i = 1; i < DEC80_NUM_LSU; i++){
tmp.lsu[i] = 0;
curr_recip.lsu[i] = 0;
}
copy_decn(acc, &tmp);
copy_decn(&AccDecn, &curr_recip);
//do newton raphson iterations
for (i = 0; i < DEC80_NUM_LSU; i++){ //just fix number of iterations for now
#ifdef DEBUG_DIV
extern char Buf[80];
decn_to_str_complete(Buf, &tmp);
extern char Buf[DECN_BUF_SIZE];
decn_to_str_complete(Buf, &curr_recip);
printf("%2d: %s\n", i, Buf);
#endif
mult_decn(acc, x);
copy_decn(&BDecn, &x_copy);
mult_decn();
#ifdef DEBUG_DIV
decn_to_str_complete(Buf, acc);
decn_to_str_complete(Buf, &AccDecn);
printf(" %20s: %s\n", "recip*x", Buf);
#endif
negate_decn(acc);
add_decn(acc, &DECN_1);
negate_decn(&AccDecn);
copy_decn(&BDecn, &DECN_1);
add_decn();
#ifdef DEBUG_DIV
decn_to_str_complete(Buf, acc);
decn_to_str_complete(Buf, &AccDecn);
printf(" %20s: %s\n", "(1-recip*x)", Buf);
#endif
mult_decn(acc, &tmp);
copy_decn(&BDecn, &curr_recip);
mult_decn();
#ifdef DEBUG_DIV
decn_to_str_complete(Buf, acc);
decn_to_str_complete(Buf, &AccDecn);
printf(" %20s: %s\n", "recip * (1-recip*x)", Buf);
#endif
add_decn(acc, &tmp);
add_decn();
//new_est(acc) = recip + (1 - recip*x)*recip, where tmp is current recip estimate
copy_decn(&tmp, acc);
copy_decn(&curr_recip, &AccDecn);
}
//acc now holds 1/x, multiply by original acc to complete division
mult_decn(acc, &acc_copy);
copy_decn(&BDecn, &acc_copy);
mult_decn();
}
static void set_str_error(char* buf){
@ -983,8 +993,16 @@ void decn_to_str_complete(char* buf, const dec80* x){
u32str(exponent, &buf[i], 10); //adds null terminator automatically
}
}
}
#endif
void build_decn_at(dec80* dest, const char* signif_str, exp_t exponent){
dec80 tmp;
copy_decn(&tmp, &AccDecn); //save
build_dec80(signif_str, exponent);
copy_decn(dest, &AccDecn);
copy_decn(&AccDecn, &tmp); //restore
}
#endif //DESKTOP

View File

@ -50,21 +50,19 @@ static const dec80 DECN_1 = {
//remove sign bit, and return 15 bit exponent sign-extended to 16 bits
exp_t get_exponent(const dec80* x);
//void dec64to80(dec80* dest, const dec64* src);
void copy_decn(dec80* dest, const dec80* src);
extern __idata dec80 AccDecn, BDecn;
void build_dec80(dec80* dest, const char* signif_str, exp_t exponent);
void build_dec80(const char* signif_str, exp_t exponent);
void set_dec80_zero(dec80* dest);
void set_dec80_NaN(dec80* dest);
uint8_t decn_is_nan(const dec80* x);
void negate_decn(dec80* x);
int8_t compare_decn(const dec80* a, const dec80* b); //a<b: -1, a==b: 0, a>b: 1
void add_decn(dec80* acc, const dec80* x);
void mult_decn(dec80* acc, const dec80* x);
void div_decn(dec80* acc, const dec80* x);
void add_decn(void);
void mult_decn(void);
void div_decn(void);
//buf should hold at least 18 + 4 + 5 + 1 = 28
#define DECN_BUF_SIZE 28
@ -73,6 +71,7 @@ int8_t decn_to_str(char* buf, const dec80* x);
#ifdef DESKTOP
//complete string including exponent
void decn_to_str_complete(char* buf, const dec80* x);
void build_decn_at(dec80* dest, const char* signif_str, exp_t exponent);
#endif
#ifdef __cplusplus

View File

@ -9,209 +9,180 @@
char Buf[DECN_BUF_SIZE];
static dec80 diff;
static void take_diff(void){ //diff = acc - diff
negate_decn(&diff);
dec80 tmp_copy, tmp_copy2;
copy_decn(&tmp_copy, &AccDecn); //save
copy_decn(&tmp_copy2, &BDecn); //save
copy_decn(&BDecn, &diff);
add_decn();
copy_decn(&diff, &AccDecn);
copy_decn(&AccDecn, &tmp_copy); //restore
copy_decn(&BDecn, &tmp_copy2); //restore
}
static void div_test(
const char* a_str, int a_exp,
const char* b_str, int b_exp,
const char* res_str,
const char* res_calc, int res_exp)
{
build_dec80(a_str, a_exp);
build_decn_at(&BDecn, b_str, b_exp);
decn_to_str_complete(Buf, &AccDecn);
printf(" acc: %s\n", Buf);
decn_to_str_complete(Buf, &BDecn);
printf(" b: %s\n", Buf);
div_decn();
decn_to_str_complete(Buf, &AccDecn);
printf("acc/b: %s\n", Buf);
printf(" : %s\n", res_str);
build_decn_at(&diff, res_calc, res_exp);
take_diff();
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
}
int main(void){
dec80 acc, b;
// dec80 acc, b;
build_dec80(&acc, "0.0009234567890123456", 7);
decn_to_str_complete(Buf, &acc);
build_dec80("0.0009234567890123456", 7);
decn_to_str_complete(Buf, &AccDecn);
printf(" acc: %s\n", Buf);
build_dec80(&acc, "9.234567890123456", 3);
decn_to_str_complete(Buf, &acc);
build_dec80("9.234567890123456", 3);
decn_to_str_complete(Buf, &AccDecn);
printf(" acc: %s\n", Buf);
negate_decn(&acc);
decn_to_str_complete(Buf, &acc);
negate_decn(&AccDecn);
decn_to_str_complete(Buf, &AccDecn);
printf("-acc: %s\n", Buf);
build_dec80(&b, "-92.3456789012345678", 1);
decn_to_str_complete(Buf, &b);
dec80 tmp_copy;
copy_decn(&tmp_copy, &AccDecn); //save
build_dec80("-92.3456789012345678", 1);
copy_decn(&BDecn, &AccDecn);
copy_decn(&AccDecn, &tmp_copy); //restore
decn_to_str_complete(Buf, &BDecn);
printf(" b: %s\n", Buf);
decn_to_str_complete(Buf, &acc);
decn_to_str_complete(Buf, &AccDecn);
printf("-acc: %s\n", Buf);
//compare result of b - acc
add_decn(&acc, &b);
decn_to_str_complete(Buf, &acc);
add_decn();
decn_to_str_complete(Buf, &AccDecn);
printf("b - a: %s\n", Buf);
printf(" : %s\n", "-10158.0246791358016");
dec80 diff;
build_dec80(&diff, "-1.01580246791358016", 4);
negate_decn(&diff);
add_decn(&diff, &acc);
build_decn_at(&diff, "-1.01580246791358016", 4);
take_diff();
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
//new acc for acc - b test
decn_to_str_complete(Buf, &acc);
decn_to_str_complete(Buf, &AccDecn);
printf("acc: %s\n", Buf);
negate_decn(&b);
decn_to_str_complete(Buf, &b);
negate_decn(&BDecn);
decn_to_str_complete(Buf, &BDecn);
printf(" -b: %s\n", Buf);
add_decn(&acc, &b);
decn_to_str_complete(Buf, &acc);
add_decn();
decn_to_str_complete(Buf, &AccDecn);
//compare result of new acc - b
printf("acc - b: %s\n", Buf);
printf(" : %s\n", "-9234.567890123456");
build_dec80(&diff, "-9.234567890123456", 3);
negate_decn(&diff);
add_decn(&diff, &acc);
build_decn_at(&diff, "-9.234567890123456", 3);
take_diff();
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
//new acc and b for multiply test
// build_dec80(&acc, "7", 2);
build_dec80(&acc, "92.34567890123456", 2);
build_dec80(&b, "-92.3456789012345678", 1);
decn_to_str_complete(Buf, &acc);
// build_dec80("7", 2);
build_dec80("92.34567890123456", 2);
build_decn_at(&BDecn, "-92.3456789012345678", 1);
decn_to_str_complete(Buf, &AccDecn);
printf(" acc: %s\n", Buf);
decn_to_str_complete(Buf, &b);
decn_to_str_complete(Buf, &BDecn);
printf(" b: %s\n", Buf);
mult_decn(&acc, &b);
decn_to_str_complete(Buf, &acc);
mult_decn();
decn_to_str_complete(Buf, &AccDecn);
printf("acc*b: %s\n", Buf);
printf(" : %s\n", "-8527724.41172991849");
build_dec80(&diff, "-8.52772441172991849", 6);
negate_decn(&diff);
add_decn(&diff, &acc);
build_decn_at(&diff, "-8.52772441172991849", 6);
take_diff();
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
//new acc and b for divide test
build_dec80(&acc, "3.14", 60);
build_dec80(&b, "-1.5", -2);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
div_decn(&acc, &b);
decn_to_str_complete(Buf, &acc);
printf("acc/b: %s\n", Buf);
printf(" : %s\n", "-2.09333333333333334E62");
build_dec80(&diff, "-2.09333333333333334", 62);
negate_decn(&diff);
add_decn(&diff, &acc);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
div_test(
"3.14", 60,
"-1.5", -2,
"-2.09333333333333334E62",
"-2.09333333333333334", 62
);
//new acc and b for divide test
build_dec80(&acc, "4", 0);
build_dec80(&b, "4", 0);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
div_decn(&acc, &b);
decn_to_str_complete(Buf, &acc);
printf("acc/b: %s\n", Buf);
printf(" : %s\n", "1.");
build_dec80(&diff, "1", 0);
negate_decn(&diff);
add_decn(&diff, &acc);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
div_test(
"4", 0,
"4", 0,
"1.",
"1", 0
);
//new acc and b for divide test
build_dec80(&acc, "1", 0);
build_dec80(&b, "3", 0);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
div_decn(&acc, &b);
decn_to_str_complete(Buf, &acc);
printf("acc/b: %s\n", Buf);
printf(" : %s\n", "0.333333333333333336");
build_dec80(&diff, "3.33333333333333336", -1);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n", Buf);
negate_decn(&diff);
add_decn(&diff, &acc);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
div_test(
"1", 0,
"3", 0,
"0.333333333333333336",
"3.33333333333333336", -1
);
//small fractions >= 1/10
build_dec80(&acc, "0.333", 0);
build_dec80(&b, "3.33", -1);
decn_to_str_complete(Buf, &acc);
build_dec80("0.333", 0);
build_decn_at(&BDecn, "3.33", -1);
decn_to_str_complete(Buf, &AccDecn);
printf(" a : %s\n", Buf);
decn_to_str_complete(Buf, &b);
decn_to_str_complete(Buf, &BDecn);
printf(" b : %s\n", Buf);
negate_decn(&b);
add_decn(&acc, &b);
decn_to_str_complete(Buf, &acc);
negate_decn(&BDecn);
add_decn();
decn_to_str_complete(Buf, &AccDecn);
printf("a - b: %s\n", Buf);
//new acc and b for divide test
build_dec80(&acc, "500", 0);
build_dec80(&b, "99", 0);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
div_decn(&acc, &b);
decn_to_str_complete(Buf, &acc);
printf("acc/b: %s\n", Buf);
printf(" : %s\n", "5.05050505050505055");
build_dec80(&diff, "5.05050505050505055", 0);
negate_decn(&diff);
add_decn(&diff, &acc);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
div_test(
"500", 0,
"99", 0,
"5.05050505050505055",
"5.05050505050505055", 0
);
//new acc and b for divide test
build_dec80(&acc, "500", 0);
build_dec80(&b, "2", 0);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
div_decn(&acc, &b);
decn_to_str_complete(Buf, &acc);
printf("acc/b: %s\n", Buf);
printf(" : %s\n", "250.");
build_dec80(&diff, "250", 0);
negate_decn(&diff);
add_decn(&diff, &acc);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
div_test(
"500", 0,
"2", 0,
"250.",
"250", 0
);
//new acc and b for divide test
build_dec80(&acc, "3", 0);
build_dec80(&b, "25", -15);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
div_decn(&acc, &b);
decn_to_str_complete(Buf, &acc);
printf("acc/b: %s\n", Buf);
printf(" : %s\n", "120000000000000");
build_dec80(&diff, "1.2", 14);
negate_decn(&diff);
add_decn(&diff, &acc);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
div_test(
"3", 0,
"25", -15,
"120000000000000",
"1.2", 14
);
//new acc and b for divide test
build_dec80(&acc, "0.02", 0);
build_dec80(&b, "0.03", 0);
decn_to_str_complete(Buf, &acc);
printf(" acc: %s\n", Buf);
decn_to_str_complete(Buf, &b);
printf(" b: %s\n", Buf);
div_decn(&acc, &b);
decn_to_str_complete(Buf, &acc);
printf("acc/b: %s\n", Buf);
printf(" : %s\n", "0.666666666666666672");
build_dec80(&diff, "0.666666666666666672", 0);
negate_decn(&diff);
add_decn(&diff, &acc);
decn_to_str_complete(Buf, &diff);
printf(" : %s\n\n", Buf);
div_test(
"0.02", 0,
"0.03", 0,
"0.666666666666666672",
"0.666666666666666672", 0
);
return 0;
}

View File

@ -0,0 +1,66 @@
acc: 9234.567890123456
acc: 9234.567890123456
-acc: -9234.567890123456
b: -923.456789012345678
-acc: -9234.567890123456
b - a: -10158.0246791358016
: -10158.0246791358016
: 0
acc: -10158.0246791358016
-b: 923.456789012345678
acc - b: -9234.567890123456
: -9234.567890123456
: 0
acc: 9234.567890123456
b: -923.456789012345678
acc*b: -8527724.41172991849
: -8527724.41172991849
: 0
acc: 3.14E60
b: -0.015
acc/b: -2.09333333333333334E62
: -2.09333333333333334E62
: 0
acc: 4.
b: 4.
acc/b: 1.
: 1.
: 0
acc: 1.
b: 3.
acc/b: 0.333333333333333336
: 0.333333333333333336
: 0
a : 0.333
b : 0.333
a - b: 0
acc: 500.
b: 99.
acc/b: 5.05050505050505055
: 5.05050505050505055
: 0
acc: 500.
b: 2.
acc/b: 250.
: 250.
: 0
acc: 3.
b: 2.5E-14
acc/b: 120000000000000.
: 120000000000000
: 0
acc: 0.02
b: 0.03
acc/b: 0.666666666666666672
: 0.666666666666666672
: 0

View File

@ -172,7 +172,7 @@ int main()
ExpBuf[0] = 0;
ExpBuf[1] = 0;
LCD_OutString("STC RPN Calculator v1.01", 32);
LCD_OutString("STC RPN Calculator v1.02", 32);
#ifdef DESKTOP
LcdAvailable.release();
#endif

View File

@ -37,6 +37,7 @@ char* u32str(uint32_t x, char* buf, uint8_t base);
#if defined(DESKTOP) || defined(IS_ECLIPSE)
#define __xdata
#define __idata
#define __sfr
#define __at uint8_t*
#define SDCC_ISR(isr, reg)