modify code to use accumulator architecture to minimize pointer usage
This commit is contained in:
parent
96c762aeed
commit
6399cbf44f
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,7 +1,9 @@
|
|||||||
*.hex
|
*.hex
|
||||||
|
*.bak
|
||||||
CMakeLists.txt.user
|
CMakeLists.txt.user
|
||||||
build*/*
|
build*/*
|
||||||
.project
|
.project
|
||||||
.cproject
|
.cproject
|
||||||
|
*.kdev4
|
||||||
.settings/*
|
.settings/*
|
||||||
|
|
||||||
|
14
src/calc.c
14
src/calc.c
@ -7,6 +7,8 @@
|
|||||||
#include "decn/decn.h"
|
#include "decn/decn.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include "calc.h"
|
||||||
|
|
||||||
#define STACK_SIZE 4 //must be a power of 2
|
#define STACK_SIZE 4 //must be a power of 2
|
||||||
|
|
||||||
#define STACK_X 0
|
#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){
|
if (!no_lift){
|
||||||
StackPtr--;
|
StackPtr--;
|
||||||
}
|
}
|
||||||
build_dec80(&stack(STACK_X), signif_str, exponent);
|
set_x(signif_str, exponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_x(void){
|
void clear_x(void){
|
||||||
@ -37,7 +39,8 @@ void clear_x(void){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void set_x(const char* signif_str, exp_t exponent){
|
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){
|
__xdata dec80* get_x(void){
|
||||||
@ -47,11 +50,14 @@ __xdata dec80* get_y(void){
|
|||||||
return &stack(STACK_Y);
|
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))){
|
if (decn_is_nan(&stack(STACK_Y)) || decn_is_nan(&stack(STACK_X))){
|
||||||
set_dec80_NaN(&stack(STACK_Y));
|
set_dec80_NaN(&stack(STACK_Y));
|
||||||
} else {
|
} 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();
|
pop();
|
||||||
}
|
}
|
||||||
|
248
src/decn/decn.c
248
src/decn/decn.c
@ -7,13 +7,16 @@
|
|||||||
|
|
||||||
#include "../utils.h"
|
#include "../utils.h"
|
||||||
|
|
||||||
|
#include "decn.h"
|
||||||
|
|
||||||
|
|
||||||
#define EXTRA_CHECKS
|
#define EXTRA_CHECKS
|
||||||
//#define DEBUG
|
// #define DEBUG
|
||||||
//#define DEBUG_COMPARE_MAGN
|
// #define DEBUG_COMPARE_MAGN
|
||||||
//#define DEBUG_ADD
|
// #define DEBUG_ADD
|
||||||
//#define DEBUG_MULT
|
// #define DEBUG_MULT
|
||||||
//#define DEBUG_MULT_ALL //even more verbose
|
// #define DEBUG_MULT_ALL //even more verbose
|
||||||
//#define DEBUG_DIV
|
// #define DEBUG_DIV
|
||||||
|
|
||||||
#ifndef DESKTOP
|
#ifndef DESKTOP
|
||||||
//#undef EXTRA_CHECKS
|
//#undef EXTRA_CHECKS
|
||||||
@ -34,14 +37,14 @@
|
|||||||
#define assert(x)
|
#define assert(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "decn.h"
|
|
||||||
|
|
||||||
#ifdef DESKTOP
|
#ifdef DESKTOP
|
||||||
static const uint8_t num_digits_display = DEC80_NUM_LSU*2;
|
static const uint8_t num_digits_display = DEC80_NUM_LSU*2;
|
||||||
#else
|
#else
|
||||||
static const uint8_t num_digits_display = 16;
|
static const uint8_t num_digits_display = 16;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
__idata dec80 AccDecn, BDecn;
|
||||||
|
|
||||||
|
|
||||||
void copy_decn(dec80* dest, const dec80* src){
|
void copy_decn(dec80* dest, const dec80* src){
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
@ -149,7 +152,7 @@ static void remove_leading_zeros(dec80* x){
|
|||||||
set_exponent(x, exponent, is_negative);
|
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 {
|
enum {
|
||||||
SIGN_ZERO,
|
SIGN_ZERO,
|
||||||
SIGN_ZERO_SEEN_POINT,
|
SIGN_ZERO_SEEN_POINT,
|
||||||
@ -175,7 +178,7 @@ void build_dec80(dec80* dest, const char* signif_str, exp_t exponent){
|
|||||||
|
|
||||||
//check first digit
|
//check first digit
|
||||||
if (signif_str[0] == '\0'){
|
if (signif_str[0] == '\0'){
|
||||||
set_dec80_zero(dest);
|
set_dec80_zero(&AccDecn);
|
||||||
return;
|
return;
|
||||||
} else if (signif_str[0] == '-'){
|
} else if (signif_str[0] == '-'){
|
||||||
curr_sign = SIGN_NEG_ZERO;
|
curr_sign = SIGN_NEG_ZERO;
|
||||||
@ -194,14 +197,14 @@ void build_dec80(dec80* dest, const char* signif_str, exp_t exponent){
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf(" ERROR: multiple '.'s in string\n");
|
printf(" ERROR: multiple '.'s in string\n");
|
||||||
#endif
|
#endif
|
||||||
set_dec80_NaN(dest);
|
set_dec80_NaN(&AccDecn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else if (signif_str[i] >= '1' && signif_str[i] <= '9'){
|
} else if (signif_str[i] >= '1' && signif_str[i] <= '9'){
|
||||||
if (nibble_i < DEC80_NUM_LSU*2){
|
if (nibble_i < DEC80_NUM_LSU*2){
|
||||||
if (nibble_i & 1) { //odd
|
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 {
|
} else {
|
||||||
save_nibble = signif_str[i] - '0';
|
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 (!IS_ZERO(curr_sign)){ //non-zero value
|
||||||
if (nibble_i < DEC80_NUM_LSU*2){
|
if (nibble_i < DEC80_NUM_LSU*2){
|
||||||
if (nibble_i & 1) { //odd
|
if (nibble_i & 1) { //odd
|
||||||
dest->lsu[nibble_i/2] = save_nibble * 10 + 0;
|
AccDecn.lsu[nibble_i/2] = save_nibble * 10 + 0;
|
||||||
} else {
|
} else {
|
||||||
save_nibble = 0;
|
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
|
} else if (signif_str[i] == '\0'){ //done
|
||||||
if (IS_ZERO(curr_sign)){
|
if (IS_ZERO(curr_sign)){
|
||||||
//zero
|
//zero
|
||||||
set_dec80_zero(dest);
|
set_dec80_zero(&AccDecn);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
//not zero
|
//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
|
//write out saved nibble, if it exists
|
||||||
// (saved while nibble_i even, nibble_i then incremented to odd)
|
// (saved while nibble_i even, nibble_i then incremented to odd)
|
||||||
if (nibble_i & 1){ //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
|
nibble_i++; //increment for zeroing out
|
||||||
}
|
}
|
||||||
//zero out any old data
|
//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
|
// adjust exponent for left-aligned significand input
|
||||||
// or for number of digits past decimal point
|
// or for number of digits past decimal point
|
||||||
if (num_lr_points > 0){ //left count exists
|
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",
|
printf(" overflow (new_exp, exp)=(%d,%d)\n",
|
||||||
new_exponent, exponent);
|
new_exponent, exponent);
|
||||||
#endif
|
#endif
|
||||||
set_dec80_NaN(dest);
|
set_dec80_NaN(&AccDecn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#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",
|
printf(" underflow (new_exp, exp)=(%d,%d)\n",
|
||||||
new_exponent, exponent);
|
new_exponent, exponent);
|
||||||
#endif
|
#endif
|
||||||
set_dec80_NaN(dest);
|
set_dec80_NaN(&AccDecn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -307,15 +310,15 @@ void build_dec80(dec80* dest, const char* signif_str, exp_t exponent){
|
|||||||
}
|
}
|
||||||
exponent = new_exponent;
|
exponent = new_exponent;
|
||||||
//set negative bit
|
//set negative bit
|
||||||
set_exponent(dest, exponent, IS_NEG(curr_sign));
|
set_exponent(&AccDecn, exponent, IS_NEG(curr_sign));
|
||||||
//normalize
|
//normalize
|
||||||
remove_leading_zeros(dest);
|
remove_leading_zeros(&AccDecn);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf(" num_lr_points (%d), new_exp (%d), sign (%d), exp (%d)\n",
|
printf(" num_lr_points (%d), new_exp (%d), sign (%d), exp (%d)\n",
|
||||||
num_lr_points, new_exponent, curr_sign, exponent);
|
num_lr_points, new_exponent, curr_sign, exponent);
|
||||||
printf(" ");
|
printf(" ");
|
||||||
for (i = 0; i < DEC80_NUM_LSU; i++){
|
for (i = 0; i < DEC80_NUM_LSU; i++){
|
||||||
printf("%02d,", dest->lsu[i]);
|
printf("%02d,", AccDecn.lsu[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
#endif
|
#endif
|
||||||
@ -390,14 +393,14 @@ void negate_decn(dec80* x){
|
|||||||
(x->exponent) ^= xor_val;
|
(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;
|
uint8_t a_i, b_i;
|
||||||
exp_t a_exp=0, b_exp=0;
|
exp_t a_exp=0, b_exp=0;
|
||||||
int8_t a_signif_b = 0; //a<b: -1, a==b: 0, a>b: 1
|
int8_t a_signif_b = 0; //a<b: -1, a==b: 0, a>b: 1
|
||||||
static __xdata dec80 a_tmp, b_tmp;
|
static __xdata dec80 a_tmp, b_tmp;
|
||||||
//copy
|
//copy
|
||||||
copy_decn(&a_tmp, a);
|
copy_decn(&a_tmp, &AccDecn);
|
||||||
copy_decn(&b_tmp, b);
|
copy_decn(&b_tmp, &BDecn);
|
||||||
//normalize
|
//normalize
|
||||||
remove_leading_zeros(&a_tmp);
|
remove_leading_zeros(&a_tmp);
|
||||||
remove_leading_zeros(&b_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;
|
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;
|
int8_t is_neg;
|
||||||
|
|
||||||
//handle zero special cases
|
//handle zero special cases
|
||||||
if (decn_is_zero(a) && decn_is_zero(b)){
|
if (decn_is_zero(&AccDecn) && decn_is_zero(&BDecn)){
|
||||||
return 0;
|
return 0;
|
||||||
} else if (decn_is_zero(a)){
|
} else if (decn_is_zero(&AccDecn)){
|
||||||
if (b->exponent < 0){
|
if (BDecn.exponent < 0){
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (decn_is_zero(b)){
|
} else if (decn_is_zero(&BDecn)){
|
||||||
if (a->exponent < 0){
|
if (AccDecn.exponent < 0){
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//handle cases where signs differ
|
//handle cases where signs differ
|
||||||
if (a->exponent < 0 && b->exponent > 0){
|
if (AccDecn.exponent < 0 && BDecn.exponent > 0){
|
||||||
return -1;
|
return -1;
|
||||||
} else if (a->exponent > 0 && b->exponent < 0){
|
} else if (AccDecn.exponent > 0 && BDecn.exponent < 0){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
//signs must now be the same, either both pos, or both neg
|
//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
|
//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
|
#ifdef DEBUG_ADD
|
||||||
extern char Buf[DECN_BUF_SIZE];
|
extern char Buf[DECN_BUF_SIZE];
|
||||||
decn_to_str_complete(buf, &tmp);
|
decn_to_str_complete(Buf, &tmp);
|
||||||
printf(" incr_exp tmp: %s\n", buf);
|
printf(" incr_exp tmp: %s\n", Buf);
|
||||||
#endif
|
#endif
|
||||||
//do subtraction
|
//do subtraction
|
||||||
for (i = DEC80_NUM_LSU - 1; i >=0; i--){
|
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|
|
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;
|
static __xdata dec80 tmp;
|
||||||
int8_t rel;
|
int8_t rel;
|
||||||
uint8_t carry = 0;
|
uint8_t carry = 0;
|
||||||
int8_t i;
|
int8_t i;
|
||||||
|
|
||||||
//check if zero
|
//check if zero
|
||||||
if (decn_is_zero(x)){
|
if (decn_is_zero(&BDecn)){
|
||||||
return;
|
return;
|
||||||
} else if (decn_is_zero(acc)){
|
} else if (decn_is_zero(&AccDecn)){
|
||||||
copy_decn(acc, x);
|
copy_decn(&AccDecn, &BDecn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//handle cases where signs differ
|
//handle cases where signs differ
|
||||||
if (acc->exponent < 0 && x->exponent >= 0){
|
if (AccDecn.exponent < 0 && BDecn.exponent >= 0){
|
||||||
// -acc, +x
|
// -acc, +x
|
||||||
rel = compare_magn(acc, x);
|
rel = compare_magn();
|
||||||
if (rel == 1){
|
if (rel == 1){
|
||||||
#ifdef DEBUG_ADD
|
#ifdef DEBUG_ADD
|
||||||
printf("|-acc| > |+x|\n");
|
printf("|-acc| > |+x|\n");
|
||||||
#endif
|
#endif
|
||||||
sub_mag(acc, x);
|
sub_mag(&AccDecn, &BDecn);
|
||||||
return;
|
return;
|
||||||
} else if (rel == -1){
|
} else if (rel == -1){
|
||||||
#ifdef DEBUG_ADD
|
#ifdef DEBUG_ADD
|
||||||
printf("|-acc| < |+x|\n");
|
printf("|-acc| < |+x|\n");
|
||||||
#endif
|
#endif
|
||||||
copy_decn(&tmp, x);
|
copy_decn(&tmp, &BDecn);
|
||||||
sub_mag(&tmp, acc);
|
sub_mag(&tmp, &AccDecn);
|
||||||
copy_decn(acc, &tmp);
|
copy_decn(&AccDecn, &tmp);
|
||||||
return;
|
return;
|
||||||
} else { //equal
|
} else { //equal
|
||||||
#ifdef DEBUG_ADD
|
#ifdef DEBUG_ADD
|
||||||
printf("|-acc| == |+x|\n");
|
printf("|-acc| == |+x|\n");
|
||||||
#endif
|
#endif
|
||||||
set_dec80_zero(acc);
|
set_dec80_zero(&AccDecn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (acc->exponent >= 0 && x->exponent < 0){
|
} else if (AccDecn.exponent >= 0 && BDecn.exponent < 0){
|
||||||
// +acc, -x
|
// +acc, -x
|
||||||
rel = compare_magn(acc, x);
|
rel = compare_magn();
|
||||||
if (rel == 1){
|
if (rel == 1){
|
||||||
#ifdef DEBUG_ADD
|
#ifdef DEBUG_ADD
|
||||||
printf("|+acc| > |-x|\n");
|
printf("|+acc| > |-x|\n");
|
||||||
#endif
|
#endif
|
||||||
sub_mag(acc, x);
|
sub_mag(&AccDecn, &BDecn);
|
||||||
return;
|
return;
|
||||||
} else if (rel == -1){
|
} else if (rel == -1){
|
||||||
#ifdef DEBUG_ADD
|
#ifdef DEBUG_ADD
|
||||||
printf("|+acc| < |-x|\n");
|
printf("|+acc| < |-x|\n");
|
||||||
#endif
|
#endif
|
||||||
copy_decn(&tmp, x);
|
copy_decn(&tmp, &BDecn);
|
||||||
sub_mag(&tmp, acc);
|
sub_mag(&tmp, &AccDecn);
|
||||||
copy_decn(acc, &tmp);
|
copy_decn(&AccDecn, &tmp);
|
||||||
return;
|
return;
|
||||||
} else { //equal
|
} else { //equal
|
||||||
#ifdef DEBUG_ADD
|
#ifdef DEBUG_ADD
|
||||||
printf("|+acc| == |-x|\n");
|
printf("|+acc| == |-x|\n");
|
||||||
#endif
|
#endif
|
||||||
set_dec80_zero(acc);
|
set_dec80_zero(&AccDecn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//signs must now be the same, begin adding
|
//signs must now be the same, begin adding
|
||||||
copy_decn(&tmp, x);
|
copy_decn(&tmp, &BDecn);
|
||||||
//normalize
|
//normalize
|
||||||
remove_leading_zeros(acc);
|
remove_leading_zeros(&AccDecn);
|
||||||
remove_leading_zeros(&tmp);
|
remove_leading_zeros(&tmp);
|
||||||
#ifdef DEBUG_ADD
|
#ifdef DEBUG_ADD
|
||||||
extern char Buf[DECN_BUF_SIZE];
|
extern char Buf[DECN_BUF_SIZE];
|
||||||
decn_to_str_complete(buf, acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf(" rem_leading_zeros acc: %s\n", buf);
|
printf(" rem_leading_zeros acc: %s\n", Buf);
|
||||||
decn_to_str_complete(buf, &tmp);
|
decn_to_str_complete(Buf, &tmp);
|
||||||
printf(" rem_leading_zeros tmp: %s\n", buf);
|
printf(" rem_leading_zeros tmp: %s\n", Buf);
|
||||||
#endif
|
#endif
|
||||||
if (get_exponent(acc) > get_exponent(&tmp)){
|
if (get_exponent(&AccDecn) > get_exponent(&tmp)){
|
||||||
_incr_exp(&tmp, get_exponent(acc));
|
_incr_exp(&tmp, get_exponent(&AccDecn));
|
||||||
} else if (get_exponent(acc) < get_exponent(&tmp)){
|
} else if (get_exponent(&AccDecn) < get_exponent(&tmp)){
|
||||||
//shift significand and adjust exponent to match
|
//shift significand and adjust exponent to match
|
||||||
for (i = 0; i < get_exponent(&tmp) - get_exponent(acc); i++){
|
for (i = 0; i < get_exponent(&tmp) - get_exponent(&AccDecn); i++){
|
||||||
shift_right(acc);
|
shift_right(&AccDecn);
|
||||||
}
|
}
|
||||||
set_exponent(acc, get_exponent(&tmp), (acc->exponent < 0));
|
set_exponent(&AccDecn, get_exponent(&tmp), (AccDecn.exponent < 0));
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_ADD
|
#ifdef DEBUG_ADD
|
||||||
extern char Buf[DECN_BUF_SIZE];
|
extern char Buf[DECN_BUF_SIZE];
|
||||||
decn_to_str_complete(buf, acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf(" incr_exp acc: %s\n", buf);
|
printf(" incr_exp acc: %s\n", Buf);
|
||||||
decn_to_str_complete(buf, &tmp);
|
decn_to_str_complete(Buf, &tmp);
|
||||||
printf(" incr_exp tmp: %s\n", buf);
|
printf(" incr_exp tmp: %s\n", Buf);
|
||||||
#endif
|
#endif
|
||||||
//do addition
|
//do addition
|
||||||
for (i = DEC80_NUM_LSU - 1; i >= 0; i--){
|
for (i = DEC80_NUM_LSU - 1; i >= 0; i--){
|
||||||
uint8_t digit100 = acc->lsu[i] + tmp.lsu[i] + carry;
|
uint8_t digit100 = AccDecn.lsu[i] + tmp.lsu[i] + carry;
|
||||||
acc->lsu[i] = digit100 % 100;
|
AccDecn.lsu[i] = digit100 % 100;
|
||||||
carry = digit100 / 100;
|
carry = digit100 / 100;
|
||||||
assert(carry < 100);
|
assert(carry < 100);
|
||||||
}
|
}
|
||||||
//may need to rescale number
|
//may need to rescale number
|
||||||
if (carry > 0){
|
if (carry > 0){
|
||||||
exp_t curr_exp = get_exponent(acc);
|
exp_t curr_exp = get_exponent(&AccDecn);
|
||||||
rel = (acc->exponent < 0); //is_neg?
|
rel = (AccDecn.exponent < 0); //is_neg?
|
||||||
#ifdef DEBUG_ADD
|
#ifdef DEBUG_ADD
|
||||||
printf(" carry out: %d", carry);
|
printf(" carry out: %d", carry);
|
||||||
#endif
|
#endif
|
||||||
//shift right
|
//shift right
|
||||||
if (carry < 10){
|
if (carry < 10){
|
||||||
shift_right(acc);
|
shift_right(&AccDecn);
|
||||||
acc->lsu[0] += carry*10; //carry gets shifted into most significant digit
|
AccDecn.lsu[0] += carry*10; //carry gets shifted into most significant digit
|
||||||
curr_exp++;
|
curr_exp++;
|
||||||
} else {
|
} else {
|
||||||
shift_right(acc);
|
shift_right(&AccDecn);
|
||||||
shift_right(acc);
|
shift_right(&AccDecn);
|
||||||
acc->lsu[0] = carry;
|
AccDecn.lsu[0] = carry;
|
||||||
curr_exp+=2;
|
curr_exp+=2;
|
||||||
}
|
}
|
||||||
//track sign
|
//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 tmp; //copy of x
|
||||||
static __xdata dec80 acc_tmp; //holds sum
|
static __xdata dec80 acc_tmp; //holds sum
|
||||||
int8_t i, j;
|
int8_t i, j;
|
||||||
@ -661,23 +664,23 @@ void mult_decn(dec80* acc, const dec80* x){
|
|||||||
uint8_t is_neg;
|
uint8_t is_neg;
|
||||||
exp_t new_exponent;
|
exp_t new_exponent;
|
||||||
//initialize values
|
//initialize values
|
||||||
copy_decn(&tmp, x);
|
copy_decn(&tmp, &BDecn);
|
||||||
set_dec80_zero(&acc_tmp);
|
set_dec80_zero(&acc_tmp);
|
||||||
//normalize
|
//normalize
|
||||||
remove_leading_zeros(acc);
|
remove_leading_zeros(&AccDecn);
|
||||||
remove_leading_zeros(&tmp);
|
remove_leading_zeros(&tmp);
|
||||||
//store new sign
|
//store new sign
|
||||||
#ifdef EXP16
|
#ifdef EXP16
|
||||||
if ((acc->exponent & 0x8000) ^ (tmp.exponent & 0x8000)){ //signs differ
|
if ((AccDecn.exponent & 0x8000) ^ (tmp.exponent & 0x8000)){ //signs differ
|
||||||
#else
|
#else
|
||||||
if ((acc->exponent & 0x80) ^ (tmp.exponent & 0x80)){ //signs differ
|
if ((AccDecn.exponent & 0x80) ^ (tmp.exponent & 0x80)){ //signs differ
|
||||||
#endif
|
#endif
|
||||||
is_neg = 1;
|
is_neg = 1;
|
||||||
} else {
|
} else {
|
||||||
is_neg = 0;
|
is_neg = 0;
|
||||||
}
|
}
|
||||||
//calculate new exponent
|
//calculate new exponent
|
||||||
new_exponent = get_exponent(acc) + get_exponent(&tmp);
|
new_exponent = get_exponent(&AccDecn) + get_exponent(&tmp);
|
||||||
#ifdef DEBUG_MULT
|
#ifdef DEBUG_MULT
|
||||||
printf("\n new exponent: %d:", new_exponent);
|
printf("\n new exponent: %d:", new_exponent);
|
||||||
#endif
|
#endif
|
||||||
@ -685,7 +688,7 @@ void mult_decn(dec80* acc, const dec80* x){
|
|||||||
for (i = DEC80_NUM_LSU - 1; i >= 0; i--){
|
for (i = DEC80_NUM_LSU - 1; i >= 0; i--){
|
||||||
//partial product
|
//partial product
|
||||||
for (j = DEC80_NUM_LSU - 1; j >= 0; j--){
|
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;
|
acc_tmp.lsu[j] = digit100 % 100;
|
||||||
carry = digit100 / 100;
|
carry = digit100 / 100;
|
||||||
assert(carry < 100);
|
assert(carry < 100);
|
||||||
@ -694,7 +697,7 @@ void mult_decn(dec80* acc, const dec80* x){
|
|||||||
printf("\n%d:", i);
|
printf("\n%d:", i);
|
||||||
printf("\n acc:");
|
printf("\n acc:");
|
||||||
for (j = 0; j < DEC80_NUM_LSU; j++){
|
for (j = 0; j < DEC80_NUM_LSU; j++){
|
||||||
printf(" %3d", acc->lsu[j]);
|
printf(" %3d", AccDecn.lsu[j]);
|
||||||
}
|
}
|
||||||
printf("\n x:");
|
printf("\n x:");
|
||||||
for (j = 0; j < DEC80_NUM_LSU; j++){
|
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){
|
if (new_exponent < DEC80_MAX_EXP && new_exponent > DEC80_MIN_EXP){
|
||||||
set_exponent(&acc_tmp, new_exponent, is_neg);
|
set_exponent(&acc_tmp, new_exponent, is_neg);
|
||||||
} else {
|
} else {
|
||||||
set_dec80_NaN(acc);
|
set_dec80_NaN(&AccDecn);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//copy back to acc
|
//copy back to acc
|
||||||
copy_decn(acc, &acc_tmp);
|
copy_decn(&AccDecn, &acc_tmp);
|
||||||
//normalize
|
//normalize
|
||||||
remove_leading_zeros(acc);
|
remove_leading_zeros(&AccDecn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void div_decn(dec80* acc, const dec80* x){
|
void div_decn(void){
|
||||||
static __xdata dec80 tmp; //copy of x, holds current 1/x estimate
|
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
|
static __xdata dec80 acc_copy; //holds copy of original acc
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
exp_t initial_exp;
|
exp_t initial_exp;
|
||||||
//check divide by zero
|
//check divide by zero
|
||||||
#ifdef EXTRA_CHECKS
|
#ifdef EXTRA_CHECKS
|
||||||
if (decn_is_zero(x)){
|
if (decn_is_zero(&BDecn)){
|
||||||
set_dec80_NaN(acc);
|
set_dec80_NaN(&AccDecn);
|
||||||
#ifdef DESKTOP
|
#ifdef DESKTOP
|
||||||
printf("error division by 0\n");
|
printf("error division by 0\n");
|
||||||
#endif
|
#endif
|
||||||
@ -762,9 +766,11 @@ void div_decn(dec80* acc, const dec80* x){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//store copy of acc for final multiply by 1/x
|
//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
|
//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
|
#ifdef DEBUG_DIV
|
||||||
printf("exponent %d", initial_exp);
|
printf("exponent %d", initial_exp);
|
||||||
#endif
|
#endif
|
||||||
@ -773,41 +779,45 @@ void div_decn(dec80* acc, const dec80* x){
|
|||||||
#ifdef DEBUG_DIV
|
#ifdef DEBUG_DIV
|
||||||
printf(" -> %d\n", initial_exp);
|
printf(" -> %d\n", initial_exp);
|
||||||
#endif
|
#endif
|
||||||
set_exponent(&tmp, initial_exp, (x->exponent < 0)); //set exponent, copy sign
|
set_exponent(&curr_recip, initial_exp, (BDecn.exponent < 0)); //set exponent, copy sign
|
||||||
tmp.lsu[0] = 10; //1 with implicit point
|
curr_recip.lsu[0] = 10; //1 with implicit point
|
||||||
for (i = 1; i < DEC80_NUM_LSU; i++){
|
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
|
//do newton raphson iterations
|
||||||
for (i = 0; i < DEC80_NUM_LSU; i++){ //just fix number of iterations for now
|
for (i = 0; i < DEC80_NUM_LSU; i++){ //just fix number of iterations for now
|
||||||
#ifdef DEBUG_DIV
|
#ifdef DEBUG_DIV
|
||||||
extern char Buf[80];
|
extern char Buf[DECN_BUF_SIZE];
|
||||||
decn_to_str_complete(Buf, &tmp);
|
decn_to_str_complete(Buf, &curr_recip);
|
||||||
printf("%2d: %s\n", i, Buf);
|
printf("%2d: %s\n", i, Buf);
|
||||||
#endif
|
#endif
|
||||||
mult_decn(acc, x);
|
copy_decn(&BDecn, &x_copy);
|
||||||
|
mult_decn();
|
||||||
#ifdef DEBUG_DIV
|
#ifdef DEBUG_DIV
|
||||||
decn_to_str_complete(Buf, acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf(" %20s: %s\n", "recip*x", Buf);
|
printf(" %20s: %s\n", "recip*x", Buf);
|
||||||
#endif
|
#endif
|
||||||
negate_decn(acc);
|
negate_decn(&AccDecn);
|
||||||
add_decn(acc, &DECN_1);
|
copy_decn(&BDecn, &DECN_1);
|
||||||
|
add_decn();
|
||||||
#ifdef DEBUG_DIV
|
#ifdef DEBUG_DIV
|
||||||
decn_to_str_complete(Buf, acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf(" %20s: %s\n", "(1-recip*x)", Buf);
|
printf(" %20s: %s\n", "(1-recip*x)", Buf);
|
||||||
#endif
|
#endif
|
||||||
mult_decn(acc, &tmp);
|
copy_decn(&BDecn, &curr_recip);
|
||||||
|
mult_decn();
|
||||||
#ifdef DEBUG_DIV
|
#ifdef DEBUG_DIV
|
||||||
decn_to_str_complete(Buf, acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf(" %20s: %s\n", "recip * (1-recip*x)", Buf);
|
printf(" %20s: %s\n", "recip * (1-recip*x)", Buf);
|
||||||
#endif
|
#endif
|
||||||
add_decn(acc, &tmp);
|
add_decn();
|
||||||
//new_est(acc) = recip + (1 - recip*x)*recip, where tmp is current recip estimate
|
//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
|
//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){
|
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
|
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
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,21 +50,19 @@ static const dec80 DECN_1 = {
|
|||||||
//remove sign bit, and return 15 bit exponent sign-extended to 16 bits
|
//remove sign bit, and return 15 bit exponent sign-extended to 16 bits
|
||||||
exp_t get_exponent(const dec80* x);
|
exp_t get_exponent(const dec80* x);
|
||||||
|
|
||||||
//void dec64to80(dec80* dest, const dec64* src);
|
|
||||||
|
|
||||||
void copy_decn(dec80* dest, const dec80* 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_zero(dec80* dest);
|
||||||
void set_dec80_NaN(dec80* dest);
|
void set_dec80_NaN(dec80* dest);
|
||||||
uint8_t decn_is_nan(const dec80* x);
|
uint8_t decn_is_nan(const dec80* x);
|
||||||
|
|
||||||
void negate_decn(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(void);
|
||||||
void add_decn(dec80* acc, const dec80* x);
|
void mult_decn(void);
|
||||||
void mult_decn(dec80* acc, const dec80* x);
|
void div_decn(void);
|
||||||
void div_decn(dec80* acc, const dec80* x);
|
|
||||||
|
|
||||||
//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
|
||||||
@ -73,6 +71,7 @@ int8_t decn_to_str(char* buf, const dec80* x);
|
|||||||
#ifdef DESKTOP
|
#ifdef DESKTOP
|
||||||
//complete string including exponent
|
//complete string including exponent
|
||||||
void decn_to_str_complete(char* buf, const dec80* x);
|
void decn_to_str_complete(char* buf, const dec80* x);
|
||||||
|
void build_decn_at(dec80* dest, const char* signif_str, exp_t exponent);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -9,209 +9,180 @@
|
|||||||
|
|
||||||
char Buf[DECN_BUF_SIZE];
|
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){
|
int main(void){
|
||||||
dec80 acc, b;
|
// dec80 acc, b;
|
||||||
|
|
||||||
build_dec80(&acc, "0.0009234567890123456", 7);
|
build_dec80("0.0009234567890123456", 7);
|
||||||
decn_to_str_complete(Buf, &acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf(" acc: %s\n", Buf);
|
printf(" acc: %s\n", Buf);
|
||||||
|
|
||||||
build_dec80(&acc, "9.234567890123456", 3);
|
build_dec80("9.234567890123456", 3);
|
||||||
decn_to_str_complete(Buf, &acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf(" acc: %s\n", Buf);
|
printf(" acc: %s\n", Buf);
|
||||||
|
|
||||||
negate_decn(&acc);
|
negate_decn(&AccDecn);
|
||||||
decn_to_str_complete(Buf, &acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf("-acc: %s\n", Buf);
|
printf("-acc: %s\n", Buf);
|
||||||
|
|
||||||
build_dec80(&b, "-92.3456789012345678", 1);
|
dec80 tmp_copy;
|
||||||
decn_to_str_complete(Buf, &b);
|
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);
|
printf(" b: %s\n", Buf);
|
||||||
|
|
||||||
decn_to_str_complete(Buf, &acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf("-acc: %s\n", Buf);
|
printf("-acc: %s\n", Buf);
|
||||||
|
|
||||||
//compare result of b - acc
|
//compare result of b - acc
|
||||||
add_decn(&acc, &b);
|
add_decn();
|
||||||
decn_to_str_complete(Buf, &acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf("b - a: %s\n", Buf);
|
printf("b - a: %s\n", Buf);
|
||||||
printf(" : %s\n", "-10158.0246791358016");
|
printf(" : %s\n", "-10158.0246791358016");
|
||||||
dec80 diff;
|
build_decn_at(&diff, "-1.01580246791358016", 4);
|
||||||
build_dec80(&diff, "-1.01580246791358016", 4);
|
take_diff();
|
||||||
negate_decn(&diff);
|
|
||||||
add_decn(&diff, &acc);
|
|
||||||
decn_to_str_complete(Buf, &diff);
|
decn_to_str_complete(Buf, &diff);
|
||||||
printf(" : %s\n\n", Buf);
|
printf(" : %s\n\n", Buf);
|
||||||
|
|
||||||
//new acc for acc - b test
|
//new acc for acc - b test
|
||||||
decn_to_str_complete(Buf, &acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf("acc: %s\n", Buf);
|
printf("acc: %s\n", Buf);
|
||||||
negate_decn(&b);
|
negate_decn(&BDecn);
|
||||||
decn_to_str_complete(Buf, &b);
|
decn_to_str_complete(Buf, &BDecn);
|
||||||
printf(" -b: %s\n", Buf);
|
printf(" -b: %s\n", Buf);
|
||||||
|
|
||||||
add_decn(&acc, &b);
|
add_decn();
|
||||||
decn_to_str_complete(Buf, &acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
//compare result of new acc - b
|
//compare result of new acc - b
|
||||||
printf("acc - b: %s\n", Buf);
|
printf("acc - b: %s\n", Buf);
|
||||||
printf(" : %s\n", "-9234.567890123456");
|
printf(" : %s\n", "-9234.567890123456");
|
||||||
build_dec80(&diff, "-9.234567890123456", 3);
|
build_decn_at(&diff, "-9.234567890123456", 3);
|
||||||
negate_decn(&diff);
|
take_diff();
|
||||||
add_decn(&diff, &acc);
|
|
||||||
decn_to_str_complete(Buf, &diff);
|
decn_to_str_complete(Buf, &diff);
|
||||||
printf(" : %s\n\n", Buf);
|
printf(" : %s\n\n", Buf);
|
||||||
|
|
||||||
//new acc and b for multiply test
|
//new acc and b for multiply test
|
||||||
// build_dec80(&acc, "7", 2);
|
// build_dec80("7", 2);
|
||||||
build_dec80(&acc, "92.34567890123456", 2);
|
build_dec80("92.34567890123456", 2);
|
||||||
build_dec80(&b, "-92.3456789012345678", 1);
|
build_decn_at(&BDecn, "-92.3456789012345678", 1);
|
||||||
decn_to_str_complete(Buf, &acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf(" acc: %s\n", Buf);
|
printf(" acc: %s\n", Buf);
|
||||||
decn_to_str_complete(Buf, &b);
|
decn_to_str_complete(Buf, &BDecn);
|
||||||
printf(" b: %s\n", Buf);
|
printf(" b: %s\n", Buf);
|
||||||
mult_decn(&acc, &b);
|
mult_decn();
|
||||||
decn_to_str_complete(Buf, &acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf("acc*b: %s\n", Buf);
|
printf("acc*b: %s\n", Buf);
|
||||||
printf(" : %s\n", "-8527724.41172991849");
|
printf(" : %s\n", "-8527724.41172991849");
|
||||||
build_dec80(&diff, "-8.52772441172991849", 6);
|
build_decn_at(&diff, "-8.52772441172991849", 6);
|
||||||
negate_decn(&diff);
|
take_diff();
|
||||||
add_decn(&diff, &acc);
|
|
||||||
decn_to_str_complete(Buf, &diff);
|
decn_to_str_complete(Buf, &diff);
|
||||||
printf(" : %s\n\n", Buf);
|
printf(" : %s\n\n", Buf);
|
||||||
|
|
||||||
//new acc and b for divide test
|
//new acc and b for divide test
|
||||||
build_dec80(&acc, "3.14", 60);
|
div_test(
|
||||||
build_dec80(&b, "-1.5", -2);
|
"3.14", 60,
|
||||||
decn_to_str_complete(Buf, &acc);
|
"-1.5", -2,
|
||||||
printf(" acc: %s\n", Buf);
|
"-2.09333333333333334E62",
|
||||||
decn_to_str_complete(Buf, &b);
|
"-2.09333333333333334", 62
|
||||||
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);
|
|
||||||
|
|
||||||
//new acc and b for divide test
|
//new acc and b for divide test
|
||||||
build_dec80(&acc, "4", 0);
|
div_test(
|
||||||
build_dec80(&b, "4", 0);
|
"4", 0,
|
||||||
decn_to_str_complete(Buf, &acc);
|
"4", 0,
|
||||||
printf(" acc: %s\n", Buf);
|
"1.",
|
||||||
decn_to_str_complete(Buf, &b);
|
"1", 0
|
||||||
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);
|
|
||||||
|
|
||||||
//new acc and b for divide test
|
//new acc and b for divide test
|
||||||
build_dec80(&acc, "1", 0);
|
div_test(
|
||||||
build_dec80(&b, "3", 0);
|
"1", 0,
|
||||||
decn_to_str_complete(Buf, &acc);
|
"3", 0,
|
||||||
printf(" acc: %s\n", Buf);
|
"0.333333333333333336",
|
||||||
decn_to_str_complete(Buf, &b);
|
"3.33333333333333336", -1
|
||||||
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);
|
|
||||||
|
|
||||||
//small fractions >= 1/10
|
//small fractions >= 1/10
|
||||||
build_dec80(&acc, "0.333", 0);
|
build_dec80("0.333", 0);
|
||||||
build_dec80(&b, "3.33", -1);
|
build_decn_at(&BDecn, "3.33", -1);
|
||||||
decn_to_str_complete(Buf, &acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf(" a : %s\n", Buf);
|
printf(" a : %s\n", Buf);
|
||||||
decn_to_str_complete(Buf, &b);
|
decn_to_str_complete(Buf, &BDecn);
|
||||||
printf(" b : %s\n", Buf);
|
printf(" b : %s\n", Buf);
|
||||||
negate_decn(&b);
|
negate_decn(&BDecn);
|
||||||
add_decn(&acc, &b);
|
add_decn();
|
||||||
decn_to_str_complete(Buf, &acc);
|
decn_to_str_complete(Buf, &AccDecn);
|
||||||
printf("a - b: %s\n", Buf);
|
printf("a - b: %s\n", Buf);
|
||||||
|
|
||||||
//new acc and b for divide test
|
//new acc and b for divide test
|
||||||
build_dec80(&acc, "500", 0);
|
div_test(
|
||||||
build_dec80(&b, "99", 0);
|
"500", 0,
|
||||||
decn_to_str_complete(Buf, &acc);
|
"99", 0,
|
||||||
printf(" acc: %s\n", Buf);
|
"5.05050505050505055",
|
||||||
decn_to_str_complete(Buf, &b);
|
"5.05050505050505055", 0
|
||||||
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);
|
|
||||||
|
|
||||||
//new acc and b for divide test
|
//new acc and b for divide test
|
||||||
build_dec80(&acc, "500", 0);
|
div_test(
|
||||||
build_dec80(&b, "2", 0);
|
"500", 0,
|
||||||
decn_to_str_complete(Buf, &acc);
|
"2", 0,
|
||||||
printf(" acc: %s\n", Buf);
|
"250.",
|
||||||
decn_to_str_complete(Buf, &b);
|
"250", 0
|
||||||
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);
|
|
||||||
|
|
||||||
//new acc and b for divide test
|
//new acc and b for divide test
|
||||||
build_dec80(&acc, "3", 0);
|
div_test(
|
||||||
build_dec80(&b, "25", -15);
|
"3", 0,
|
||||||
decn_to_str_complete(Buf, &acc);
|
"25", -15,
|
||||||
printf(" acc: %s\n", Buf);
|
"120000000000000",
|
||||||
decn_to_str_complete(Buf, &b);
|
"1.2", 14
|
||||||
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);
|
|
||||||
|
|
||||||
//new acc and b for divide test
|
//new acc and b for divide test
|
||||||
build_dec80(&acc, "0.02", 0);
|
div_test(
|
||||||
build_dec80(&b, "0.03", 0);
|
"0.02", 0,
|
||||||
decn_to_str_complete(Buf, &acc);
|
"0.03", 0,
|
||||||
printf(" acc: %s\n", Buf);
|
"0.666666666666666672",
|
||||||
decn_to_str_complete(Buf, &b);
|
"0.666666666666666672", 0
|
||||||
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);
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
66
src/decn/decn_test_refout.txt
Normal file
66
src/decn/decn_test_refout.txt
Normal 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
|
||||||
|
|
@ -172,7 +172,7 @@ int main()
|
|||||||
ExpBuf[0] = 0;
|
ExpBuf[0] = 0;
|
||||||
ExpBuf[1] = 0;
|
ExpBuf[1] = 0;
|
||||||
|
|
||||||
LCD_OutString("STC RPN Calculator v1.01", 32);
|
LCD_OutString("STC RPN Calculator v1.02", 32);
|
||||||
#ifdef DESKTOP
|
#ifdef DESKTOP
|
||||||
LcdAvailable.release();
|
LcdAvailable.release();
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,6 +37,7 @@ char* u32str(uint32_t x, char* buf, uint8_t base);
|
|||||||
|
|
||||||
#if defined(DESKTOP) || defined(IS_ECLIPSE)
|
#if defined(DESKTOP) || defined(IS_ECLIPSE)
|
||||||
#define __xdata
|
#define __xdata
|
||||||
|
#define __idata
|
||||||
#define __sfr
|
#define __sfr
|
||||||
#define __at uint8_t*
|
#define __at uint8_t*
|
||||||
#define SDCC_ISR(isr, reg)
|
#define SDCC_ISR(isr, reg)
|
||||||
|
Loading…
Reference in New Issue
Block a user