gcalctool r2471 - in trunk: . gcalctool
- From: rancell svn gnome org
- To: svn-commits-list gnome org
- Subject: gcalctool r2471 - in trunk: . gcalctool
- Date: Mon, 6 Apr 2009 01:21:05 +0000 (UTC)
Author: rancell
Date: Mon Apr 6 01:21:05 2009
New Revision: 2471
URL: http://svn.gnome.org/viewvc/gcalctool?rev=2471&view=rev
Log:
Replace MP number arrays with an MPNumber structure (Robert Ancell)
Modified:
trunk/ChangeLog
trunk/configure.in
trunk/gcalctool/calctool.c
trunk/gcalctool/calctool.h
trunk/gcalctool/ce_parser.c
trunk/gcalctool/ce_parser.h
trunk/gcalctool/ce_parser.y
trunk/gcalctool/ce_tokeniser.l
trunk/gcalctool/display.c
trunk/gcalctool/display.h
trunk/gcalctool/financial.c
trunk/gcalctool/financial.h
trunk/gcalctool/functions.c
trunk/gcalctool/gtk.c
trunk/gcalctool/mp-binary.c
trunk/gcalctool/mp-convert.c
trunk/gcalctool/mp-internal.h
trunk/gcalctool/mp-trigonometric.c
trunk/gcalctool/mp.c
trunk/gcalctool/mp.h
trunk/gcalctool/parser.c
trunk/gcalctool/parser.h
trunk/gcalctool/register.c
trunk/gcalctool/register.h
trunk/gcalctool/unittest.c
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Mon Apr 6 01:21:05 2009
@@ -18,7 +18,7 @@
AC_SUBST(ATK_CFLAGS)
AC_SUBST(ATK_LIBS)
-pkg_modules="gtk+-2.0 >= 2.14.0 gobject-2.0 gdk-x11-2.0 glib-2.0 atk gdk-pixbuf-2.0 libglade-2.0"
+pkg_modules="gtk+-2.0 >= 2.12.0 gobject-2.0 gdk-x11-2.0 glib-2.0 atk gdk-pixbuf-2.0 libglade-2.0"
PKG_CHECK_MODULES(PACKAGE, [$pkg_modules])
AC_SUBST(PACKAGE_CFLAGS)
AC_SUBST(PACKAGE_LIBS)
Modified: trunk/gcalctool/calctool.c
==============================================================================
--- trunk/gcalctool/calctool.c (original)
+++ trunk/gcalctool/calctool.c Mon Apr 6 01:21:05 2009
@@ -46,37 +46,37 @@
/* Change type to radian */
void
-to_rad(int s1[MP_SIZE], int t1[MP_SIZE])
+to_rad(const MPNumber *s1, MPNumber *t1)
{
- int MP1[MP_SIZE], MP2[MP_SIZE];
+ MPNumber MP1, MP2;
if (v->ttype == DEG) {
- mp_get_pi(MP1);
- mpmul(s1, MP1, MP2);
- mp_set_from_integer(180, MP1);
- mpdiv(MP2, MP1, t1);
+ mp_get_pi(&MP1);
+ mpmul(s1, &MP1, &MP2);
+ mp_set_from_integer(180, &MP1);
+ mpdiv(&MP2, &MP1, t1);
} else if (v->ttype == GRAD) {
- mp_get_pi(MP1);
- mpmul(s1, MP1, MP2);
- mp_set_from_integer(200, MP1);
- mpdiv(MP2, MP1, t1);
+ mp_get_pi(&MP1);
+ mpmul(s1, &MP1, &MP2);
+ mp_set_from_integer(200, &MP1);
+ mpdiv(&MP2, &MP1, t1);
} else {
mp_set_from_mp(s1, t1);
}
}
void
-do_trig_typeconv(TrigType ttype, int s1[MP_SIZE], int t1[MP_SIZE])
+do_trig_typeconv(TrigType ttype, const MPNumber *s1, MPNumber *t1)
{
- int MP1[MP_SIZE], MP2[MP_SIZE];
+ MPNumber MP1, MP2;
switch (ttype) {
case DEG:
- mp_set_from_integer(180, MP1);
- mpmul(s1, MP1, MP2);
- mp_get_pi(MP1);
- mpdiv(MP2, MP1, t1);
+ mp_set_from_integer(180, &MP1);
+ mpmul(s1, &MP1, &MP2);
+ mp_get_pi(&MP1);
+ mpdiv(&MP2, &MP1, t1);
break;
case RAD:
@@ -84,10 +84,10 @@
break;
case GRAD:
- mp_set_from_integer(200, MP1);
- mpmul(s1, MP1, MP2);
- mp_get_pi(MP1);
- mpdiv(MP2, MP1, t1);
+ mp_set_from_integer(200, &MP1);
+ mpmul(s1, &MP1, &MP2);
+ mp_get_pi(&MP1);
+ mpdiv(&MP2, &MP1, t1);
break;
default:
@@ -202,11 +202,10 @@
static void
init_state(void)
{
- int acc, size, i;
+ int acc, i;
acc = MAX_DIGITS + 12; /* MP internal accuracy. */
- size = MP_SIZE;
- mpset(acc, size, size);
+ mpset(acc, MP_SIZE);
v->error = FALSE; /* No calculator error initially. */
v->radix = get_radix(); /* Locale specific radix string. */
Modified: trunk/gcalctool/calctool.h
==============================================================================
--- trunk/gcalctool/calctool.h (original)
+++ trunk/gcalctool/calctool.h Mon Apr 6 01:21:05 2009
@@ -86,9 +86,9 @@
extern int basevals[]; /* Supported arithmetic bases. */
/* Change type to radian */
-void to_rad(int s1[MP_SIZE], int t1[MP_SIZE]);
+void to_rad(const MPNumber *s1, MPNumber *t1);
-void do_trig_typeconv(TrigType ttype, int s1[MP_SIZE], int t1[MP_SIZE]);
+void do_trig_typeconv(TrigType ttype, const MPNumber *s1, MPNumber *t1);
void doerr(char *);
Modified: trunk/gcalctool/ce_parser.c
==============================================================================
--- trunk/gcalctool/ce_parser.c (original)
+++ trunk/gcalctool/ce_parser.c Mon Apr 6 01:21:05 2009
@@ -26,7 +26,7 @@
/* TODO: This file is almost identical to lr-parser. */
int
-ce_parse_(const char *expression, int result[MP_SIZE], int flags)
+ce_parse_(const char *expression, MPNumber *result, int flags)
{
int ret = 0;
@@ -58,16 +58,16 @@
}
if (flags & ANS) {
- memcpy(result, parser_state.ret, sizeof(int)*MP_SIZE);
+ mp_set_from_mp(&parser_state.ret, result);
}
- return 0;
+ return 0;
}
}
int
-ce_parse(const char *expression, int result[MP_SIZE])
+ce_parse(const char *expression, MPNumber *result)
{
return(ce_parse_(expression, result, ANS));
}
@@ -76,7 +76,6 @@
int
ce_udf_parse(const char *expression)
{
- int dummy[MP_SIZE];
-
- return(ce_parse_(expression, dummy, 0));
+ MPNumber temp;
+ return(ce_parse_(expression, &temp, 0));
}
Modified: trunk/gcalctool/ce_parser.h
==============================================================================
--- trunk/gcalctool/ce_parser.h (original)
+++ trunk/gcalctool/ce_parser.h Mon Apr 6 01:21:05 2009
@@ -40,7 +40,7 @@
int ceerror(); /* dummy definition TODO: this is a douple */
int ceparse(); /* dummy definition. */
int ceerror(char *s);
-int ce_parse(const char *expression, int result[MP_SIZE]);
+int ce_parse(const char *expression, MPNumber *result);
int ce_udf_parse(const char *expression);
void reset_ce_tokeniser();
Modified: trunk/gcalctool/ce_parser.y
==============================================================================
--- trunk/gcalctool/ce_parser.y (original)
+++ trunk/gcalctool/ce_parser.y Mon Apr 6 01:21:05 2009
@@ -34,7 +34,7 @@
%}
%union {
- int int_t[MP_SIZE];
+ MPNumber int_t;
int integer;
}
@@ -98,7 +98,7 @@
statement:
seq
-| value {ret($1);}
+| value {ret(&$1);}
| error {
yyclearin;
reset_ce_tokeniser();
@@ -114,15 +114,15 @@
udf:
value '=' {
- display_set_number(&v->display, $1);
+ display_set_number(&v->display, &$1);
}
| value '=' tSTO '(' tNUMBER ')' {
- int val = mp_cast_to_int($5);
- register_set(val, $1);
+ int val = mp_cast_to_int(&$5);
+ register_set(val, &$1);
}
| value tSTO '(' tNUMBER ')' {
- int val = mp_cast_to_int($4);
- register_set(val, $1);
+ int val = mp_cast_to_int(&$4);
+ register_set(val, &$1);
}
| tCLR {
display_clear(&v->display);
@@ -130,124 +130,124 @@
;
value:
- exp {cp($1, $$);}
-| tPI %prec HIGH {mp_get_pi($$);}
+ exp {cp(&$1, &$$);}
+| tPI %prec HIGH {mp_get_pi(&$$);}
;
exp:
- term {cp($1, $$);}
+ term {cp(&$1, &$$);}
-| exp '+' exp {mp_add($1, $3, $$);}
-| exp '-' exp {mp_subtract($1, $3, $$);}
+| exp '+' exp {mp_add(&$1, &$3, &$$);}
+| exp '-' exp {mp_subtract(&$1, &$3, &$$);}
| exp tMOD exp %prec MED {
- if (!mp_is_integer($1) || !mp_is_integer($3)) {
+ if (!mp_is_integer(&$1) || !mp_is_integer(&$3)) {
parser_state.error = -PARSER_ERR_MODULUSOP;
} else {
- if (mp_modulus_divide($1, $3, $$)) {
+ if (mp_modulus_divide(&$1, &$3, &$$)) {
parser_state.error = -EINVAL;
}
}
}
| exp tAND exp {
- if (!mp_is_natural($1) || !mp_is_natural($3)) {
+ if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
parser_state.error = -PARSER_ERR_BITWISEOP;
}
- mp_and($1, $3, $$);
+ mp_and(&$1, &$3, &$$);
}
| exp tOR exp {
- if (!mp_is_natural($1) || !mp_is_natural($3)) {
+ if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
parser_state.error = -PARSER_ERR_BITWISEOP;
}
- mp_or($1, $3, $$);
+ mp_or(&$1, &$3, &$$);
}
| exp tXNOR exp {
- if (!mp_is_natural($1) || !mp_is_natural($3)) {
+ if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
parser_state.error = -PARSER_ERR_BITWISEOP;
}
- mp_xnor($1, $3, $$);
+ mp_xnor(&$1, &$3, &$$);
}
| exp tXOR exp {
- if (!mp_is_natural($1) || !mp_is_natural($3)) {
+ if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
parser_state.error = -PARSER_ERR_BITWISEOP;
}
- mp_xor($1, $3, $$);
+ mp_xor(&$1, &$3, &$$);
}
;
term:
- number {cp($1, $$);}
-| rcl {cp($1, $$);}
-| term '/' term {mpdiv($1, $3, $$);}
-| term '*' term {mpmul($1, $3, $$);}
-| 'e' '^' term {mp_epowy($3, $$);}
-| term '!' {mp_factorial($1 ,$$);}
-| term '%' {mp_percent($1, $$);}
+ number {cp(&$1, &$$);}
+| rcl {cp(&$1, &$$);}
+| term '/' term {mpdiv(&$1, &$3, &$$);}
+| term '*' term {mpmul(&$1, &$3, &$$);}
+| 'e' '^' term {mp_epowy(&$3, &$$);}
+| term '!' {mp_factorial(&$1, &$$);}
+| term '%' {mp_percent(&$1, &$$);}
| '~' term %prec LNEG {
- if (!mp_is_natural($2)) {
+ if (!mp_is_natural(&$2)) {
parser_state.error = -PARSER_ERR_BITWISEOP;
}
- mp_not($2, $$);
+ mp_not(&$2, &$$);
}
-| '-' term %prec NEG {mp_invert_sign($2, $$);}
-| '+' term %prec POS {cp($2, $$);}
-| term '^' term {mp_xpowy($1, $3, $$);}
+| '-' term %prec NEG {mp_invert_sign(&$2, &$$);}
+| '+' term %prec POS {cp(&$2, &$$);}
+| term '^' term {mp_xpowy(&$1, &$3, &$$);}
-| func {cp($1, $$);}
-| reg {cp($1, $$);}
+| func {cp(&$1, &$$);}
+| reg {cp(&$1, &$$);}
-| parenthesis {cp($1, $$);}
+| parenthesis {cp(&$1, &$$);}
;
parenthesis:
- '(' exp ')' {cp($2, $$);}
+ '(' exp ')' {cp(&$2, &$$);}
;
reg:
- tREG {register_get($1, $$);}
+ tREG {register_get($1, &$$);}
;
func:
- tLOG10 term %prec HIGH {mp_logarithm(10, $2, $$);}
-| tLOG2 term %prec HIGH {mp_logarithm(2, $2, $$);}
-| tSQRT term %prec HIGH {mp_sqrt($2, $$);}
-| tLN term %prec HIGH {mpln($2, $$);}
-| tRAND %prec HIGH {mp_set_from_random($$);}
-| tABS term %prec HIGH {mp_abs($2, $$);}
-| tFRAC term %prec HIGH {mpcmf($2, $$);}
-| tINT term %prec HIGH {mpcmim($2, $$);}
-| tCHS term %prec HIGH {mp_invert_sign($2, $$);}
-
-| tSIN term %prec HIGH {to_rad($2, $2); mp_sin($2, $$);}
-| tCOS term %prec HIGH {to_rad($2, $2); mp_cos($2, $$);}
-| tTAN term %prec HIGH {to_rad($2, $2); mp_tan($2, $$);}
-| tASIN term %prec HIGH {mp_asin($2, $$); do_trig_typeconv(v->ttype, $$, $$);}
-| tACOS term %prec HIGH {mp_acos($2, $$); do_trig_typeconv(v->ttype, $$, $$);}
-| tATAN term %prec HIGH {mp_atan($2, $$); do_trig_typeconv(v->ttype, $$, $$);}
-| tSINH term %prec HIGH {mp_sinh($2, $$);}
-| tCOSH term %prec HIGH {mp_cosh($2, $$);}
-| tTANH term %prec HIGH {mp_tanh($2, $$);}
-| tASINH term %prec HIGH {mp_asinh($2, $$);}
-| tACOSH term %prec HIGH {mp_acosh($2, $$);}
-| tATANH term %prec HIGH {mp_atanh($2, $$);}
+ tLOG10 term %prec HIGH {mp_logarithm(10, &$2, &$$);}
+| tLOG2 term %prec HIGH {mp_logarithm(2, &$2, &$$);}
+| tSQRT term %prec HIGH {mp_sqrt(&$2, &$$);}
+| tLN term %prec HIGH {mpln(&$2, &$$);}
+| tRAND %prec HIGH {mp_set_from_random(&$$);}
+| tABS term %prec HIGH {mp_abs(&$2, &$$);}
+| tFRAC term %prec HIGH {mpcmf(&$2, &$$);}
+| tINT term %prec HIGH {mpcmim(&$2, &$$);}
+| tCHS term %prec HIGH {mp_invert_sign(&$2, &$$);}
+
+| tSIN term %prec HIGH {to_rad(&$2, &$2); mp_sin(&$2, &$$);}
+| tCOS term %prec HIGH {to_rad(&$2, &$2); mp_cos(&$2, &$$);}
+| tTAN term %prec HIGH {to_rad(&$2, &$2); mp_tan(&$2, &$$);}
+| tASIN term %prec HIGH {mp_asin(&$2, &$$); do_trig_typeconv(v->ttype, &$$, &$$);}
+| tACOS term %prec HIGH {mp_acos(&$2, &$$); do_trig_typeconv(v->ttype, &$$, &$$);}
+| tATAN term %prec HIGH {mp_atan(&$2, &$$); do_trig_typeconv(v->ttype, &$$, &$$);}
+| tSINH term %prec HIGH {mp_sinh(&$2, &$$);}
+| tCOSH term %prec HIGH {mp_cosh(&$2, &$$);}
+| tTANH term %prec HIGH {mp_tanh(&$2, &$$);}
+| tASINH term %prec HIGH {mp_asinh(&$2, &$$);}
+| tACOSH term %prec HIGH {mp_acosh(&$2, &$$);}
+| tATANH term %prec HIGH {mp_atanh(&$2, &$$);}
-| tU32 term %prec HIGH {mp_mask_u32($2, $$);}
-| tU16 term %prec HIGH {mp_mask_u16($2, $$);}
+| tU32 term %prec HIGH {mp_mask_u32(&$2, &$$);}
+| tU16 term %prec HIGH {mp_mask_u16(&$2, &$$);}
;
rcl:
tRCL '(' tNUMBER ')' {
- int val = mp_cast_to_int($3);
- register_get(val, $$);
+ int val = mp_cast_to_int(&$3);
+ register_get(val, &$$);
}
;
number:
- tNUMBER {cp($1, $$);}
+ tNUMBER {cp(&$1, &$$);}
| tANS {
- cp(display_get_answer(&v->display), $$);
+ cp(display_get_answer(&v->display), &$$);
}
;
@@ -260,8 +260,8 @@
#if 0
-| '(' lexp ')' {cp($2, $$);}
+| '(' lexp ')' {cp(&$2, &$$);}
-| term term {mpmul($1, $2, $$);}
+| term term {mpmul(&$1, &$2, &$$);}
#endif
Modified: trunk/gcalctool/ce_tokeniser.l
==============================================================================
--- trunk/gcalctool/ce_tokeniser.l (original)
+++ trunk/gcalctool/ce_tokeniser.l Mon Apr 6 01:21:05 2009
@@ -98,35 +98,35 @@
{DEC_NUM}{EXP}{DEC_NUM} {
if (v->base == HEX) REJECT;
if (strlen(yytext) > MAX_DIGITS) parser_state.error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, basevals[v->base], celval.int_t);
+mp_set_from_string(yytext, basevals[v->base], &celval.int_t);
return tNUMBER;
}
{BIN_NUM} {
if (v->base != BIN) REJECT;
if (strlen(yytext) > MAX_DIGITS) parser_state.error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, basevals[v->base], celval.int_t);
+mp_set_from_string(yytext, basevals[v->base], &celval.int_t);
return tNUMBER;
}
{OCT_NUM} {
if (v->base != OCT) REJECT;
if (strlen(yytext) > MAX_DIGITS) parser_state.error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, basevals[v->base], celval.int_t);
+mp_set_from_string(yytext, basevals[v->base], &celval.int_t);
return tNUMBER;
}
{DEC_NUM} {
if (v->base != DEC) REJECT;
if (strlen(yytext) > MAX_DIGITS) parser_state.error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, basevals[v->base], celval.int_t);
+mp_set_from_string(yytext, basevals[v->base], &celval.int_t);
return tNUMBER;
}
{HEX_NUM} {
if (v->base != HEX) REJECT;
if (strlen(yytext) > MAX_DIGITS) parser_state.error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, basevals[v->base], celval.int_t);
+mp_set_from_string(yytext, basevals[v->base], &celval.int_t);
return tNUMBER;
}
Modified: trunk/gcalctool/display.c
==============================================================================
--- trunk/gcalctool/display.c (original)
+++ trunk/gcalctool/display.c Mon Apr 6 01:21:05 2009
@@ -224,9 +224,9 @@
}
-int *display_get_answer(GCDisplay *display)
+MPNumber *display_get_answer(GCDisplay *display)
{
- return get_state(display)->ans;
+ return &get_state(display)->ans;
}
@@ -238,7 +238,7 @@
void
-display_set_number(GCDisplay *display, const int *MPval)
+display_set_number(GCDisplay *display, const MPNumber *MPval)
{
char text[MAX_DISPLAY];
display_make_number(display, text, MAX_DISPLAY, MPval, v->base, FALSE);
@@ -256,29 +256,30 @@
static void
display_refresh(GCDisplay *display)
{
- int i, MP_reg[MP_SIZE];
+ int i;
+ MPNumber MP_reg;
char localized[MAX_LOCALIZED], temp[MAX_LOCALIZED], *str, reg[3];
GCDisplayState *e;
int cursor = display_get_cursor(display);
e = get_state(display);
if (display_is_empty(display)) {
- mp_set_from_integer(0, MP_reg);
- display_make_number(display, temp, MAX_LOCALIZED, MP_reg, v->base, FALSE);
+ mp_set_from_integer(0, &MP_reg);
+ display_make_number(display, temp, MAX_LOCALIZED, &MP_reg, v->base, FALSE);
str = strdup(temp);
} else {
str = strdup(e->expression);
}
/* Substitute answer register */
- display_make_number(display, temp, MAX_LOCALIZED, e->ans, v->base, TRUE);
+ display_make_number(display, temp, MAX_LOCALIZED, &e->ans, v->base, TRUE);
str = str_replace(str, "Ans", temp);
/* Replace registers with values. */
for (i = 0; i < 10; i++) {
SNPRINTF(reg, 3, "R%d", i);
- register_get(i, MP_reg);
- display_make_number(display, temp, MAX_LOCALIZED, MP_reg, v->base, FALSE);
+ register_get(i, &MP_reg);
+ display_make_number(display, temp, MAX_LOCALIZED, &MP_reg, v->base, FALSE);
str = str_replace(str, reg, temp);
}
@@ -439,7 +440,7 @@
}
void
-display_insert_number(GCDisplay *display, int cursor, const int value[MP_SIZE])
+display_insert_number(GCDisplay *display, int cursor, const MPNumber *value)
{
char text[MAX_DISPLAY];
display_make_number(display, text, MAX_DISPLAY, value, v->base, FALSE);
@@ -452,21 +453,22 @@
{
char buf[MAX_DISPLAY] = "", buf2[MAX_DISPLAY], *t;
GCDisplayState *e = get_state(display);
- int i, MP_reg[MP_SIZE], cursor;
+ int i, cursor;
+ MPNumber MP_reg;
cursor = display_get_cursor(display);
/* If cursor is at end of the line then delete the last character preserving accuracy */
if (cursor < 0) {
if (exp_has_postfix(e->expression, "Ans")) {
- display_make_number(display, buf, MAX_DISPLAY, e->ans, v->base, FALSE);
+ display_make_number(display, buf, MAX_DISPLAY, &e->ans, v->base, FALSE);
e->expression = str_replace(e->expression, "Ans", buf);
} else {
for (i = 0; i < 10; i++) {
SNPRINTF(buf, MAX_DISPLAY, "R%d", i);
if (exp_has_postfix(e->expression, buf)) {
- register_get(i, MP_reg);
- display_make_number(display, buf2, MAX_DISPLAY, MP_reg, v->base, FALSE);
+ register_get(i, &MP_reg);
+ display_make_number(display, buf2, MAX_DISPLAY, &MP_reg, v->base, FALSE);
/* Remove "Rx" postfix and replace with backspaced number */
SNPRINTF(buf, MAX_DISPLAY, "%.*s%s", strlen(e->expression) - 2, e->expression - 3, buf2);
display_set_string(display, buf, cursor - 1);
@@ -525,7 +527,7 @@
}
gboolean
-display_is_usable_number(GCDisplay *display, int MPnum[MP_SIZE])
+display_is_usable_number(GCDisplay *display, MPNumber *MPnum)
{
if (display_is_empty(display)) {
return ce_parse("0", MPnum);
@@ -608,7 +610,7 @@
int
-display_solve(GCDisplay *display, int *result)
+display_solve(GCDisplay *display, MPNumber *result)
{
const char *text;
int errorCode;
@@ -622,14 +624,14 @@
/* Convert engineering or scientific number in the given base. */
void
-make_eng_sci(GCDisplay *display, char *target, int target_len, const int *MPnumber, int base)
+make_eng_sci(GCDisplay *display, char *target, int target_len, const MPNumber *MPnumber, int base)
{
static char digits[] = "0123456789ABCDEF";
char fixed[MAX_DIGITS], *optr;
- int MP1[MP_SIZE], MPatmp[MP_SIZE], MPval[MP_SIZE];
- int MP1base[MP_SIZE], MP3base[MP_SIZE], MP10base[MP_SIZE];
+ MPNumber MP1, MPatmp, MPval;
+ MPNumber MP1base, MP3base, MP10base;
int i, dval, len;
- int MPmant[MP_SIZE]; /* Mantissa. */
+ MPNumber MPmant; /* Mantissa. */
int ddig; /* Number of digits in exponent. */
int eng = 0; /* Set if this is an engineering number. */
int exp = 0; /* Exponent */
@@ -638,47 +640,47 @@
eng = 1;
}
optr = target;
- mp_abs(MPnumber, MPval);
- mp_set_from_integer(0, MP1);
- if (mp_is_less_than(MPnumber, MP1)) {
+ mp_abs(MPnumber, &MPval);
+ mp_set_from_integer(0, &MP1);
+ if (mp_is_less_than(MPnumber, &MP1)) {
*optr++ = '-';
}
- mp_set_from_mp(MPval, MPmant);
+ mp_set_from_mp(&MPval, &MPmant);
- mp_set_from_integer(basevals[base], MP1base);
- mppwr(MP1base, 3, MP3base);
+ mp_set_from_integer(basevals[base], &MP1base);
+ mppwr(&MP1base, 3, &MP3base);
- mppwr(MP1base, 10, MP10base);
+ mppwr(&MP1base, 10, &MP10base);
- mp_set_from_integer(1, MP1);
- mpdiv(MP1, MP10base, MPatmp);
+ mp_set_from_integer(1, &MP1);
+ mpdiv(&MP1, &MP10base, &MPatmp);
- mp_set_from_integer(0, MP1);
- if (!mp_is_equal(MPmant, MP1)) {
- while (!eng && mp_is_greater_equal(MPmant, MP10base)) {
+ mp_set_from_integer(0, &MP1);
+ if (!mp_is_equal(&MPmant, &MP1)) {
+ while (!eng && mp_is_greater_equal(&MPmant, &MP10base)) {
exp += 10;
- mpmul(MPmant, MPatmp, MPmant);
+ mpmul(&MPmant, &MPatmp, &MPmant);
}
- while ((!eng && mp_is_greater_equal(MPmant, MP1base)) ||
- (eng && (mp_is_greater_equal(MPmant, MP3base) || exp % 3 != 0))) {
+ while ((!eng && mp_is_greater_equal(&MPmant, &MP1base)) ||
+ (eng && (mp_is_greater_equal(&MPmant, &MP3base) || exp % 3 != 0))) {
exp += 1;
- mpdiv(MPmant, MP1base, MPmant);
+ mpdiv(&MPmant, &MP1base, &MPmant);
}
- while (!eng && mp_is_less_than(MPmant, MPatmp)) {
+ while (!eng && mp_is_less_than(&MPmant, &MPatmp)) {
exp -= 10;
- mpmul(MPmant, MP10base, MPmant);
+ mpmul(&MPmant, &MP10base, &MPmant);
}
- mp_set_from_integer(1, MP1);
- while (mp_is_less_than(MPmant, MP1) || (eng && exp % 3 != 0)) {
+ mp_set_from_integer(1, &MP1);
+ while (mp_is_less_than(&MPmant, &MP1) || (eng && exp % 3 != 0)) {
exp -= 1;
- mpmul(MPmant, MP1base, MPmant);
+ mpmul(&MPmant, &MP1base, &MPmant);
}
}
- mp_cast_to_string(fixed, MAX_DIGITS, MPmant, basevals[base], v->accuracy);
+ mp_cast_to_string(fixed, MAX_DIGITS, &MPmant, basevals[base], v->accuracy);
len = strlen(fixed);
for (i = 0; i < len; i++) {
*optr++ = fixed[i];
@@ -693,11 +695,11 @@
*optr++ = '+';
}
- mp_set_from_string("0.5", 10, MP1);
- mp_add_integer(MP1, exp, MPval);
- mp_set_from_integer(1, MP1);
- for (ddig = 0; mp_is_greater_equal(MPval, MP1); ddig++) {
- mpdiv(MPval, MP1base, MPval);
+ mp_set_from_string("0.5", 10, &MP1);
+ mp_add_integer(&MP1, exp, &MPval);
+ mp_set_from_integer(1, &MP1);
+ for (ddig = 0; mp_is_greater_equal(&MPval, &MP1); ddig++) {
+ mpdiv(&MPval, &MP1base, &MPval);
}
if (ddig == 0) {
@@ -705,11 +707,11 @@
}
while (ddig-- > 0) {
- mpmul(MPval, MP1base, MPval);
- dval = mp_cast_to_int(MPval);
+ mpmul(&MPval, &MP1base, &MPval);
+ dval = mp_cast_to_int(&MPval);
*optr++ = digits[dval];
dval = -dval;
- mp_add_integer(MPval, dval, MPval);
+ mp_add_integer(&MPval, dval, &MPval);
}
*optr++ = '\0';
}
@@ -717,7 +719,7 @@
/* Convert MP number to character string in the given base. */
void
-display_make_number(GCDisplay *display, char *target, int target_len, const int *MPnumber, int base, int ignoreError)
+display_make_number(GCDisplay *display, char *target, int target_len, const MPNumber *MPnumber, int base, int ignoreError)
{
static double max_fix[MAXBASES] = {
1.298074214e+33, /* Binary. */
Modified: trunk/gcalctool/display.h
==============================================================================
--- trunk/gcalctool/display.h (original)
+++ trunk/gcalctool/display.h Mon Apr 6 01:21:05 2009
@@ -31,7 +31,7 @@
/* Expression mode state */
typedef struct {
- int ans[MP_SIZE]; /* Previously calculated answer */
+ MPNumber ans; /* Previously calculated answer */
char *expression; /* Expression entered by user */
int cursor;
} GCDisplayState;
@@ -66,10 +66,10 @@
gboolean display_get_integer(GCDisplay *display, gint64 *value);
gboolean display_get_unsigned_integer(GCDisplay *display, guint64 *value);
-int *display_get_answer(GCDisplay *);
+MPNumber *display_get_answer(GCDisplay *);
int display_get_cursor(GCDisplay *);
-void display_set_number(GCDisplay *display, const int *);
+void display_set_number(GCDisplay *display, const MPNumber *);
void display_set_answer(GCDisplay *display);
void display_set_string(GCDisplay *display, const char *, int);
void display_set_cursor(GCDisplay *display, int);
@@ -82,17 +82,17 @@
gboolean display_is_undo_step(GCDisplay *display);
void display_insert(GCDisplay *display, int, const char *);
-void display_insert_number(GCDisplay *display, int, const int *);
+void display_insert_number(GCDisplay *display, int, const MPNumber *);
void display_backspace(GCDisplay *);
void display_delete(GCDisplay *);
void display_surround(GCDisplay *display, const char *, const char *);
gboolean display_is_empty(GCDisplay *);
gboolean display_is_result(GCDisplay *);
-gboolean display_is_usable_number(GCDisplay *display, int *);
+gboolean display_is_usable_number(GCDisplay *display, MPNumber *);
-int display_solve(GCDisplay *display, int *);
+int display_solve(GCDisplay *display, MPNumber *);
-void display_make_number(GCDisplay *display, char *target, int target_len, const int *MPnumber, int base, int ignoreError);
+void display_make_number(GCDisplay *display, char *target, int target_len, const MPNumber *MPnumber, int base, int ignoreError);
#endif /* DISPLAY_H */
Modified: trunk/gcalctool/financial.c
==============================================================================
--- trunk/gcalctool/financial.c (original)
+++ trunk/gcalctool/financial.c Mon Apr 6 01:21:05 2009
@@ -25,7 +25,7 @@
#include <libintl.h>
void
-calc_ctrm(int t[MP_SIZE], int pint[MP_SIZE], int fv[MP_SIZE], int pv[MP_SIZE])
+calc_ctrm(MPNumber *t, MPNumber *pint, MPNumber *fv, MPNumber *pv)
{
/* Cterm - pint (periodic interest rate).
@@ -34,19 +34,18 @@
*
* RESULT = log(fv / pv) / log(1 + pint)
*/
- int MP1[MP_SIZE], MP2[MP_SIZE], MP3[MP_SIZE], MP4[MP_SIZE];
+ MPNumber MP1, MP2, MP3, MP4;
- mpdiv(fv, pv, MP1);
- mpln(MP1, MP2);
- mp_add_integer(pint, 1, MP3);
- mpln(MP3, MP4);
- mpdiv(MP2, MP4, t);
+ mpdiv(fv, pv, &MP1);
+ mpln(&MP1, &MP2);
+ mp_add_integer(pint, 1, &MP3);
+ mpln(&MP3, &MP4);
+ mpdiv(&MP2, &MP4, t);
}
void
-calc_ddb(int t[MP_SIZE], int cost[MP_SIZE], int life[MP_SIZE],
- int period[MP_SIZE])
+calc_ddb(MPNumber *t, MPNumber *cost, MPNumber *life, MPNumber *period)
{
/* Ddb - cost (amount paid for asset).
@@ -65,16 +64,16 @@
int i;
int len;
- int MPbv[MP_SIZE], MP1[MP_SIZE], MP2[MP_SIZE];
+ MPNumber MPbv, MP1, MP2;
- mp_set_from_integer(0, MPbv);
+ mp_set_from_integer(0, &MPbv);
len = mp_cast_to_int(period);
for (i = 0; i < len; i++) {
- mp_subtract(cost, MPbv, MP1);
- mpmuli(MP1, 2, MP2);
- mpdiv(MP2, life, t);
- mp_set_from_mp(MPbv, MP1);
- mp_add(MP1, t, MPbv); /* TODO: why result is MPbv, for next loop? */
+ mp_subtract(cost, &MPbv, &MP1);
+ mpmuli(&MP1, 2, &MP2);
+ mpdiv(&MP2, life, t);
+ mp_set_from_mp(&MPbv, &MP1);
+ mp_add(&MP1, t, &MPbv); /* TODO: why result is MPbv, for next loop? */
}
if (len >= 0) {
@@ -86,7 +85,7 @@
void
-calc_fv(int t[MP_SIZE], int pmt[MP_SIZE], int pint[MP_SIZE], int n[MP_SIZE])
+calc_fv(MPNumber *t, MPNumber *pmt, MPNumber *pint, MPNumber *n)
{
/* Fv - pmt (periodic payment).
@@ -96,18 +95,18 @@
* RESULT = pmt * (pow(1 + pint, n) - 1) / pint
*/
- int MP1[MP_SIZE], MP2[MP_SIZE], MP3[MP_SIZE], MP4[MP_SIZE];
+ MPNumber MP1, MP2, MP3, MP4;
- mp_add_integer(pint, 1, MP1);
- mppwr2(MP1, n, MP2);
- mp_add_integer(MP2, -1, MP3);
- mpmul(pmt, MP3, MP4);
- mpdiv(MP4, pint, t);
+ mp_add_integer(pint, 1, &MP1);
+ mppwr2(&MP1, n, &MP2);
+ mp_add_integer(&MP2, -1, &MP3);
+ mpmul(pmt, &MP3, &MP4);
+ mpdiv(&MP4, pint, t);
}
void
-calc_gpm(int t[MP_SIZE], int cost[MP_SIZE], int margin[MP_SIZE])
+calc_gpm(MPNumber *t, MPNumber *cost, MPNumber *margin)
{
/* Gpm - cost (cost of sale).
@@ -116,16 +115,16 @@
* RESULT = cost / (1 - margin)
*/
- int MP1[MP_SIZE], MP2[MP_SIZE];
+ MPNumber MP1, MP2;
- mp_set_from_integer(1, MP1);
- mp_subtract(MP1, margin, MP2);
- mpdiv(cost, MP2, t);
+ mp_set_from_integer(1, &MP1);
+ mp_subtract(&MP1, margin, &MP2);
+ mpdiv(cost, &MP2, t);
}
void
-calc_pmt(int t[MP_SIZE], int prin[MP_SIZE], int pint[MP_SIZE], int n[MP_SIZE])
+calc_pmt(MPNumber *t, MPNumber *prin, MPNumber *pint, MPNumber *n)
{
/* Pmt - prin (principal).
@@ -135,20 +134,20 @@
* RESULT = prin * (pint / (1 - pow(pint + 1, -1 * n)))
*/
- int MP1[MP_SIZE], MP2[MP_SIZE], MP3[MP_SIZE], MP4[MP_SIZE];
+ MPNumber MP1, MP2, MP3, MP4;
- mp_add_integer(pint, 1, MP1);
- mpmuli(n, -1, MP2);
- mppwr2(MP1, MP2, MP3);
- mpmuli(MP3, -1, MP4);
- mp_add_integer(MP4, 1, MP1);
- mpdiv(pint, MP1, MP2);
- mpmul(prin, MP2, t);
+ mp_add_integer(pint, 1, &MP1);
+ mpmuli(n, -1, &MP2);
+ mppwr2(&MP1, &MP2, &MP3);
+ mpmuli(&MP3, -1, &MP4);
+ mp_add_integer(&MP4, 1, &MP1);
+ mpdiv(pint, &MP1, &MP2);
+ mpmul(prin, &MP2, t);
}
void
-calc_pv(int t[MP_SIZE], int pmt[MP_SIZE], int pint[MP_SIZE], int n[MP_SIZE])
+calc_pv(MPNumber *t, MPNumber *pmt, MPNumber *pint, MPNumber *n)
{
/* Pv - pmt (periodic payment).
@@ -158,20 +157,20 @@
* RESULT = pmt * (1 - pow(1 + pint, -1 * n)) / pint
*/
- int MP1[MP_SIZE], MP2[MP_SIZE], MP3[MP_SIZE], MP4[MP_SIZE];
+ MPNumber MP1, MP2, MP3, MP4;
- mp_add_integer(pint, 1, MP1);
- mpmuli(n, -1, MP2);
- mppwr2(MP1, MP2, MP3);
- mpmuli(MP3, -1, MP4);
- mp_add_integer(MP4, 1, MP1);
- mpdiv(MP1, pint, MP2);
- mpmul(pmt, MP2, t);
+ mp_add_integer(pint, 1, &MP1);
+ mpmuli(n, -1, &MP2);
+ mppwr2(&MP1, &MP2, &MP3);
+ mpmuli(&MP3, -1, &MP4);
+ mp_add_integer(&MP4, 1, &MP1);
+ mpdiv(&MP1, pint, &MP2);
+ mpmul(pmt, &MP2, t);
}
void
-calc_rate(int t[MP_SIZE], int fv[MP_SIZE], int pv[MP_SIZE], int n[MP_SIZE])
+calc_rate(MPNumber *t, MPNumber *fv, MPNumber *pv, MPNumber *n)
{
/* Rate - fv (future value).
@@ -181,19 +180,18 @@
* RESULT = pow(fv / pv, 1 / n) - 1
*/
- int MP1[MP_SIZE], MP2[MP_SIZE], MP3[MP_SIZE], MP4[MP_SIZE];
+ MPNumber MP1, MP2, MP3, MP4;
- mpdiv(fv, pv, MP1);
- mp_set_from_integer(1, MP2);
- mpdiv(MP2, n, MP3);
- mppwr2(MP1, MP3, MP4);
- mp_add_integer(MP4, -1, t);
+ mpdiv(fv, pv, &MP1);
+ mp_set_from_integer(1, &MP2);
+ mpdiv(&MP2, n, &MP3);
+ mppwr2(&MP1, &MP3, &MP4);
+ mp_add_integer(&MP4, -1, t);
}
void
-calc_sln(int t[MP_SIZE], int cost[MP_SIZE], int salvage[MP_SIZE],
- int life[MP_SIZE])
+calc_sln(MPNumber *t, MPNumber *cost, MPNumber *salvage, MPNumber *life)
{
/* Sln - cost (cost of the asset).
@@ -203,16 +201,14 @@
* RESULT = (cost - salvage) / life
*/
- int MP1[MP_SIZE];
-
- mp_subtract(cost, salvage, MP1);
- mpdiv(MP1, life, t);
+ MPNumber MP1;
+ mp_subtract(cost, salvage, &MP1);
+ mpdiv(&MP1, life, t);
}
void
-calc_syd(int t[MP_SIZE], int cost[MP_SIZE], int salvage[MP_SIZE],
- int life[MP_SIZE], int period[MP_SIZE])
+calc_syd(MPNumber *t, MPNumber *cost, MPNumber *salvage, MPNumber *life, MPNumber *period)
{
/* Syd - cost (cost of the asset).
@@ -224,22 +220,22 @@
* (life * (life + 1)) / 2
*/
- int MP1[MP_SIZE], MP2[MP_SIZE], MP3[MP_SIZE], MP4[MP_SIZE];
+ MPNumber MP1, MP2, MP3, MP4;
- mp_subtract(life, period, MP2);
- mp_add_integer(MP2, 1, MP3);
- mp_add_integer(life, 1, MP2);
- mpmul(life, MP2, MP4);
- mp_set_from_integer(2, MP2);
- mpdiv(MP4, MP2, MP1);
- mpdiv(MP3, MP1, MP2);
- mp_subtract(cost, salvage, MP1);
- mpmul(MP1, MP2, t);
+ mp_subtract(life, period, &MP2);
+ mp_add_integer(&MP2, 1, &MP3);
+ mp_add_integer(life, 1, &MP2);
+ mpmul(life, &MP2, &MP4);
+ mp_set_from_integer(2, &MP2);
+ mpdiv(&MP4, &MP2, &MP1);
+ mpdiv(&MP3, &MP1, &MP2);
+ mp_subtract(cost, salvage, &MP1);
+ mpmul(&MP1, &MP2, t);
}
void
-calc_term(int t[MP_SIZE], int pmt[MP_SIZE], int fv[MP_SIZE], int pint[MP_SIZE])
+calc_term(MPNumber *t, MPNumber *pmt, MPNumber *fv, MPNumber *pint)
{
/* Term - pmt (periodic payment).
@@ -249,53 +245,52 @@
* RESULT = log(1 + (fv * pint / pmt)) / log(1 + pint)
*/
- int MP1[MP_SIZE], MP2[MP_SIZE], MP3[MP_SIZE], MP4[MP_SIZE];
+ MPNumber MP1, MP2, MP3, MP4;
- mp_add_integer(pint, 1, MP1);
- mpln(MP1, MP2);
- mpmul(fv, pint, MP1);
- mpdiv(MP1, pmt, MP3);
- mp_add_integer(MP3, 1, MP4);
- mpln(MP4, MP1);
- mpdiv(MP1, MP2, t);
+ mp_add_integer(pint, 1, &MP1);
+ mpln(&MP1, &MP2);
+ mpmul(fv, pint, &MP1);
+ mpdiv(&MP1, pmt, &MP3);
+ mp_add_integer(&MP3, 1, &MP4);
+ mpln(&MP4, &MP1);
+ mpdiv(&MP1, &MP2, t);
}
void
-do_finc_expression(int function, int arg1[MP_SIZE], int arg2[MP_SIZE],
- int arg3[MP_SIZE], int arg4[MP_SIZE])
+do_finc_expression(int function, MPNumber *arg1, MPNumber *arg2, MPNumber *arg3, MPNumber *arg4)
{
- int result[MP_SIZE];
- switch (function) {
- case FINC_CTRM_DIALOG:
- calc_ctrm(result, arg1, arg2, arg3);
- break;
- case FINC_DDB_DIALOG:
- calc_ddb(result, arg1, arg2, arg3);
- break;
- case FINC_FV_DIALOG:
- calc_fv(result, arg1, arg2, arg3);
- break;
- case FINC_GPM_DIALOG:
- calc_gpm(result, arg1, arg2);
- break;
- case FINC_PMT_DIALOG:
- calc_pmt(result, arg1, arg2, arg3);
- break;
- case FINC_PV_DIALOG:
- calc_pv(result, arg1, arg2, arg3);
- break;
- case FINC_RATE_DIALOG:
- calc_rate(result, arg1, arg2, arg3);
- break;
- case FINC_SLN_DIALOG:
- calc_sln(result, arg1, arg2, arg3);
- break;
- case FINC_SYD_DIALOG:
- calc_syd(result, arg1, arg2, arg3, arg4);
- break;
- case FINC_TERM_DIALOG:
- calc_term(result, arg1, arg2, arg3);
- break;
+ MPNumber result;
+ switch (function) {
+ case FINC_CTRM_DIALOG:
+ calc_ctrm(&result, arg1, arg2, arg3);
+ break;
+ case FINC_DDB_DIALOG:
+ calc_ddb(&result, arg1, arg2, arg3);
+ break;
+ case FINC_FV_DIALOG:
+ calc_fv(&result, arg1, arg2, arg3);
+ break;
+ case FINC_GPM_DIALOG:
+ calc_gpm(&result, arg1, arg2);
+ break;
+ case FINC_PMT_DIALOG:
+ calc_pmt(&result, arg1, arg2, arg3);
+ break;
+ case FINC_PV_DIALOG:
+ calc_pv(&result, arg1, arg2, arg3);
+ break;
+ case FINC_RATE_DIALOG:
+ calc_rate(&result, arg1, arg2, arg3);
+ break;
+ case FINC_SLN_DIALOG:
+ calc_sln(&result, arg1, arg2, arg3);
+ break;
+ case FINC_SYD_DIALOG:
+ calc_syd(&result, arg1, arg2, arg3, arg4);
+ break;
+ case FINC_TERM_DIALOG:
+ calc_term(&result, arg1, arg2, arg3);
+ break;
}
- display_set_number(&v->display, result);
+ display_set_number(&v->display, &result);
}
Modified: trunk/gcalctool/financial.h
==============================================================================
--- trunk/gcalctool/financial.h (original)
+++ trunk/gcalctool/financial.h Mon Apr 6 01:21:05 2009
@@ -23,8 +23,7 @@
#include "mp.h"
-void do_finc_expression(int function, int arg1[MP_SIZE], int arg2[MP_SIZE],
- int arg3[MP_SIZE], int arg4[MP_SIZE]);
+void do_finc_expression(int function, MPNumber *arg1, MPNumber *arg2, MPNumber *arg3, MPNumber *arg4);
enum finc_dialogs {
FINC_CTRM_DIALOG,
@@ -37,7 +36,7 @@
FINC_SLN_DIALOG,
FINC_SYD_DIALOG,
FINC_TERM_DIALOG,
- FINC_NUM_DIALOGS,
+ FINC_NUM_DIALOGS,
};
#endif /* FINANCIAL_H */
Modified: trunk/gcalctool/functions.c
==============================================================================
--- trunk/gcalctool/functions.c (original)
+++ trunk/gcalctool/functions.c Mon Apr 6 01:21:05 2009
@@ -184,16 +184,16 @@
static void
do_shift(int count) /* Perform bitwise shift on display value. */
{
- int MPval[MP_SIZE];
+ MPNumber MPval;
- if (display_is_usable_number(&v->display, MPval) || !mp_is_integer(MPval)) {
+ if (display_is_usable_number(&v->display, &MPval) || !mp_is_integer(&MPval)) {
/* Translators: This message is displayed in the status bar when a bit
shift operation is performed and the display does not contain a number */
ui_set_statusbar(_("No sane value to do bitwise shift"),
"gtk-dialog-error");
}
else {
- mp_shift(MPval, display_get_answer(&v->display), count);
+ mp_shift(&MPval, display_get_answer(&v->display), count);
display_set_answer(&v->display);
}
}
@@ -203,16 +203,17 @@
static void
do_base(BaseType b)
{
- int ret, MP[MP_SIZE];
+ int ret;
+ MPNumber MP;
if (!display_is_empty(&v->display))
{
- ret = display_is_usable_number(&v->display, MP);
+ ret = display_is_usable_number(&v->display, &MP);
if (ret) {
ui_set_statusbar(_("No sane value to convert"),
"gtk-dialog-error");
} else {
- mp_set_from_mp(MP, display_get_answer(&v->display));
+ mp_set_from_mp(&MP, display_get_answer(&v->display));
display_set_answer(&v->display);
clear_undo_history();
}
@@ -229,16 +230,15 @@
static void
do_exchange(int index)
{
- int MPtemp[MP_SIZE];
- int MPexpr[MP_SIZE];
+ MPNumber MPtemp, MPexpr;
- if (display_is_usable_number(&v->display, MPexpr)) {
+ if (display_is_usable_number(&v->display, &MPexpr)) {
ui_set_statusbar(_("No sane value to store"),
"gtk-dialog-error");
} else {
- register_get(index, MPtemp);
- register_set(index, MPexpr);
- mp_set_from_mp(MPtemp, display_get_answer(&v->display));
+ register_get(index, &MPtemp);
+ register_set(index, &MPexpr);
+ mp_set_from_mp(&MPtemp, display_get_answer(&v->display));
display_set_answer(&v->display);
ui_make_registers();
}
@@ -248,17 +248,18 @@
static void
do_numtype(DisplayFormat n) /* Set number display type. */
{
- int ret, MP[MP_SIZE];
+ int ret;
+ MPNumber MP;
/* Convert display if it contains a number */
if (!display_is_empty(&v->display))
{
- ret = display_is_usable_number(&v->display, MP);
+ ret = display_is_usable_number(&v->display, &MP);
if (ret) {
ui_set_statusbar(_("No sane value to convert"),
"gtk-dialog-error");
} else {
- mp_set_from_mp(MP, display_get_answer(&v->display));
+ mp_set_from_mp(&MP, display_get_answer(&v->display));
display_set_answer(&v->display);
clear_undo_history();
}
@@ -272,13 +273,13 @@
static void
do_sto(int index)
{
- int temp[MP_SIZE];
+ MPNumber temp;
- if (display_is_usable_number(&v->display, temp))
+ if (display_is_usable_number(&v->display, &temp))
ui_set_statusbar(_("No sane value to store"),
"gtk-dialog-error");
else
- register_set(index, temp);
+ register_set(index, &temp);
ui_make_registers();
}
@@ -288,7 +289,7 @@
do_expression(int function, int arg, int cursor)
{
char buf[MAXLINE];
- int *ans;
+ MPNumber *ans;
int enabled;
guint64 bit_value;
@@ -388,14 +389,14 @@
case FN_TOGGLE_BIT:
if (display_get_unsigned_integer(&v->display, &bit_value)) {
char buf[MAX_DISPLAY];
- int MP[MP_SIZE];
+ MPNumber MP;
bit_value ^= (1LL << (63 - arg));
/* FIXME: Convert to string since we don't support setting MP numbers from 64 bit integers */
SNPRINTF(buf, MAX_DISPLAY, "%llu", bit_value);
- mp_set_from_string(buf, 10, MP);
- display_set_number(&v->display, MP);
+ mp_set_from_string(buf, 10, &MP);
+ display_set_number(&v->display, &MP);
}
break;
@@ -417,14 +418,14 @@
/* Solve the equation */
} else {
- int MPval[MP_SIZE];
+ MPNumber MPval;
int result;
const char *message = NULL;
- result = display_solve(&v->display, MPval);
+ result = display_solve(&v->display, &MPval);
switch (result) {
case 0:
- mp_set_from_mp(MPval, ans);
+ mp_set_from_mp(&MPval, ans);
display_set_answer(&v->display);
break;
Modified: trunk/gcalctool/gtk.c
==============================================================================
--- trunk/gcalctool/gtk.c (original)
+++ trunk/gcalctool/gtk.c Mon Apr 6 01:21:05 2009
@@ -1298,10 +1298,10 @@
char *ch;
if (response_id == GTK_RESPONSE_OK) {
- int value[MP_SIZE];
+ MPNumber value;
ch = (char *) gtk_entry_get_text(GTK_ENTRY(X.aframe_ch));
- mp_set_from_integer(ch[0], value);
- display_set_number(&v->display, value);
+ mp_set_from_integer(ch[0], &value);
+ display_set_number(&v->display, &value);
}
gtk_widget_hide(dialog);
@@ -1369,7 +1369,7 @@
GError *error = NULL;
screen = gtk_widget_get_screen (GTK_WIDGET (X.kframe));
- gtk_show_uri (screen, "ghelp:gcalctool", gtk_get_current_event_time (), &error);
+ //gtk_show_uri (screen, "ghelp:gcalctool", gtk_get_current_event_time (), &error);
if (error != NULL)
{
@@ -1471,7 +1471,7 @@
{
int dialog = GPOINTER_TO_INT (dialog_pointer);
int i;
- int arg[FINC_NUM_ARGS][MP_SIZE];
+ MPNumber arg[FINC_NUM_ARGS];
GtkWidget *entry;
if (response_id != GTK_RESPONSE_OK) {
return;
@@ -1483,13 +1483,13 @@
}
entry = glade_xml_get_widget(X.financial,
finc_dialog_fields[dialog][i]);
- mp_set_from_string(gtk_entry_get_text(GTK_ENTRY(entry)), 10, arg[i]);
+ mp_set_from_string(gtk_entry_get_text(GTK_ENTRY(entry)), 10, &arg[i]);
gtk_entry_set_text(GTK_ENTRY(entry), "0");
}
gtk_widget_grab_focus(glade_xml_get_widget(X.financial,
finc_dialog_fields[dialog][0]));
- do_finc_expression(dialog, arg[0], arg[1], arg[2], arg[3]);
+ do_finc_expression(dialog, &arg[0], &arg[1], &arg[2], &arg[3]);
}
@@ -1590,13 +1590,13 @@
if (id == GTK_RESPONSE_ACCEPT) {
if (gtk_tree_model_get_iter_first(X.constants_model, &iter)) {
do {
- int temp[MP_SIZE];
+ MPNumber temp;
gtk_tree_model_get(X.constants_model, &iter,
COLUMN_NUMBER, &number,
COLUMN_VALUE, &value,
COLUMN_DESCRIPTION, &description, -1);
- mp_set_from_string(value, 10, temp);
- constant_set(number, description, temp);
+ mp_set_from_string(value, 10, &temp);
+ constant_set(number, description, &temp);
} while (gtk_tree_model_iter_next(X.constants_model, &iter));
}
}
@@ -1708,15 +1708,15 @@
int n;
for (n = 0; n < MAX_REGISTERS; n++) {
- int temp[MP_SIZE];
+ MPNumber temp;
- register_get(n, temp);
- display_make_number(&v->display, mval, MAXLINE, temp, v->base, TRUE);
+ register_get(n, &temp);
+ display_make_number(&v->display, mval, MAXLINE, &temp, v->base, TRUE);
gtk_entry_set_width_chars(GTK_ENTRY(X.regs[n]), strlen(mval));
gtk_entry_set_text(GTK_ENTRY(X.regs[n]), mval);
SNPRINTF(key, MAXLINE, "register%d", n);
- display_make_number(&v->display, value, MAXLINE, temp, DEC, TRUE);
+ display_make_number(&v->display, value, MAXLINE, &temp, DEC, TRUE);
set_resource(key, value);
}
}
@@ -1792,9 +1792,9 @@
int i;
for (i = 0; i < MAX_REGISTERS; i++) {
- int temp[MP_SIZE];
- register_get(i, temp);
- display_make_number(&v->display, value, MAXLINE, temp, v->base, TRUE);
+ MPNumber temp;
+ register_get(i, &temp);
+ display_make_number(&v->display, value, MAXLINE, &temp, v->base, TRUE);
SNPRINTF(mstr, MAXLINE, "<span weight=\"bold\">%s_%d:</span> %s",
/* Translators: R is the short form of register used inter alia in popup menus */
_("R"), i, value);
Modified: trunk/gcalctool/mp-binary.c
==============================================================================
--- trunk/gcalctool/mp-binary.c (original)
+++ trunk/gcalctool/mp-binary.c Mon Apr 6 01:21:05 2009
@@ -16,7 +16,7 @@
static void
-mp_bitwise(const int s1[MP_SIZE], const int s2[MP_SIZE], int (*bitwise_operator)(int, int), int t[MP_SIZE])
+mp_bitwise(const MPNumber *s1, const MPNumber *s2, int (*bitwise_operator)(int, int), MPNumber *t)
{
char text1[MAX_DIGITS], text2[MAX_DIGITS], text_out[MAX_DIGITS];
int offset1, offset2, offset_out;
@@ -58,44 +58,44 @@
void
-mp_and(const int s1[MP_SIZE], const int s2[MP_SIZE], int t[MP_SIZE])
+mp_and(const MPNumber *s1, const MPNumber *s2, MPNumber *t)
{
mp_bitwise(s1, s2, mp_bitwise_and, t);
}
void
-mp_or(const int s1[MP_SIZE], const int s2[MP_SIZE], int t[MP_SIZE])
+mp_or(const MPNumber *s1, const MPNumber *s2, MPNumber *t)
{
mp_bitwise(s1, s2, mp_bitwise_or, t);
}
void
-mp_xor(const int s1[MP_SIZE], const int s2[MP_SIZE], int t[MP_SIZE])
+mp_xor(const MPNumber *s1, const MPNumber *s2, MPNumber *t)
{
mp_bitwise(s1, s2, mp_bitwise_xor, t);
}
void
-mp_xnor(const int s1[MP_SIZE], const int s2[MP_SIZE], int t[MP_SIZE])
+mp_xnor(const MPNumber *s1, const MPNumber *s2, MPNumber *t)
{
mp_bitwise(s1, s2, mp_bitwise_xnor, t);
}
void
-mp_not(const int s1[MP_SIZE], int t[MP_SIZE])
+mp_not(const MPNumber *s1, MPNumber *t)
{
- int dummy[MP_SIZE];
- mp_set_from_integer(0, dummy);
- mp_bitwise(s1, dummy, mp_bitwise_not, t);
+ MPNumber temp;
+ mp_set_from_integer(0, &temp);
+ mp_bitwise(s1, &temp, mp_bitwise_not, t);
}
void
-mp_mask_u32(const int s1[MP_SIZE], int t1[MP_SIZE])
+mp_mask_u32(const MPNumber *s1, MPNumber *t1)
{
char text[MAX_DIGITS];
size_t len, offset;
@@ -109,7 +109,7 @@
void
-mp_mask_u16(const int s1[MP_SIZE], int t1[MP_SIZE])
+mp_mask_u16(const MPNumber *s1, MPNumber *t1)
{
char text[MAX_DIGITS];
size_t len, offset;
@@ -123,7 +123,7 @@
void
-mp_shift(int s[MP_SIZE], int t[MP_SIZE], int times)
+mp_shift(MPNumber *s, MPNumber *t, int times)
{
int i, multiplier = 1;
@@ -133,10 +133,10 @@
mpmuli(s, multiplier, t);
}
else {
- int temp[MP_SIZE];
+ MPNumber temp;
for (i = 0; i < -times; i++)
multiplier *= 2;
- mpdivi(s, multiplier, temp);
- mpcmim(temp, t);
+ mpdivi(s, multiplier, &temp);
+ mpcmim(&temp, t);
}
}
Modified: trunk/gcalctool/mp-convert.c
==============================================================================
--- trunk/gcalctool/mp-convert.c (original)
+++ trunk/gcalctool/mp-convert.c Mon Apr 6 01:21:05 2009
@@ -35,15 +35,15 @@
* SEE IF X AND Y HAVE THE SAME ADDRESS (THEY OFTEN DO)
*/
void
-mp_set_from_mp(const int *x, int *y)
+mp_set_from_mp(const MPNumber *x, MPNumber *y)
{
/* HERE X AND Y MUST HAVE THE SAME ADDRESS */
if (x == y)
return;
/* NO NEED TO COPY X[1],X[2],... IF X[0] == 0 */
- if (x[0] == 0) {
- y[0] = 0;
+ if (x->data[0] == 0) {
+ y->data[0] = 0;
return;
}
@@ -56,7 +56,7 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mp_set_from_float(float rx, int *z)
+mp_set_from_float(float rx, MPNumber *z)
{
int i, k, i2, ib, ie, re, tp, rs;
float rb, rj;
@@ -73,7 +73,7 @@
rj = rx;
} else {
/* IF RX = 0E0 RETURN 0 */
- z[0] = 0;
+ z->data[0] = 0;
return;
}
@@ -134,7 +134,7 @@
}
void
-mp_set_from_random(int t[MP_SIZE])
+mp_set_from_random(MPNumber *t)
{
mp_set_from_double(drand48(), t);
}
@@ -147,7 +147,7 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mp_set_from_double(double dx, int *z)
+mp_set_from_double(double dx, MPNumber *z)
{
int i, k, i2, ib, ie, re, tp, rs;
double db, dj;
@@ -163,7 +163,7 @@
rs = 1;
dj = dx;
} else {
- z[0] = 0;
+ z->data[0] = 0;
return;
}
@@ -223,30 +223,30 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mp_set_from_integer(int ix, int *z)
+mp_set_from_integer(int ix, MPNumber *z)
{
mpchk(1, 4);
if (ix == 0) {
- z[0] = 0;
+ z->data[0] = 0;
return;
}
if (ix < 0) {
ix = -ix;
- z[0] = -1;
+ z->data[0] = -1;
}
else
- z[0] = 1;
+ z->data[0] = 1;
/* SET EXPONENT TO T */
- z[1] = MP.t;
+ z->data[1] = MP.t;
/* CLEAR FRACTION */
- memset(&z[2], 0, (MP.t-1)*sizeof(int));
+ memset(&z->data[2], 0, (MP.t-1)*sizeof(int));
/* INSERT IX */
- z[MP.t + 1] = ix;
+ z->data[MP.t + 1] = ix;
/* NORMALIZE BY CALLING MPMUL2 */
mpmul2(z, 1, z, 1);
@@ -254,13 +254,13 @@
/* CONVERTS THE RATIONAL NUMBER I/J TO MULTIPLE PRECISION Q. */
void
-mp_set_from_fraction(int i, int j, int *q)
+mp_set_from_fraction(int i, int j, MPNumber *q)
{
mpgcd(&i, &j);
if (j == 0) {
mperr("*** J == 0 IN CALL TO MP_SET_FROM_FRACTION ***\n");
- q[0] = 0;
+ q->data[0] = 0;
return;
}
@@ -284,21 +284,21 @@
* RETURN FROM MP_CAST_TO_INST.
*/
int
-mp_cast_to_int(const int *x)
+mp_cast_to_int(const MPNumber *x)
{
int i, j, k, j1, x2, kx, xs, izs, ret_val = 0;
- xs = x[0];
+ xs = x->data[0];
/* RETURN 0 IF X = 0 OR IF NUMBER FRACTION */
- if (xs == 0 || x[1] <= 0)
+ if (xs == 0 || x->data[1] <= 0)
return 0;
- x2 = x[1];
+ x2 = x->data[1];
for (i = 1; i <= x2; ++i) {
izs = ret_val;
ret_val = MP.b * ret_val;
if (i <= MP.t)
- ret_val += x[i + 1];
+ ret_val += x->data[i + 1];
/* CHECK FOR SIGNS OF INTEGER OVERFLOW */
if (ret_val <= 0 || ret_val <= izs)
@@ -314,7 +314,7 @@
k = x2 + 1 - i;
kx = 0;
if (k <= MP.t)
- kx = x[k + 1];
+ kx = x->data[k + 1];
if (kx != j - MP.b * j1)
return 0;
j = j1;
@@ -359,7 +359,7 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
float
-mp_cast_to_float(const int *x)
+mp_cast_to_float(const MPNumber *x)
{
float rz = 0.0;
@@ -367,12 +367,12 @@
float rb, rz2;
mpchk(1, 4);
- if (x[0] == 0)
+ if (x->data[0] == 0)
return 0.0;
rb = (float) MP.b;
for (i = 1; i <= MP.t; ++i) {
- rz = rb * rz + (float) x[i + 1];
+ rz = rb * rz + (float) x->data[i + 1];
tm = i;
/* CHECK IF FULL SINGLE-PRECISION ACCURACY ATTAINED */
@@ -382,12 +382,12 @@
}
/* NOW ALLOW FOR EXPONENT */
- rz *= mppow_ri(rb, x[1] - tm);
+ rz *= mppow_ri(rb, x->data[1] - tm);
/* CHECK REASONABLENESS OF RESULT */
/* LHS SHOULD BE <= 0.5, BUT ALLOW FOR SOME ERROR IN ALOG */
if (rz <= (float)0. ||
- fabs((float) x[1] - (log(rz) / log((float) MP.b) + (float).5)) > (float).6) {
+ fabs((float) x->data[1] - (log(rz) / log((float) MP.b) + (float).5)) > (float).6) {
/* FOLLOWING MESSAGE INDICATES THAT X IS TOO LARGE OR SMALL -
* TRY USING MPCMRE INSTEAD.
*/
@@ -395,7 +395,7 @@
return 0.0;
}
- if (x[0] < 0)
+ if (x->data[0] < 0)
rz = -(double)(rz);
return rz;
}
@@ -429,18 +429,18 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
double
-mp_cast_to_double(const int *x)
+mp_cast_to_double(const MPNumber *x)
{
int i, tm = 0;
double d__1, db, dz2, ret_val = 0.0;
mpchk(1, 4);
- if (x[0] == 0)
+ if (x->data[0] == 0)
return 0.0;
db = (double) MP.b;
for (i = 1; i <= MP.t; ++i) {
- ret_val = db * ret_val + (double) x[i + 1];
+ ret_val = db * ret_val + (double) x->data[i + 1];
tm = i;
/* CHECK IF FULL DOUBLE-PRECISION ACCURACY ATTAINED */
@@ -454,12 +454,12 @@
}
/* NOW ALLOW FOR EXPONENT */
- ret_val *= mppow_di(db, x[1] - tm);
+ ret_val *= mppow_di(db, x->data[1] - tm);
/* CHECK REASONABLENESS OF RESULT. */
/* LHS SHOULD BE .LE. 0.5 BUT ALLOW FOR SOME ERROR IN DLOG */
if (ret_val <= 0. ||
- ((d__1 = (double) ((float) x[1]) - (log(ret_val) / log((double)
+ ((d__1 = (double) ((float) x->data[1]) - (log(ret_val) / log((double)
((float) MP.b)) + .5), abs(d__1)) > .6)) {
/* FOLLOWING MESSAGE INDICATES THAT X IS TOO LARGE OR SMALL -
* TRY USING MPCMDE INSTEAD.
@@ -469,7 +469,7 @@
}
else
{
- if (x[0] < 0)
+ if (x->data[0] < 0)
ret_val = -ret_val;
return ret_val;
}
@@ -480,49 +480,49 @@
* maximum number of digits specified.
*/
void
-mp_cast_to_string(char *target, int target_len, const int *MPnumber, int base, int accuracy)
+mp_cast_to_string(char *target, int target_len, const MPNumber *MPnumber, int base, int accuracy)
{
static char digits[] = "0123456789ABCDEF";
char *optr, *start, *end, *last_non_zero;
- int number[MP_SIZE], integer_component[MP_SIZE], fractional_component[MP_SIZE], MPbase[MP_SIZE], temp[MP_SIZE];
+ MPNumber number, integer_component, fractional_component, MPbase, temp;
optr = target;
/* Insert sign */
if (mp_is_negative(MPnumber)) {
*optr++ = '-';
- mp_abs(MPnumber, number);
+ mp_abs(MPnumber, &number);
} else {
- mp_set_from_mp(MPnumber, number);
+ mp_set_from_mp(MPnumber, &number);
}
/* Add rounding factor */
- mp_set_from_integer(base, MPbase);
- mppwr(MPbase, -(accuracy+1), temp);
- mpmuli(temp, base, temp);
- mpdivi(temp, 2, temp);
- mp_add(number, temp, number);
+ mp_set_from_integer(base, &MPbase);
+ mppwr(&MPbase, -(accuracy+1), &temp);
+ mpmuli(&temp, base, &temp);
+ mpdivi(&temp, 2, &temp);
+ mp_add(&number, &temp, &number);
/* Split into integer and fractional component */
- mpcmim(number, integer_component);
- mpcmf(number, fractional_component);
+ mpcmim(&number, &integer_component);
+ mpcmf(&number, &fractional_component);
/* Write out the integer component least significant digit to most */
start = optr;
- mp_set_from_mp(integer_component, temp);
+ mp_set_from_mp(&integer_component, &temp);
do {
- int t[MP_SIZE], t2[MP_SIZE], t3[MP_SIZE];
+ MPNumber t, t2, t3;
- mpdivi(temp, base, t);
- mpcmim(t, t);
- mpmuli(t, base, t2);
+ mpdivi(&temp, base, &t);
+ mpcmim(&t, &t);
+ mpmuli(&t, base, &t2);
- mp_subtract(temp, t2, t3);
- mpcmim(t3, t3);
- *optr++ = digits[mp_cast_to_int(t3)];
+ mp_subtract(&temp, &t2, &t3);
+ mpcmim(&t3, &t3);
+ *optr++ = digits[mp_cast_to_int(&t3)];
- mp_set_from_mp(t, temp);
- } while (!mp_is_zero(temp));
+ mp_set_from_mp(&t, &temp);
+ } while (!mp_is_zero(&temp));
end = optr - 1;
/* Reverse digits */
@@ -536,7 +536,7 @@
}
/* Stop if there is no fractional component or not showing fractional part */
- if ((mp_is_zero(fractional_component) && !v->display.show_zeroes) || accuracy == 0) {
+ if ((mp_is_zero(&fractional_component) && !v->display.show_zeroes) || accuracy == 0) {
*optr = '\0';
return;
}
@@ -545,21 +545,21 @@
*optr++ = '.';
/* Write out the fractional component */
- mp_set_from_mp(fractional_component, temp);
+ mp_set_from_mp(&fractional_component, &temp);
do {
int d;
- int digit[MP_SIZE];
+ MPNumber digit;
- mpmuli(temp, base, temp);
- mpcmim(temp, digit);
- d = mp_cast_to_int(digit);
+ mpmuli(&temp, base, &temp);
+ mpcmim(&temp, &digit);
+ d = mp_cast_to_int(&digit);
*optr++ = digits[d];
if(d != 0)
last_non_zero = optr;
- mp_subtract(temp, digit, temp);
+ mp_subtract(&temp, &digit, &temp);
accuracy--;
- } while (!mp_is_zero(temp) && accuracy > 0);
+ } while (!mp_is_zero(&temp) && accuracy > 0);
/* Strip trailing zeroes */
if (!v->display.show_zeroes)
@@ -591,7 +591,7 @@
/* Convert string into an MP number, in the given base
*/
void
-mp_set_from_string(const char *str, int base, int *MPval)
+mp_set_from_string(const char *str, int base, MPNumber *MPval)
{
const char *optr;
int inum;
@@ -620,26 +620,26 @@
/* Convert fractional part */
if (*optr == '.' || *optr == *v->radix) {
- int numerator[MP_SIZE], denominator[MP_SIZE];
+ MPNumber numerator, denominator;
optr++;
- mp_set_from_integer(0, numerator);
- mp_set_from_integer(1, denominator);
+ mp_set_from_integer(0, &numerator);
+ mp_set_from_integer(1, &denominator);
while ((inum = char_val(*optr, base)) >= 0) {
- mpmuli(denominator, base, denominator);
- mpmuli(numerator, base, numerator);
- mp_add_integer(numerator, inum, numerator);
+ mpmuli(&denominator, base, &denominator);
+ mpmuli(&numerator, base, &numerator);
+ mp_add_integer(&numerator, inum, &numerator);
optr++;
}
- mpdiv(numerator, denominator, numerator);
- mp_add(MPval, numerator, MPval);
+ mpdiv(&numerator, &denominator, &numerator);
+ mp_add(MPval, &numerator, MPval);
}
/* Convert exponential part */
if (*optr == 'e' || *optr == 'E') {
int negate = 0;
- int MPbase[MP_SIZE], MPexponent[MP_SIZE], temp[MP_SIZE];
+ MPNumber MPbase, MPexponent, temp;
optr++;
@@ -652,19 +652,19 @@
}
/* Get magnitude */
- mp_set_from_integer(0, MPexponent);
+ mp_set_from_integer(0, &MPexponent);
while ((inum = char_val(*optr, base)) >= 0) {
- mpmuli(MPexponent, base, MPexponent);
- mp_add_integer(MPexponent, inum, MPexponent);
+ mpmuli(&MPexponent, base, &MPexponent);
+ mp_add_integer(&MPexponent, inum, &MPexponent);
optr++;
}
if (negate) {
- mp_invert_sign(MPexponent, MPexponent);
+ mp_invert_sign(&MPexponent, &MPexponent);
}
- mp_set_from_integer(base, MPbase);
- mppwr2(MPbase, MPexponent, temp);
- mpmul(MPval, temp, MPval);
+ mp_set_from_integer(base, &MPbase);
+ mppwr2(&MPbase, &MPexponent, &temp);
+ mpmul(MPval, &temp, MPval);
}
/* Strip trailing whitespace */
Modified: trunk/gcalctool/mp-internal.h
==============================================================================
--- trunk/gcalctool/mp-internal.h (original)
+++ trunk/gcalctool/mp-internal.h Mon Apr 6 01:21:05 2009
@@ -25,17 +25,28 @@
#define min(a, b) ((a) <= (b) ? (a) : (b))
#define max(a, b) ((a) >= (b) ? (a) : (b))
+/* Evil global variables that must be removed */
struct {
- int b, t, m, mxr, r[MP_SIZE];
+ /* Base */
+ int b;
+
+ /* Number of digits */
+ int t;
+
+ /* Min/max exponent value */
+ int m;
+
+ /* ??? */
+ int r[MP_SIZE];
} MP;
void mpchk(int i, int j);
void mpgcd(int *, int *);
-void mpmul2(int *, int, int *, int);
-void mp_get_normalized_register(int reg_sign, int *reg_exp, int *z, int trunc);
-void mpexp1(const int *, int *);
-void mpmulq(int *, int, int, int *);
-void mp_reciprocal(const int *, int *);
-void mp_atan1N(int n, int *z);
+void mpmul2(MPNumber *, int, MPNumber *, int);
+void mp_get_normalized_register(int reg_sign, int *reg_exp, MPNumber *z, int trunc);
+void mpexp1(const MPNumber *, MPNumber *);
+void mpmulq(MPNumber *, int, int, MPNumber *);
+void mp_reciprocal(const MPNumber *, MPNumber *);
+void mp_atan1N(int n, MPNumber *z);
#endif /* MP_INTERNAL_H */
Modified: trunk/gcalctool/mp-trigonometric.c
==============================================================================
--- trunk/gcalctool/mp-trigonometric.c (original)
+++ trunk/gcalctool/mp-trigonometric.c Mon Apr 6 01:21:05 2009
@@ -38,13 +38,15 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
static int
-mp_compare_mp_to_int(const int *x, int i)
+mp_compare_mp_to_int(const MPNumber *x, int i)
{
+ MPNumber t;
+
mpchk(2, 6);
/* CONVERT I TO MULTIPLE-PRECISION AND COMPARE */
- mp_set_from_integer(i, &MP.r[MP.t + 4]);
- return mp_compare_mp_to_mp(x, &MP.r[MP.t + 4]);
+ mp_set_from_integer(i, &t);
+ return mp_compare_mp_to_mp(x, &t);
}
@@ -60,66 +62,65 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
static void
-mpsin1(const int *x, int *z, int do_sin)
+mpsin1(const MPNumber *x, MPNumber *z, int do_sin)
{
- int i, b2, i2, i3, ts;
+ int i, b2, ts;
+ MPNumber t1, t2;
mpchk(3, 8);
/* SIN(0) = 0, COS(0) = 1 */
- if (x[0] == 0) {
- z[0] = 0;
+ if (x->data[0] == 0) {
+ z->data[0] = 0;
if (do_sin == 0)
mp_set_from_integer(1, z);
return;
}
- i2 = MP.t + 5;
- i3 = i2 + MP.t + 2;
b2 = max(MP.b,64) << 1;
- mpmul(x, x, &MP.r[i3 - 1]);
- if (mp_compare_mp_to_int(&MP.r[i3 - 1], 1) > 0) {
+ mpmul(x, x, &t2);
+ if (mp_compare_mp_to_int(&t2, 1) > 0) {
mperr("*** ABS(X) > 1 IN CALL TO MPSIN1 ***\n");
}
if (do_sin == 0)
- mp_set_from_integer(1, &MP.r[i2 - 1]);
+ mp_set_from_integer(1, &t1);
if (do_sin != 0)
- mp_set_from_mp(x, &MP.r[i2 - 1]);
+ mp_set_from_mp(x, &t1);
- z[0] = 0;
+ z->data[0] = 0;
i = 1;
ts = MP.t;
if (do_sin != 0) {
- mp_set_from_mp(&MP.r[i2 - 1], z);
+ mp_set_from_mp(&t1, z);
i = 2;
}
/* POWER SERIES LOOP. REDUCE T IF POSSIBLE */
do {
- MP.t = MP.r[i2] + ts + 2;
+ MP.t = t1.data[1] + ts + 2;
if (MP.t <= 2)
break;
MP.t = min(MP.t,ts);
/* PUT R(I3) FIRST IN CASE ITS DIGITS ARE MAINLY ZERO */
- mpmul(&MP.r[i3 - 1], &MP.r[i2 - 1], &MP.r[i2 - 1]);
+ mpmul(&t2, &t1, &t1);
/* IF I*(I+1) IS NOT REPRESENTABLE AS AN INTEGER, THE FOLLOWING
* DIVISION BY I*(I+1) HAS TO BE SPLIT UP.
*/
if (i > b2) {
- mpdivi(&MP.r[i2 - 1], -i, &MP.r[i2 - 1]);
- mpdivi(&MP.r[i2 - 1], i + 1, &MP.r[i2 - 1]);
+ mpdivi(&t1, -i, &t1);
+ mpdivi(&t1, i + 1, &t1);
} else {
- mpdivi(&MP.r[i2 - 1], -i * (i + 1), &MP.r[i2 - 1]);
+ mpdivi(&t1, -i * (i + 1), &t1);
}
i += 2;
MP.t = ts;
- mp_add(&MP.r[i2 - 1], z, z);
- } while(MP.r[i2 - 1] != 0);
+ mp_add(&t1, z, z);
+ } while(t1.data[0] != 0);
MP.t = ts;
if (do_sin == 0)
@@ -142,34 +143,34 @@
* 6. If (-1 < x < 0) then acos(x) = atan(sqrt(1-x^2) / x) + PI
*/
void
-mp_acos(const int *x, int *z)
+mp_acos(const MPNumber *x, MPNumber *z)
{
- int MP1[MP_SIZE], MP2[MP_SIZE];
- int MPn1[MP_SIZE], MPpi[MP_SIZE], MPy[MP_SIZE];
+ MPNumber MP1, MP2;
+ MPNumber MPn1, MPpi, MPy;
- mp_get_pi(MPpi);
- mp_set_from_integer(1, MP1);
- mp_set_from_integer(-1, MPn1);
+ mp_get_pi(&MPpi);
+ mp_set_from_integer(1, &MP1);
+ mp_set_from_integer(-1, &MPn1);
- if (mp_is_greater_than(x, MP1) || mp_is_less_than(x, MPn1)) {
+ if (mp_is_greater_than(x, &MP1) || mp_is_less_than(x, &MPn1)) {
doerr(_("Error"));
- z[0] = 0;
- } else if (x[0] == 0) {
- mpdivi(MPpi, 2, z);
- } else if (mp_is_equal(x, MP1)) {
- z[0] = 0;
- } else if (mp_is_equal(x, MPn1)) {
- mp_set_from_mp(MPpi, z);
+ z->data[0] = 0;
+ } else if (x->data[0] == 0) {
+ mpdivi(&MPpi, 2, z);
+ } else if (mp_is_equal(x, &MP1)) {
+ z->data[0] = 0;
+ } else if (mp_is_equal(x, &MPn1)) {
+ mp_set_from_mp(&MPpi, z);
} else {
- mpmul(x, x, MP2);
- mp_subtract(MP1, MP2, MP2);
- mp_sqrt(MP2, MP2);
- mpdiv(MP2, x, MP2);
- mp_atan(MP2, MPy);
- if (x[0] > 0) {
- mp_set_from_mp(MPy, z);
+ mpmul(x, x, &MP2);
+ mp_subtract(&MP1, &MP2, &MP2);
+ mp_sqrt(&MP2, &MP2);
+ mpdiv(&MP2, x, &MP2);
+ mp_atan(&MP2, &MPy);
+ if (x->data[0] > 0) {
+ mp_set_from_mp(&MPy, z);
} else {
- mp_add(MPy, MPpi, z);
+ mp_add(&MPy, &MPpi, z);
}
}
}
@@ -182,20 +183,20 @@
* 2. acosh(x) = log(x + sqrt(x^2 - 1))
*/
void
-mp_acosh(const int *x, int *z)
+mp_acosh(const MPNumber *x, MPNumber *z)
{
- int MP1[MP_SIZE];
+ MPNumber MP1;
- mp_set_from_integer(1, MP1);
- if (mp_is_less_than(x, MP1)) {
+ mp_set_from_integer(1, &MP1);
+ if (mp_is_less_than(x, &MP1)) {
doerr(_("Error"));
mp_set_from_integer(0, z);
} else {
- mpmul(x, x, MP1);
- mp_add_integer(MP1, -1, MP1);
- mp_sqrt(MP1, MP1);
- mp_add(x, MP1, MP1);
- mpln(MP1, z);
+ mpmul(x, x, &MP1);
+ mp_add_integer(&MP1, -1, &MP1);
+ mp_sqrt(&MP1, &MP1);
+ mp_add(x, &MP1, &MP1);
+ mpln(&MP1, z);
}
}
@@ -208,40 +209,38 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mp_asin(const int *x, int *z)
+mp_asin(const MPNumber *x, MPNumber *z)
{
- int i2, i3;
+ MPNumber t1, t2;
mpchk(5, 12);
- i3 = (MP.t << 2) + 11;
- if (x[0] == 0) {
- z[0] = 0;
+ if (x->data[0] == 0) {
+ z->data[0] = 0;
return;
}
- if (x[1] <= 0) {
+ if (x->data[1] <= 0) {
/* HERE ABS(X) < 1, SO USE ARCTAN(X/SQRT(1 - X^2)) */
- i2 = i3 - (MP.t + 2);
- mp_set_from_integer(1, &MP.r[i2 - 1]);
- mp_set_from_mp(&MP.r[i2 - 1], &MP.r[i3 - 1]);
- mp_subtract(&MP.r[i2 - 1], x, &MP.r[i2 - 1]);
- mp_add(&MP.r[i3 - 1], x, &MP.r[i3 - 1]);
- mpmul(&MP.r[i2 - 1], &MP.r[i3 - 1], &MP.r[i3 - 1]);
- mp_root(&MP.r[i3 - 1], -2, &MP.r[i3 - 1]);
- mpmul(x, &MP.r[i3 - 1], z);
+ mp_set_from_integer(1, &t1);
+ mp_set_from_mp(&t1, &t2);
+ mp_subtract(&t1, x, &t1);
+ mp_add(&t2, x, &t2);
+ mpmul(&t1, &t2, &t2);
+ mp_root(&t2, -2, &t2);
+ mpmul(x, &t2, z);
mp_atan(z, z);
return;
}
/* HERE ABS(X) >= 1. SEE IF X == +-1 */
- mp_set_from_integer(x[0], &MP.r[i3 - 1]);
- if (! mp_is_equal(x, &MP.r[i3 - 1])) {
+ mp_set_from_integer(x->data[0], &t2);
+ if (!mp_is_equal(x, &t2)) {
mperr("*** ABS(X) > 1 IN CALL TO MP_ASIN ***\n");
}
/* X == +-1 SO RETURN +-PI/2 */
mp_get_pi(z);
- mpdivi(z, MP.r[i3 - 1] << 1, z);
+ mpdivi(z, t2.data[0] << 1, z);
}
@@ -250,15 +249,15 @@
* 1. asinh(x) = log(x + sqrt(x^2 + 1))
*/
void
-mp_asinh(const int *x, int *z)
+mp_asinh(const MPNumber *x, MPNumber *z)
{
- int MP1[MP_SIZE];
+ MPNumber MP1;
- mpmul(x, x, MP1);
- mp_add_integer(MP1, 1, MP1);
- mp_sqrt(MP1, MP1);
- mp_add(x, MP1, MP1);
- mpln(MP1, z);
+ mpmul(x, x, &MP1);
+ mp_add_integer(&MP1, 1, &MP1);
+ mp_sqrt(&MP1, &MP1);
+ mp_add(x, &MP1, &MP1);
+ mpln(&MP1, z);
}
@@ -273,55 +272,53 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mp_atan(const int *x, int *z)
+mp_atan(const MPNumber *x, MPNumber *z)
{
- int i, q, i2, i3, ts;
+ int i, q, ts;
float rx = 0.0, ry;
-
+ MPNumber t1, t2;
mpchk(5, 12);
- i2 = MP.t * 3 + 9;
- i3 = i2 + MP.t + 2;
- if (x[0] == 0) {
- z[0] = 0;
+ if (x->data[0] == 0) {
+ z->data[0] = 0;
return;
}
- mp_set_from_mp(x, &MP.r[i3 - 1]);
- if (abs(x[1]) <= 2)
+ mp_set_from_mp(x, &t2);
+ if (abs(x->data[1]) <= 2)
rx = mp_cast_to_float(x);
q = 1;
/* REDUCE ARGUMENT IF NECESSARY BEFORE USING SERIES */
- while (MP.r[i3] >= 0)
+ while (t2.data[1] >= 0)
{
- if (MP.r[i3] == 0 && (MP.r[i3 + 1] + 1) << 1 <= MP.b)
+ if (t2.data[1] == 0 && (t2.data[2] + 1) << 1 <= MP.b)
break;
q <<= 1;
- mpmul(&MP.r[i3 - 1], &MP.r[i3 - 1], z);
+ mpmul(&t2, &t2, z);
mp_add_integer(z, 1, z);
mp_sqrt(z, z);
mp_add_integer(z, 1, z);
- mpdiv(&MP.r[i3 - 1], z, &MP.r[i3 - 1]);
+ mpdiv(&t2, z, &t2);
}
/* USE POWER SERIES NOW ARGUMENT IN (-0.5, 0.5) */
- mp_set_from_mp(&MP.r[i3 - 1], z);
- mpmul(&MP.r[i3 - 1], &MP.r[i3 - 1], &MP.r[i2 - 1]);
+ mp_set_from_mp(&t2, z);
+ mpmul(&t2, &t2, &t1);
i = 1;
ts = MP.t;
/* SERIES LOOP. REDUCE T IF POSSIBLE. */
- while ( (MP.t = ts + 2 + MP.r[i3]) > 1) {
+ while ((MP.t = ts + 2 + t2.data[1]) > 1) {
MP.t = min(MP.t,ts);
- mpmul(&MP.r[i3 - 1], &MP.r[i2 - 1], &MP.r[i3 - 1]);
- mpmulq(&MP.r[i3 - 1], -i, i + 2, &MP.r[i3 - 1]);
+ mpmul(&t2, &t1, &t2);
+ mpmulq(&t2, -i, i + 2, &t2);
i += 2;
MP.t = ts;
- mp_add(z, &MP.r[i3 - 1], z);
- if (MP.r[i3 - 1] == 0) break;
+ mp_add(z, &t2, z);
+ if (t2.data[0] == 0) break;
}
/* RESTORE T, CORRECT FOR ARGUMENT REDUCTION, AND EXIT */
@@ -331,7 +328,7 @@
/* CHECK THAT RELATIVE ERROR LESS THAN 0.01 UNLESS EXPONENT
* OF X IS LARGE (WHEN ATAN MIGHT NOT WORK)
*/
- if (abs(x[1]) > 2)
+ if (abs(x->data[1]) > 2)
return;
ry = mp_cast_to_float(z);
@@ -350,24 +347,24 @@
* 2. atanh(x) = 0.5 * log((1 + x) / (1 - x))
*/
void
-mp_atanh(const int *x, int *z)
+mp_atanh(const MPNumber *x, MPNumber *z)
{
- int MP1[MP_SIZE], MP2[MP_SIZE];
- int MP3[MP_SIZE], MPn1[MP_SIZE];
+ MPNumber MP1, MP2;
+ MPNumber MP3, MPn1;
- mp_set_from_integer(1, MP1);
- mp_set_from_integer(-1, MPn1);
+ mp_set_from_integer(1, &MP1);
+ mp_set_from_integer(-1, &MPn1);
- if (mp_is_greater_equal(x, MP1) || mp_is_less_equal(x, MPn1)) {
+ if (mp_is_greater_equal(x, &MP1) || mp_is_less_equal(x, &MPn1)) {
doerr(_("Error"));
- z[0] = 0;
+ z->data[0] = 0;
} else {
- mp_add(MP1, x, MP2);
- mp_subtract(MP1, x, MP3);
- mpdiv(MP2, MP3, MP3);
- mpln(MP3, MP3);
- mp_set_from_string("0.5", 10, MP1);
- mpmul(MP1, MP3, z);
+ mp_add(&MP1, x, &MP2);
+ mp_subtract(&MP1, x, &MP3);
+ mpdiv(&MP2, &MP3, &MP3);
+ mpln(&MP3, &MP3);
+ mp_set_from_string("0.5", 10, &MP1);
+ mpmul(&MP1, &MP3, z);
}
}
@@ -376,12 +373,12 @@
* DIMENSION OF R IN COMMON AT LEAST 5T+12.
*/
void
-mp_cos(const int *x, int *z)
+mp_cos(const MPNumber *x, MPNumber *z)
{
- int t[MP_SIZE];
+ MPNumber t;
/* COS(0) = 1 */
- if (x[0] == 0) {
+ if (x->data[0] == 0) {
mp_set_from_integer(1, z);
return;
}
@@ -398,9 +395,9 @@
/* HERE ABS(X) > 1 SO USE COS(X) = SIN(PI/2 - ABS(X)),
* COMPUTING PI/2 WITH ONE GUARD DIGIT.
*/
- mp_get_pi(t);
- mpdivi(t, 2, t);
- mp_subtract(t, z, z);
+ mp_get_pi(&t);
+ mpdivi(&t, 2, &t);
+ mp_subtract(&t, z, z);
mp_sin(z, z);
}
}
@@ -410,28 +407,27 @@
* USES MPEXP, DIMENSION OF R IN COMMON AT LEAST 5T+12
*/
void
-mp_cosh(const int *x, int *z)
+mp_cosh(const MPNumber *x, MPNumber *z)
{
- int i2;
+ MPNumber t;
/* COSH(0) == 1 */
- if (x[0] == 0) {
+ if (x->data[0] == 0) {
mp_set_from_integer(1, z);
return;
}
/* CHECK LEGALITY OF B, T, M AND MXR */
mpchk(5, 12);
- i2 = (MP.t << 2) + 11;
- mp_abs(x, &MP.r[i2 - 1]);
+ mp_abs(x, &t);
/* IF ABS(X) TOO LARGE MPEXP WILL PRINT ERROR MESSAGE
* INCREASE M TO AVOID OVERFLOW WHEN COSH(X) REPRESENTABLE
*/
MP.m += 2;
- mpexp(&MP.r[i2 - 1], &MP.r[i2 - 1]);
- mp_reciprocal(&MP.r[i2 - 1], z);
- mp_add(&MP.r[i2 - 1], z, z);
+ mpexp(&t, &t);
+ mp_reciprocal(&t, z);
+ mp_add(&t, z, z);
/* RESTORE M. IF RESULT OVERFLOWS OR UNDERFLOWS, MPDIVI WILL
* ACT ACCORDINGLY.
@@ -448,83 +444,81 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mp_sin(const int *x, int *z)
+mp_sin(const MPNumber *x, MPNumber *z)
{
- int i2, i3, ie, xs;
+ int ie, xs;
float rx = 0.0, ry;
+ MPNumber t1, t2;
mpchk(5, 12);
- i2 = (MP.t << 2) + 11;
- if (x[0] == 0) {
- z[0] = 0;
+ if (x->data[0] == 0) {
+ z->data[0] = 0;
return;
}
- xs = x[0];
- ie = abs(x[1]);
+ xs = x->data[0];
+ ie = abs(x->data[1]);
if (ie <= 2)
rx = mp_cast_to_float(x);
- mp_abs(x, &MP.r[i2 - 1]);
+ mp_abs(x, &t1);
/* USE MPSIN1 IF ABS(X) <= 1 */
- if (mp_compare_mp_to_int(&MP.r[i2 - 1], 1) <= 0)
+ if (mp_compare_mp_to_int(&t1, 1) <= 0)
{
- mpsin1(&MP.r[i2 - 1], z, 1);
+ mpsin1(&t1, z, 1);
}
/* FIND ABS(X) MODULO 2PI (IT WOULD SAVE TIME IF PI WERE
* PRECOMPUTED AND SAVED IN COMMON).
* FOR INCREASED ACCURACY COMPUTE PI/4 USING MP_ATAN1N
*/
else {
- i3 = (MP.t << 1) + 7;
- mp_atan1N(5, &MP.r[i3 - 1]);
- mpmuli(&MP.r[i3 - 1], 4, &MP.r[i3 - 1]);
+ mp_atan1N(5, &t2);
+ mpmuli(&t2, 4, &t2);
mp_atan1N(239, z);
- mp_subtract(&MP.r[i3 - 1], z, z);
- mpdiv(&MP.r[i2 - 1], z, &MP.r[i2 - 1]);
- mpdivi(&MP.r[i2 - 1], 8, &MP.r[i2 - 1]);
- mpcmf(&MP.r[i2 - 1], &MP.r[i2 - 1]);
+ mp_subtract(&t2, z, z);
+ mpdiv(&t1, z, &t1);
+ mpdivi(&t1, 8, &t1);
+ mpcmf(&t1, &t1);
/* SUBTRACT 1/2, SAVE SIGN AND TAKE ABS */
- mp_add_fraction(&MP.r[i2 - 1], -1, 2, &MP.r[i2 - 1]);
- xs = -xs * MP.r[i2 - 1];
+ mp_add_fraction(&t1, -1, 2, &t1);
+ xs = -xs * t1.data[0];
if (xs == 0) {
- z[0] = 0;
+ z->data[0] = 0;
return;
}
- MP.r[i2 - 1] = 1;
- mpmuli(&MP.r[i2 - 1], 4, &MP.r[i2 - 1]);
+ t1.data[0] = 1;
+ mpmuli(&t1, 4, &t1);
/* IF NOT LESS THAN 1, SUBTRACT FROM 2 */
- if (MP.r[i2] > 0)
- mp_add_integer(&MP.r[i2 - 1], -2, &MP.r[i2 - 1]);
+ if (t1.data[1] > 0)
+ mp_add_integer(&t1, -2, &t1);
- if (MP.r[i2 - 1] == 0) {
- z[0] = 0;
+ if (t1.data[0] == 0) {
+ z->data[0] = 0;
return;
}
- MP.r[i2 - 1] = 1;
- mpmuli(&MP.r[i2 - 1], 2, &MP.r[i2 - 1]);
+ t1.data[0] = 1;
+ mpmuli(&t1, 2, &t1);
/* NOW REDUCED TO FIRST QUADRANT, IF LESS THAN PI/4 USE
* POWER SERIES, ELSE COMPUTE COS OF COMPLEMENT
*/
- if (MP.r[i2] > 0) {
- mp_add_integer(&MP.r[i2 - 1], -2, &MP.r[i2 - 1]);
- mpmul(&MP.r[i2 - 1], z, &MP.r[i2 - 1]);
- mpsin1(&MP.r[i2 - 1], z, 0);
+ if (t1.data[1] > 0) {
+ mp_add_integer(&t1, -2, &t1);
+ mpmul(&t1, z, &t1);
+ mpsin1(&t1, z, 0);
} else {
- mpmul(&MP.r[i2 - 1], z, &MP.r[i2 - 1]);
- mpsin1(&MP.r[i2 - 1], z, 1);
+ mpmul(&t1, z, &t1);
+ mpsin1(&t1, z, 1);
}
}
- if (z[0] != 0)
- z[0] = xs;
+ z->data[0] = xs;
if (ie > 2)
return;
@@ -550,40 +544,39 @@
* SAVE SIGN OF X AND CHECK FOR ZERO, SINH(0) = 0
*/
void
-mp_sinh(const int *x, int *z)
+mp_sinh(const MPNumber *x, MPNumber *z)
{
- int i2, i3, xs;
+ int xs;
+ MPNumber t1, t2;
- xs = x[0];
+ xs = x->data[0];
if (xs == 0) {
- z[0] = 0;
+ z->data[0] = 0;
return;
}
/* CHECK LEGALITY OF B, T, M AND MXR */
mpchk(5, 12);
- i3 = (MP.t << 2) + 11;
/* WORK WITH ABS(X) */
- mp_abs(x, &MP.r[i3 - 1]);
+ mp_abs(x, &t2);
/* HERE ABS(X) < 1 SO USE MPEXP1 TO AVOID CANCELLATION */
- if (MP.r[i3] <= 0) {
- i2 = i3 - (MP.t + 2);
- mpexp1(&MP.r[i3 - 1], &MP.r[i2 - 1]);
- mp_add_integer(&MP.r[i2 - 1], 2, &MP.r[i3 - 1]);
- mpmul(&MP.r[i3 - 1], &MP.r[i2 - 1], z);
- mp_add_integer(&MP.r[i2 - 1], 1, &MP.r[i3 - 1]);
- mpdiv(z, &MP.r[i3 - 1], z);
+ if (t2.data[1] <= 0) {
+ mpexp1(&t2, &t1);
+ mp_add_integer(&t1, 2, &t2);
+ mpmul(&t2, &t1, z);
+ mp_add_integer(&t1, 1, &t2);
+ mpdiv(z, &t2, z);
}
/* HERE ABS(X) >= 1, IF TOO LARGE MPEXP GIVES ERROR MESSAGE
* INCREASE M TO AVOID OVERFLOW IF SINH(X) REPRESENTABLE
*/
else {
MP.m += 2;
- mpexp(&MP.r[i3 - 1], &MP.r[i3 - 1]);
- mp_reciprocal(&MP.r[i3 - 1], z);
- mp_subtract(&MP.r[i3 - 1], z, z);
+ mpexp(&t2, &t2);
+ mp_reciprocal(&t2, z);
+ mp_subtract(&t2, z, z);
/* RESTORE M. IF RESULT OVERFLOWS OR UNDERFLOWS, MPDIVI AT
* STATEMENT 30 WILL ACT ACCORDINGLY.
@@ -597,18 +590,18 @@
void
-mp_tan(const int x[MP_SIZE], int z[MP_SIZE])
+mp_tan(const MPNumber *x, MPNumber *z)
{
- int MPcos[MP_SIZE], MPsin[MP_SIZE];
+ MPNumber MPcos, MPsin;
- mp_sin(x, MPsin);
- mp_cos(x, MPcos);
+ mp_sin(x, &MPsin);
+ mp_cos(x, &MPcos);
/* Check if COS(x) == 0 */
- if (mp_is_zero(MPcos)) {
+ if (mp_is_zero(&MPcos)) {
doerr(_("Error, cannot calculate cosine"));
return;
}
- mpdiv(MPsin, MPcos, z);
+ mpdiv(&MPsin, &MPcos, z);
}
@@ -616,50 +609,49 @@
* USING MPEXP OR MPEXP1, SPACE = 5T+12
*/
void
-mp_tanh(const int *x, int *z)
+mp_tanh(const MPNumber *x, MPNumber *z)
{
float r__1;
-
- int i2, xs;
+ int xs;
+ MPNumber t;
/* TANH(0) = 0 */
- if (x[0] == 0) {
- z[0] = 0;
+ if (x->data[0] == 0) {
+ z->data[0] = 0;
return;
}
/* CHECK LEGALITY OF B, T, M AND MXR */
mpchk(5, 12);
- i2 = (MP.t << 2) + 11;
/* SAVE SIGN AND WORK WITH ABS(X) */
- xs = x[0];
- mp_abs(x, &MP.r[i2 - 1]);
+ xs = x->data[0];
+ mp_abs(x, &t);
/* SEE IF ABS(X) SO LARGE THAT RESULT IS +-1 */
r__1 = (float) MP.t * (float).5 * log((float) MP.b);
mp_set_from_float(r__1, z);
- if (mp_compare_mp_to_mp(&MP.r[i2 - 1], z) > 0) {
+ if (mp_compare_mp_to_mp(&t, z) > 0) {
/* HERE ABS(X) IS VERY LARGE */
mp_set_from_integer(xs, z);
return;
}
/* HERE ABS(X) NOT SO LARGE */
- mpmuli(&MP.r[i2 - 1], 2, &MP.r[i2 - 1]);
- if (MP.r[i2] > 0) {
+ mpmuli(&t, 2, &t);
+ if (t.data[1] > 0) {
/* HERE ABS(X) >= 1/2 SO USE MPEXP */
- mpexp(&MP.r[i2 - 1], &MP.r[i2 - 1]);
- mp_add_integer(&MP.r[i2 - 1], -1, z);
- mp_add_integer(&MP.r[i2 - 1], 1, &MP.r[i2 - 1]);
- mpdiv(z, &MP.r[i2 - 1], z);
+ mpexp(&t, &t);
+ mp_add_integer(&t, -1, z);
+ mp_add_integer(&t, 1, &t);
+ mpdiv(z, &t, z);
} else {
/* HERE ABS(X) < 1/2, SO USE MPEXP1 TO AVOID CANCELLATION */
- mpexp1(&MP.r[i2 - 1], &MP.r[i2 - 1]);
- mp_add_integer(&MP.r[i2 - 1], 2, z);
- mpdiv(&MP.r[i2 - 1], z, z);
+ mpexp1(&t, &t);
+ mp_add_integer(&t, 2, z);
+ mpdiv(&t, z, z);
}
/* RESTORE SIGN */
- z[0] = xs * z[0];
+ z->data[0] = xs * z->data[0];
}
Modified: trunk/gcalctool/mp.c
==============================================================================
--- trunk/gcalctool/mp.c (original)
+++ trunk/gcalctool/mp.c Mon Apr 6 01:21:05 2009
@@ -32,17 +32,17 @@
/* True if errors should be printed to stderr */
static int mp_show_errors = 0;
-static int mp_compare_mp_to_float(const int *, float);
+static int mp_compare_mp_to_float(const MPNumber *, float);
static int pow_ii(int, int);
-static void mpadd2(const int *, const int *, int *, int, int);
-static int mpadd3(const int *, const int *, int, int);
-static void mpext(int, int, int *);
-static void mplns(const int *, int *);
-static void mpmaxr(int *);
+static void mpadd2(const MPNumber *, const MPNumber *, MPNumber *, int, int);
+static int mpadd3(const MPNumber *, const MPNumber *, int, int);
+static void mpext(int, int, MPNumber *);
+static void mplns(const MPNumber *, MPNumber *);
+static void mpmaxr(MPNumber *);
static void mpmlp(int *, const int *, int, int);
-static void mpovfl(int *, const char *);
-static void mpunfl(int *);
+static void mpovfl(MPNumber *, const char *);
+static void mpunfl(MPNumber *);
void
@@ -53,10 +53,10 @@
/* SETS Y = ABS(X) FOR MP NUMBERS X AND Y */
void
-mp_abs(const int *x, int *y)
+mp_abs(const MPNumber *x, MPNumber *y)
{
mp_set_from_mp(x, y);
- y[0] = abs(y[0]);
+ y->data[0] = abs(y->data[0]);
}
@@ -65,50 +65,50 @@
* NUMBERS. FOUR GUARD DIGITS ARE USED, AND THEN R*-ROUNDING.
*/
void
-mp_add(const int *x, const int *y, int *z)
+mp_add(const MPNumber *x, const MPNumber *y, MPNumber *z)
{
- mpadd2(x, y, z, y[0], 0);
+ mpadd2(x, y, z, y->data[0], 0);
}
/* CALLED BY MP_ADD, MP_SUBTRACT ETC.
* X, Y AND Z ARE MP NUMBERS, Y_SIGN AND TRUNC ARE INTEGERS.
- * SETS Z = X + Y_SIGN*ABS(Y), WHERE Y_SIGN = +- Y[0].
+ * SETS Z = X + Y_SIGN*ABS(Y), WHERE Y_SIGN = +- y->data[0].
* IF TRUNC == 0 R*-ROUNDING IS USED, OTHERWISE TRUNCATION.
* R*-ROUNDING IS DEFINED IN KUKI AND CODI, COMM. ACM
* 16(1973), 223. (SEE ALSO BRENT, IEEE TC-22(1973), 601.)
* CHECK FOR X OR Y ZERO
*/
static void
-mpadd2(const int *x, const int *y, int *z, int y_sign, int trunc)
+mpadd2(const MPNumber *x, const MPNumber *y, MPNumber *z, int y_sign, int trunc)
{
int sign_prod;
int exp_diff, exp_result, med;
/* X = 0 OR NEGLIGIBLE, SO RESULT = +-Y */
- if (x[0] == 0) {
+ if (x->data[0] == 0) {
mp_set_from_mp(y, z);
- z[0] = y_sign;
+ z->data[0] = y_sign;
return;
}
/* Y = 0 OR NEGLIGIBLE, SO RESULT = X */
- if (y_sign == 0 || y[0] == 0) {
+ if (y_sign == 0 || y->data[0] == 0) {
mp_set_from_mp(x, z);
return;
}
/* COMPARE SIGNS */
- sign_prod = y_sign * x[0];
+ sign_prod = y_sign * x->data[0];
if (abs(sign_prod) > 1) {
mpchk(1, 4);
mperr("*** SIGN NOT 0, +1 OR -1 IN MPADD2 CALL.\n"
"POSSIBLE OVERWRITING PROBLEM ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
/* COMPARE EXPONENTS */
- exp_diff = x[1] - y[1];
+ exp_diff = x->data[1] - y->data[1];
med = abs(exp_diff);
if (exp_diff < 0) {
/* HERE EXPONENT(Y) > EXPONENT(X) */
@@ -116,7 +116,7 @@
/* 'y' so much larger than 'x' that 'x+-y = y'. Warning:
still true with rounding?? */
mp_set_from_mp(y, z);
- z[0] = y_sign;
+ z->data[0] = y_sign;
return;
}
goto L10;
@@ -136,7 +136,7 @@
larger. */
int j;
for (j = 2; j <= MP.t + 1; j++) {
- int i = x[j] - y[j];
+ int i = x->data[j] - y->data[j];
if (i < 0)
goto L10;
else if (i > 0)
@@ -144,21 +144,21 @@
}
/* both mantissas equal, so result is zero. */
- z[0] = 0;
+ z->data[0] = 0;
return;
}
}
L10:
- exp_result = y[1] + mpadd3(x, y, sign_prod, med);
+ exp_result = y->data[1] + mpadd3(x, y, sign_prod, med);
/* NORMALIZE, ROUND OR TRUNCATE, AND RETURN */
mp_get_normalized_register(y_sign, &exp_result, z, trunc);
return;
L20:
- exp_result = x[1] + mpadd3(y, x, sign_prod, med);
+ exp_result = x->data[1] + mpadd3(y, x, sign_prod, med);
/* NORMALIZE, ROUND OR TRUNCATE, AND RETURN */
- mp_get_normalized_register(x[0], &exp_result, z, trunc);
+ mp_get_normalized_register(x->data[0], &exp_result, z, trunc);
return;
}
@@ -166,7 +166,7 @@
/* CALLED BY MPADD2, DOES INNER LOOPS OF ADDITION */
/* return value is amount by which exponent needs to be increased. */
static int
-mpadd3(const int *x, const int *y, int s, int med)
+mpadd3(const MPNumber *x, const MPNumber *y, int s, int med)
{
int c, i, j, i2, i2p, ted;
@@ -185,13 +185,13 @@
/* HERE DO ADDITION, EXPONENT(Y) >= EXPONENT(X) */
while (i > MP.t) {
j = i - med;
- MP.r[i - 1] = x[j + 1];
+ MP.r[i - 1] = x->data[j + 1];
i--;
}
while (i > med) {
j = i - med;
- c = y[i + 1] + x[j + 1] + c;
+ c = y->data[i + 1] + x->data[j + 1] + c;
if (c < MP.b) {
/* NO CARRY GENERATED HERE */
@@ -207,14 +207,14 @@
while (i > 0)
{
- c = y[i + 1] + c;
+ c = y->data[i + 1] + c;
if (c < MP.b) {
MP.r[i - 1] = c;
i--;
/* NO CARRY POSSIBLE HERE */
for (; i > 0; i--)
- MP.r[i - 1] = y[i + 1];
+ MP.r[i - 1] = y->data[i + 1];
return 0;
}
@@ -239,7 +239,7 @@
while (i > MP.t) {
/* HERE DO SUBTRACTION, ABS(Y) > ABS(X) */
j = i - med;
- MP.r[i - 1] = c - x[j + 1];
+ MP.r[i - 1] = c - x->data[j + 1];
c = 0;
/* BORROW GENERATED HERE */
@@ -252,7 +252,7 @@
for(; i > med; i--) {
j = i - med;
- c = y[i + 1] + c - x[j + 1];
+ c = y->data[i + 1] + c - x->data[j + 1];
if (c >= 0) {
/* NO BORROW GENERATED HERE */
MP.r[i - 1] = c;
@@ -265,14 +265,14 @@
}
for (; i > 0; i--) {
- c = y[i + 1] + c;
+ c = y->data[i + 1] + c;
if (c >= 0) {
MP.r[i - 1] = c;
i--;
/* NO CARRY POSSIBLE HERE */
for (; i > 0; i--)
- MP.r[i - 1] = y[i + 1];
+ MP.r[i - 1] = y->data[i + 1];
return 0;
}
@@ -292,11 +292,12 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mp_add_integer(const int *x, int iy, int *z)
+mp_add_integer(const MPNumber *x, int iy, MPNumber *z)
{
+ MPNumber t;
mpchk(2, 6);
- mp_set_from_integer(iy, &MP.r[MP.t + 4]);
- mp_add(x, &MP.r[MP.t + 4], z);
+ mp_set_from_integer(iy, &t);
+ mp_add(x, &t, z);
}
@@ -305,11 +306,12 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mp_add_fraction(const int *x, int i, int j, int *y)
+mp_add_fraction(const MPNumber *x, int i, int j, MPNumber *y)
{
+ MPNumber t;
mpchk(2, 6);
- mp_set_from_fraction(i, j, &MP.r[MP.t + 4]);
- mp_add(x, &MP.r[MP.t + 4], y);
+ mp_set_from_fraction(i, j, &t);
+ mp_add(x, &t, y);
}
@@ -320,25 +322,25 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mp_atan1N(int n, int *z)
+mp_atan1N(int n, MPNumber *z)
{
- int i, b2, i2, id, ts;
+ int i, b2, id, ts;
+ MPNumber t;
mpchk(2, 6);
if (n <= 1) {
mperr("*** N <= 1 IN CALL TO MP_ATAN1N ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
- i2 = MP.t + 5;
ts = MP.t;
/* SET SUM TO X = 1/N */
mp_set_from_fraction(1, n, z);
/* SET ADDITIVE TERM TO X */
- mp_set_from_mp(z, &MP.r[i2 - 1]);
+ mp_set_from_mp(z, &t);
i = 1;
id = 0;
@@ -348,7 +350,7 @@
id = b2 * 7 * b2 / (n * n);
/* MAIN LOOP. FIRST REDUCE T IF POSSIBLE */
- while ((MP.t = ts + 2 + MP.r[i2] - z[1]) > 1) {
+ while ((MP.t = ts + 2 + t.data[1] - z->data[1]) > 1) {
MP.t = min(MP.t,ts);
@@ -356,12 +358,12 @@
* FOLLOWING HAS TO BE PERFORMED IN SEVERAL STEPS.
*/
if (i >= id) {
- mpmulq(&MP.r[i2 - 1], -i, i + 2, &MP.r[i2 - 1]);
- mpdivi(&MP.r[i2 - 1], n, &MP.r[i2 - 1]);
- mpdivi(&MP.r[i2 - 1], n, &MP.r[i2 - 1]);
+ mpmulq(&t, -i, i + 2, &t);
+ mpdivi(&t, n, &t);
+ mpdivi(&t, n, &t);
}
else {
- mpmulq(&MP.r[i2 - 1], -i, (i + 2)*n*n, &MP.r[i2 - 1]);
+ mpmulq(&t, -i, (i + 2)*n*n, &t);
}
i += 2;
@@ -370,8 +372,8 @@
MP.t = ts;
/* ADD TO SUM */
- mp_add(&MP.r[i2 - 1], z, z);
- if (MP.r[i2 - 1] == 0) break;
+ mp_add(&t, z, z);
+ if (t.data[0] == 0) break;
}
MP.t = ts;
}
@@ -403,50 +405,42 @@
/* CHECK THAT SPACE IN COMMON IS SUFFICIENT */
mx = i * MP.t + j;
- if (MP.mxr >= mx)
- return;
-
- /* HERE COMMON IS TOO SMALL, SO GIVE ERROR MESSAGE. */
- mperr("*** MXR TOO SMALL OR NOT SET TO DIM(R) BEFORE CALL TO AN MP ROUTINE ***\n"
- "*** MXR SHOULD BE AT LEAST %d*T + %d = %d ***\n*** ACTUALLY MXR = %d, AND T = %d ***\n",
- i, j, mx, MP.mxr, MP.t);
}
/* FOR MP X AND Y, RETURNS FRACTIONAL PART OF X IN Y,
* I.E., Y = X - INTEGER PART OF X (TRUNCATED TOWARDS 0).
*/
void
-mpcmf(const int *x, int *y)
+mpcmf(const MPNumber *x, MPNumber *y)
{
int offset_exp;
/* RETURN 0 IF X = 0
OR IF EXPONENT SO LARGE THAT NO FRACTIONAL PART */
- if (x[0] == 0 || x[1] >= MP.t) {
- y[0] = 0;
+ if (x->data[0] == 0 || x->data[1] >= MP.t) {
+ y->data[0] = 0;
return;
}
-
/* IF EXPONENT NOT POSITIVE CAN RETURN X */
- if (x[1] <= 0) {
+ if (x->data[1] <= 0) {
mp_set_from_mp(x, y);
return;
}
/* CLEAR ACCUMULATOR */
- offset_exp = x[1];
+ offset_exp = x->data[1];
memset(MP.r, 0, offset_exp*sizeof(int));
/* MOVE FRACTIONAL PART OF X TO ACCUMULATOR */
- memcpy (MP.r + offset_exp, x + (offset_exp + 2),
+ memcpy (MP.r + offset_exp, x->data + (offset_exp + 2),
(MP.t - offset_exp)*sizeof(int));
memset(MP.r + MP.t, 0, 4*sizeof(int));
/* NORMALIZE RESULT AND RETURN */
- mp_get_normalized_register(x[0], &offset_exp, y, 1);
+ mp_get_normalized_register(x->data[0], &offset_exp, y, 1);
}
/* RETURNS Y = INTEGER PART OF X (TRUNCATED TOWARDS 0), FOR MP X AND Y.
@@ -455,17 +449,17 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mpcmim(const int *x, int *y)
+mpcmim(const MPNumber *x, MPNumber *y)
{
int i, il;
mpchk(1, 4);
mp_set_from_mp(x, y);
- if (y[0] == 0) {
+ if (y->data[0] == 0) {
return;
}
- il = y[1] + 1;
+ il = y->data[1] + 1;
/* IF EXPONENT LARGE ENOUGH RETURN Y = X */
if (il > MP.t) {
@@ -474,13 +468,13 @@
/* IF EXPONENT SMALL ENOUGH RETURN ZERO */
if (il <= 1) {
- y[0] = 0;
+ y->data[0] = 0;
return;
}
/* SET FRACTION TO ZERO */
for (i = il; i <= MP.t; ++i) {
- y[i + 1] = 0;
+ y->data[i + 1] = 0;
}
}
@@ -492,13 +486,14 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
static int
-mp_compare_mp_to_float(const int *x, float ri)
+mp_compare_mp_to_float(const MPNumber *x, float ri)
{
+ MPNumber t;
mpchk(2, 6);
/* CONVERT RI TO MULTIPLE-PRECISION AND COMPARE */
- mp_set_from_float(ri, &MP.r[MP.t + 4]);
- return mp_compare_mp_to_mp(x, &MP.r[MP.t + 4]);
+ mp_set_from_float(ri, &t);
+ return mp_compare_mp_to_mp(x, &t);
}
/* COMPARES THE MULTIPLE-PRECISION NUMBERS X AND Y,
@@ -507,30 +502,30 @@
* AND 0 IF X == Y.
*/
int
-mp_compare_mp_to_mp(const int *x, const int *y)
+mp_compare_mp_to_mp(const MPNumber *x, const MPNumber *y)
{
int i, t2;
- if (x[0] < y[0])
+ if (x->data[0] < y->data[0])
return -1;
- if (x[0] > y[0])
+ if (x->data[0] > y->data[0])
return 1;
/* SIGN(X) == SIGN(Y), SEE IF ZERO */
- if (x[0] == 0)
+ if (x->data[0] == 0)
return 0; /* X == Y == 0 */
/* HAVE TO COMPARE EXPONENTS AND FRACTIONS */
t2 = MP.t + 2;
for (i = 2; i <= t2; ++i) {
- int i2 = x[i-1] - y[i-1];
+ int i2 = x->data[i-1] - y->data[i-1];
if (i2 < 0) {
/* ABS(X) < ABS(Y) */
- return -x[0];
+ return -x->data[0];
}
if (i2 > 0) {
/* ABS(X) > ABS(Y) */
- return x[0];
+ return x->data[0];
}
}
@@ -544,52 +539,50 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mpdiv(const int *x, const int *y, int *z)
+mpdiv(const MPNumber *x, const MPNumber *y, MPNumber *z)
{
- int i, i2, ie, iz3;
+ int i, ie, iz3;
+ MPNumber t;
mpchk(4, 10);
/* CHECK FOR DIVISION BY ZERO */
- if (y[0] == 0) {
+ if (y->data[0] == 0) {
mperr("*** ATTEMPTED DIVISION BY ZERO IN CALL TO MPDIV ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
/* CHECK FOR X = 0 */
- if (x[0] == 0) {
- z[0] = 0;
+ if (x->data[0] == 0) {
+ z->data[0] = 0;
return;
}
- /* SPACE USED BY MP_RECIPROCAL IS 4T+10 WORDS, BUT CAN OVERLAP SLIGHTLY. */
- i2 = MP.t * 3 + 9;
-
/* INCREASE M TO AVOID OVERFLOW IN MP_RECIPROCAL */
MP.m += 2;
/* FORM RECIPROCAL OF Y */
- mp_reciprocal(y, &MP.r[i2 - 1]);
+ mp_reciprocal(y, &t);
/* SET EXPONENT OF R(I2) TO ZERO TO AVOID OVERFLOW IN MPMUL */
- ie = MP.r[i2];
- MP.r[i2] = 0;
- i = MP.r[i2 + 1];
+ ie = t.data[1];
+ t.data[1] = 0;
+ i = t.data[2];
/* MULTIPLY BY X */
- mpmul(x, &MP.r[i2 - 1], z);
- iz3 = z[2];
+ mpmul(x, &t, z);
+ iz3 = z->data[2];
mpext(i, iz3, z);
/* RESTORE M, CORRECT EXPONENT AND RETURN */
MP.m += -2;
- z[1] += ie;
- if (z[1] < -MP.m) {
+ z->data[1] += ie;
+ if (z->data[1] < -MP.m) {
/* UNDERFLOW HERE */
mpunfl(z);
}
- else if (z[1] > MP.m) {
+ else if (z->data[1] > MP.m) {
/* OVERFLOW HERE */
mpovfl(z, "*** OVERFLOW OCCURRED IN MPDIV ***\n");
}
@@ -600,18 +593,17 @@
* THIS IS MUCH FASTER THAN DIVISION BY AN MP NUMBER.
*/
void
-mpdivi(const int *x, int iy, int *z)
+mpdivi(const MPNumber *x, int iy, MPNumber *z)
{
int i__1;
-
int c, i, k, b2, c2, i2, j1, j2, r1;
int j11, kh, re, iq, ir, rs, iqj;
- rs = x[0];
+ rs = x->data[0];
if (iy == 0) {
mperr("*** ATTEMPTED DIVISION BY ZERO IN CALL TO MPDIVI ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
@@ -620,7 +612,7 @@
rs = -rs;
}
- re = x[1];
+ re = x->data[1];
/* CHECK FOR ZERO DIVIDEND */
if (rs == 0) {
@@ -636,15 +628,15 @@
mpunfl(z);
return;
}
- z[0] = rs;
- z[1] = re - 1;
+ z->data[0] = rs;
+ z->data[1] = re - 1;
return;
}
/* CHECK FOR DIVISION BY 1 OR -1 */
if (iy == 1) {
mp_set_from_mp(x, z);
- z[0] = rs;
+ z->data[0] = rs;
return;
}
@@ -664,7 +656,7 @@
++i;
c = MP.b * c;
if (i <= MP.t)
- c += x[i + 1];
+ c += x->data[i + 1];
r1 = c / iy;
if (r1 < 0)
goto L210;
@@ -679,7 +671,7 @@
kh = MP.t + 1 - i;
for (k = 2; k <= kh; ++k) {
++i;
- c += x[i + 1];
+ c += x->data[i + 1];
MP.r[k - 1] = c / iy;
c = MP.b * (c - iy * MP.r[k - 1]);
}
@@ -711,7 +703,7 @@
++i;
c = MP.b * c + c2;
c2 = 0;
- if (i <= MP.t) c2 = x[i + 1];
+ if (i <= MP.t) c2 = x->data[i + 1];
if ((i__1 = c - j1) < 0)
continue;
else if (i__1 == 0) {
@@ -746,7 +738,7 @@
}
if (i <= MP.t)
- iq += x[i + 1];
+ iq += x->data[i + 1];
iqj = iq / iy;
/* R(K) = QUOTIENT, C = REMAINDER */
@@ -768,42 +760,42 @@
/* CARRY NEGATIVE SO OVERFLOW MUST HAVE OCCURRED */
mpchk(1, 4);
mperr("*** INTEGER OVERFLOW IN MPDIVI, B TOO LARGE ***\n");
- z[0] = 0;
+ z->data[0] = 0;
}
int
-mp_is_integer(int MPnum[MP_SIZE])
+mp_is_integer(const MPNumber *MPnum)
{
- int MPtt[MP_SIZE], MP0[MP_SIZE], MP1[MP_SIZE];
+ MPNumber MPtt, MP0, MP1;
/* Multiplication and division by 10000 is used to get around a
* limitation to the "fix" for Sun bugtraq bug #4006391 in the
* mpcmim() routine in mp.c, when the exponent is less than 1.
*/
- mp_set_from_integer(10000, MPtt);
- mpmul(MPnum, MPtt, MP0);
- mpdiv(MP0, MPtt, MP0);
- mpcmim(MP0, MP1);
+ mp_set_from_integer(10000, &MPtt);
+ mpmul(MPnum, &MPtt, &MP0);
+ mpdiv(&MP0, &MPtt, &MP0);
+ mpcmim(&MP0, &MP1);
- return mp_is_equal(MP0, MP1);
+ return mp_is_equal(&MP0, &MP1);
}
int
-mp_is_natural(int MPnum[MP_SIZE])
+mp_is_natural(const MPNumber *MPnum)
{
- int MP1[MP_SIZE];
+ MPNumber MP1;
if (!mp_is_integer(MPnum)) {
return 0;
}
- mp_abs(MPnum, MP1);
- return mp_is_equal(MPnum, MP1);
+ mp_abs(MPnum, &MP1);
+ return mp_is_equal(MPnum, &MP1);
}
int
-mp_is_equal(const int *x, const int *y)
+mp_is_equal(const MPNumber *x, const MPNumber *y)
{
/* RETURNS LOGICAL VALUE OF (X == Y) FOR MP X AND Y. */
return (mp_compare_mp_to_mp(x, y) == 0);
@@ -835,26 +827,23 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mpexp(const int *x, int *y)
+mpexp(const MPNumber *x, MPNumber *y)
{
float r__1;
-
- int i, i2, i3, ie, ix, ts, xs, tss;
+ int i, ie, ix, ts, xs, tss;
float rx, ry, rlb;
-
+ MPNumber t1, t2;
mpchk(4, 10);
- i2 = (MP.t << 1) + 7;
- i3 = i2 + MP.t + 2;
/* CHECK FOR X == 0 */
- if (x[0] == 0) {
+ if (x->data[0] == 0) {
mp_set_from_integer(1, y);
return;
}
/* CHECK IF ABS(X) < 1 */
- if (x[1] <= 0) {
+ if (x->data[1] <= 0) {
/* USE MPEXP1 HERE */
mpexp1(x, y);
mp_add_integer(y, 1, y);
@@ -881,23 +870,23 @@
rx = mp_cast_to_float(x);
/* SAVE SIGN AND WORK WITH ABS(X) */
- xs = x[0];
- mp_abs(x, &MP.r[i3 - 1]);
+ xs = x->data[0];
+ mp_abs(x, &t2);
/* IF ABS(X) > M POSSIBLE THAT INT(X) OVERFLOWS,
* SO DIVIDE BY 32.
*/
if (fabs(rx) > (float) MP.m) {
- mpdivi(&MP.r[i3 - 1], 32, &MP.r[i3 - 1]);
+ mpdivi(&t2, 32, &t2);
}
/* GET FRACTIONAL AND INTEGER PARTS OF ABS(X) */
- ix = mp_cast_to_int(&MP.r[i3 - 1]);
- mpcmf(&MP.r[i3 - 1], &MP.r[i3 - 1]);
+ ix = mp_cast_to_int(&t2);
+ mpcmf(&t2, &t2);
/* ATTACH SIGN TO FRACTIONAL PART AND COMPUTE EXP OF IT */
- MP.r[i3 - 1] = xs * MP.r[i3 - 1];
- mpexp1(&MP.r[i3 - 1], y);
+ t2.data[0] *= xs;
+ mpexp1(&t2, y);
mp_add_integer(y, 1, y);
/* COMPUTE E-2 OR 1/E USING TWO EXTRA DIGITS IN CASE ABS(X) LARGE
@@ -908,52 +897,50 @@
if (MP.t < 4)
ts = MP.t + 1;
MP.t = ts;
- i2 = MP.t + 5;
- i3 = i2 + MP.t + 2;
- MP.r[i3 - 1] = 0;
- mp_set_from_integer(xs, &MP.r[i2 - 1]);
+ t2.data[0] = 0;
+ mp_set_from_integer(xs, &t1);
i = 1;
/* LOOP FOR E COMPUTATION. DECREASE T IF POSSIBLE. */
/* Computing MIN */
do {
- MP.t = min(ts, ts + 2 + MP.r[i2]);
+ MP.t = min(ts, ts + 2 + t1.data[1]);
if (MP.t <= 2)
break;
++i;
- mpdivi(&MP.r[i2 - 1], i * xs, &MP.r[i2 - 1]);
+ mpdivi(&t1, i * xs, &t1);
MP.t = ts;
- mp_add(&MP.r[i3 - 1], &MP.r[i2 - 1], &MP.r[i3 - 1]);
- } while (MP.r[i2 - 1] != 0);
+ mp_add(&t2, &t1, &t2);
+ } while (t1.data[0] != 0);
/* RAISE E OR 1/E TO POWER IX */
MP.t = ts;
if (xs > 0) {
- mp_add_integer(&MP.r[i3 - 1], 2, &MP.r[i3 - 1]);
+ mp_add_integer(&t2, 2, &t2);
}
- mppwr(&MP.r[i3 - 1], ix, &MP.r[i3 - 1]);
+ mppwr(&t2, ix, &t2);
/* RESTORE T NOW */
MP.t = tss;
/* MULTIPLY EXPS OF INTEGER AND FRACTIONAL PARTS */
- mpmul(y, &MP.r[i3 - 1], y);
+ mpmul(y, &t2, y);
/* MUST CORRECT RESULT IF DIVIDED BY 32 ABOVE. */
- if (fabs(rx) > (float) MP.m && y[0] != 0) {
+ if (fabs(rx) > (float) MP.m && y->data[0] != 0) {
for (i = 1; i <= 5; ++i) {
/* SAVE EXPONENT TO AVOID OVERFLOW IN MPMUL */
- ie = y[1];
- y[1] = 0;
+ ie = y->data[1];
+ y->data[1] = 0;
mpmul(y, y, y);
- y[1] += ie << 1;
+ y->data[1] += ie << 1;
/* CHECK FOR UNDERFLOW AND OVERFLOW */
- if (y[1] < -MP.m) {
+ if (y->data[1] < -MP.m) {
mpunfl(y);
return;
}
- if (y[1] > MP.m) {
+ if (y->data[1] > MP.m) {
mpovfl(y, "*** OVERFLOW IN SUBROUTINE MPEXP ***\n");
return;
}
@@ -989,33 +976,32 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mpexp1(const int *x, int *y)
+mpexp1(const MPNumber *x, MPNumber *y)
{
- int i, q, i2, i3, ib, ic, ts;
+ int i, q, ib, ic, ts;
float rlb;
+ MPNumber t1, t2;
mpchk(3, 8);
- i2 = MP.t + 5;
- i3 = i2 + MP.t + 2;
/* CHECK FOR X = 0 */
- if (x[0] == 0) {
- y[0] = 0;
+ if (x->data[0] == 0) {
+ y->data[0] = 0;
return;
}
/* CHECK THAT ABS(X) < 1 */
- if (x[1] > 0) {
+ if (x->data[1] > 0) {
mperr("*** ABS(X) NOT LESS THAN 1 IN CALL TO MPEXP1 ***\n");
- y[0] = 0;
+ y->data[0] = 0;
return;
}
- mp_set_from_mp(x, &MP.r[i2 - 1]);
+ mp_set_from_mp(x, &t1);
rlb = log((float) MP.b);
/* COMPUTE APPROXIMATELY OPTIMAL Q (AND DIVIDE X BY 2**Q) */
- q = (int) (sqrt((float) MP.t * (float).48 * rlb) + (float) x[1] *
+ q = (int) (sqrt((float) MP.t * (float).48 * rlb) + (float) x->data[1] *
(float)1.44 * rlb);
/* HALVE Q TIMES */
@@ -1026,33 +1012,33 @@
ic <<= 1;
if (ic < ib && ic != MP.b && i < q)
continue;
- mpdivi(&MP.r[i2 - 1], ic, &MP.r[i2 - 1]);
+ mpdivi(&t1, ic, &t1);
ic = 1;
}
}
- if (MP.r[i2 - 1] == 0) {
- y[0] = 0;
+ if (t1.data[0] == 0) {
+ y->data[0] = 0;
return;
}
- mp_set_from_mp(&MP.r[i2 - 1], y);
- mp_set_from_mp(&MP.r[i2 - 1], &MP.r[i3 - 1]);
+ mp_set_from_mp(&t1, y);
+ mp_set_from_mp(&t1, &t2);
i = 1;
ts = MP.t;
/* SUM SERIES, REDUCING T WHERE POSSIBLE */
do {
- MP.t = ts + 2 + MP.r[i3] - y[1];
+ MP.t = ts + 2 + t2.data[1] - y->data[1];
if (MP.t <= 2)
break;
MP.t = min(MP.t,ts);
- mpmul(&MP.r[i2 - 1], &MP.r[i3 - 1], &MP.r[i3 - 1]);
+ mpmul(&t1, &t2, &t2);
++i;
- mpdivi(&MP.r[i3 - 1], i, &MP.r[i3 - 1]);
+ mpdivi(&t2, i, &t2);
MP.t = ts;
- mp_add(&MP.r[i3 - 1], y, y);
- } while (MP.r[i3 - 1] != 0);
+ mp_add(&t2, y, y);
+ } while (t2.data[0] != 0);
MP.t = ts;
if (q <= 0)
@@ -1060,8 +1046,8 @@
/* APPLY (X+1)**2 - 1 = X(2 + X) FOR Q ITERATIONS */
for (i = 1; i <= q; ++i) {
- mp_add_integer(y, 2, &MP.r[i2 - 1]);
- mpmul(&MP.r[i2 - 1], y, y);
+ mp_add_integer(y, 2, &t1);
+ mpmul(&t1, y, y);
}
}
@@ -1071,21 +1057,21 @@
* CAN BE. X IS AN MP NUMBER, I AND J ARE INTEGERS.
*/
static void
-mpext(int i, int j, int *x)
+mpext(int i, int j, MPNumber *x)
{
int q, s;
- if (x[0] == 0 || MP.t <= 2 || i == 0)
+ if (x->data[0] == 0 || MP.t <= 2 || i == 0)
return;
/* COMPUTE MAXIMUM POSSIBLE ERROR IN THE LAST PLACE */
q = (j + 1) / i + 1;
- s = MP.b * x[MP.t] + x[MP.t + 1];
+ s = MP.b * x->data[MP.t] + x->data[MP.t + 1];
/* SET LAST TWO DIGITS TO ZERO */
if (s <= q) {
- x[MP.t] = 0;
- x[MP.t + 1] = 0;
+ x->data[MP.t] = 0;
+ x->data[MP.t + 1] = 0;
return;
}
@@ -1093,8 +1079,8 @@
return;
/* ROUND UP HERE */
- x[MP.t] = MP.b - 1;
- x[MP.t + 1] = MP.b;
+ x->data[MP.t] = MP.b - 1;
+ x->data[MP.t + 1] = MP.b;
/* NORMALIZE X (LAST DIGIT B IS OK IN MPMULI) */
mpmuli(x, 1, x);
@@ -1139,23 +1125,23 @@
int
-mp_is_zero(const int *x)
+mp_is_zero(const MPNumber *x)
{
- return x[0] == 0;
+ return x->data[0] == 0;
}
int
-mp_is_negative(const int *x)
+mp_is_negative(const MPNumber *x)
{
- int zero[MP_SIZE];
- mp_set_from_integer(0, zero);
- return mp_is_less_than(x, zero);
+ MPNumber zero;
+ mp_set_from_integer(0, &zero);
+ return mp_is_less_than(x, &zero);
}
int
-mp_is_greater_equal(const int *x, const int *y)
+mp_is_greater_equal(const MPNumber *x, const MPNumber *y)
{
/* RETURNS LOGICAL VALUE OF (X >= Y) FOR MP X AND Y. */
return (mp_compare_mp_to_mp(x, y) >= 0);
@@ -1163,7 +1149,7 @@
int
-mp_is_greater_than(const int *x, const int *y)
+mp_is_greater_than(const MPNumber *x, const MPNumber *y)
{
/* RETURNS LOGICAL VALUE OF (X > Y) FOR MP X AND Y. */
return (mp_compare_mp_to_mp(x, y) > 0);
@@ -1171,7 +1157,7 @@
int
-mp_is_less_equal(const int *x, const int *y)
+mp_is_less_equal(const MPNumber *x, const MPNumber *y)
{
/* RETURNS LOGICAL VALUE OF (X <= Y) FOR MP X AND Y. */
return (mp_compare_mp_to_mp(x, y) <= 0);
@@ -1189,56 +1175,55 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mpln(int *x, int *y)
+mpln(MPNumber *x, MPNumber *y)
{
- int e, k, i2, i3;
+ int e, k;
float rx, rlx;
+ MPNumber t1, t2;
mpchk(6, 14);
- i2 = (MP.t << 2) + 11;
- i3 = i2 + MP.t + 2;
/* CHECK THAT X IS POSITIVE */
- if (x[0] <= 0) {
+ if (x->data[0] <= 0) {
mperr("*** X NONPOSITIVE IN CALL TO MPLN ***\n");
- y[0] = 0;
+ y->data[0] = 0;
return;
}
/* MOVE X TO LOCAL STORAGE */
- mp_set_from_mp(x, &MP.r[i2 - 1]);
- y[0] = 0;
+ mp_set_from_mp(x, &t1);
+ y->data[0] = 0;
k = 0;
/* LOOP TO GET APPROXIMATE LN(X) USING SINGLE-PRECISION */
while(1)
{
- mp_add_integer(&MP.r[i2 - 1], -1, &MP.r[i3 - 1]);
+ mp_add_integer(&t1, -1, &t2);
/* IF POSSIBLE GO TO CALL MPLNS */
- if (MP.r[i3 - 1] == 0 || MP.r[i3] + 1 <= 0) {
+ if (t2.data[0] == 0 || t2.data[1] + 1 <= 0) {
/* COMPUTE FINAL CORRECTION ACCURATELY USING MPLNS */
- mplns(&MP.r[i3 - 1], &MP.r[i3 - 1]);
- mp_add(y, &MP.r[i3 - 1], y);
+ mplns(&t2, &t2);
+ mp_add(y, &t2, y);
return;
}
/* REMOVE EXPONENT TO AVOID FLOATING-POINT OVERFLOW */
- e = MP.r[i2];
- MP.r[i2] = 0;
- rx = mp_cast_to_float(&MP.r[i2 - 1]);
+ e = t1.data[1];
+ t1.data[1] = 0;
+ rx = mp_cast_to_float(&t1);
/* RESTORE EXPONENT AND COMPUTE SINGLE-PRECISION LOG */
- MP.r[i2] = e;
+ t1.data[1] = e;
rlx = log(rx) + (float) e * log((float) MP.b);
- mp_set_from_float(-(double)rlx, &MP.r[i3 - 1]);
+ mp_set_from_float(-(double)rlx, &t2);
/* UPDATE Y AND COMPUTE ACCURATE EXP OF APPROXIMATE LOG */
- mp_subtract(y, &MP.r[i3 - 1], y);
- mpexp(&MP.r[i3 - 1], &MP.r[i3 - 1]);
+ mp_subtract(y, &t2, y);
+ mpexp(&t2, &t2);
/* COMPUTE RESIDUAL WHOSE LOG IS STILL TO BE FOUND */
- mpmul(&MP.r[i2 - 1], &MP.r[i3 - 1], &MP.r[i2 - 1]);
+ mpmul(&t1, &t2, &t1);
/* MAKE SURE NOT LOOPING INDEFINITELY */
++k;
@@ -1255,14 +1240,14 @@
* 1. log10(x) = log10(e) * log(x)
*/
void
-mp_logarithm(int n, int *MPx, int *MPretval)
+mp_logarithm(int n, MPNumber *MPx, MPNumber *MPretval)
{
- int MP1[MP_SIZE], MP2[MP_SIZE];
+ MPNumber MP1, MP2;
- mp_set_from_integer(n, MP1);
- mpln(MP1, MP1);
- mpln(MPx, MP2);
- mpdiv(MP2, MP1, MPretval);
+ mp_set_from_integer(n, &MP1);
+ mpln(&MP1, &MP1);
+ mpln(MPx, &MP2);
+ mpdiv(&MP2, &MP1, MPretval);
}
@@ -1275,38 +1260,36 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
static void
-mplns(const int *x, int *y)
+mplns(const MPNumber *x, MPNumber *y)
{
- int i2, i3, i4, ts, it0, ts2, ts3;
+ int ts, it0, ts2, ts3;
+ MPNumber t1, t2, t3;
mpchk(5, 12);
- i2 = (MP.t << 1) + 7;
- i3 = i2 + MP.t + 2;
- i4 = i3 + MP.t + 2;
/* CHECK FOR X = 0 EXACTLY */
- if (x[0] == 0) {
- y[0] = 0;
+ if (x->data[0] == 0) {
+ y->data[0] = 0;
return;
}
/* CHECK THAT ABS(X) < 1/B */
- if (x[1] + 1 > 0) {
+ if (x->data[1] + 1 > 0) {
mperr("*** ABS(X) >= 1/B IN CALL TO MPLNS ***\n");
- y[0] = 0;
+ y->data[0] = 0;
return;
}
/* SAVE T AND GET STARTING APPROXIMATION TO -LN(1+X) */
ts = MP.t;
- mp_set_from_mp(x, &MP.r[i3 - 1]);
- mpdivi(x, 4, &MP.r[i2 - 1]);
- mp_add_fraction(&MP.r[i2 - 1], -1, 3, &MP.r[i2 - 1]);
- mpmul(x, &MP.r[i2 - 1], &MP.r[i2 - 1]);
- mp_add_fraction(&MP.r[i2 - 1], 1, 2, &MP.r[i2 - 1]);
- mpmul(x, &MP.r[i2 - 1], &MP.r[i2 - 1]);
- mp_add_integer(&MP.r[i2 - 1], -1, &MP.r[i2 - 1]);
- mpmul(x, &MP.r[i2 - 1], y);
+ mp_set_from_mp(x, &t2);
+ mpdivi(x, 4, &t1);
+ mp_add_fraction(&t1, -1, 3, &t1);
+ mpmul(x, &t1, &t1);
+ mp_add_fraction(&t1, 1, 2, &t1);
+ mpmul(x, &t1, &t1);
+ mp_add_integer(&t1, -1, &t1);
+ mpmul(x, &t1, y);
/* START NEWTON ITERATION USING SMALL T, LATER INCREASE */
@@ -1318,11 +1301,11 @@
while(1)
{
- mpexp1(y, &MP.r[i4 - 1]);
- mpmul(&MP.r[i3 - 1], &MP.r[i4 - 1], &MP.r[i2 - 1]);
- mp_add(&MP.r[i4 - 1], &MP.r[i2 - 1], &MP.r[i4 - 1]);
- mp_add(&MP.r[i3 - 1], &MP.r[i4 - 1], &MP.r[i4 - 1]);
- mp_subtract(y, &MP.r[i4 - 1], y);
+ mpexp1(y, &t3);
+ mpmul(&t2, &t3, &t1);
+ mp_add(&t3, &t1, &t3);
+ mp_add(&t2, &t3, &t3);
+ mp_subtract(y, &t3, y);
if (MP.t >= ts)
break;
@@ -1342,20 +1325,20 @@
}
/* CHECK THAT NEWTON ITERATION WAS CONVERGING AS EXPECTED */
- if (MP.r[i4 - 1] != 0 && MP.r[i4] << 1 > it0 - MP.t) {
+ if (t3.data[0] != 0 && t3.data[1] << 1 > it0 - MP.t) {
mperr("*** ERROR OCCURRED IN MPLNS.\nNEWTON ITERATION NOT CONVERGING PROPERLY ***\n");
}
}
/* REVERSE SIGN OF Y AND RETURN */
- y[0] = -y[0];
+ y->data[0] = -y->data[0];
MP.t = ts;
}
/* RETURNS LOGICAL VALUE OF (X < Y) FOR MP X AND Y. */
int
-mp_is_less_than(const int *x, const int *y)
+mp_is_less_than(const MPNumber *x, const MPNumber *y)
{
return (mp_compare_mp_to_mp(x, y) < 0);
}
@@ -1365,7 +1348,7 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
static void
-mpmaxr(int *x)
+mpmaxr(MPNumber *x)
{
int i, it;
@@ -1374,11 +1357,11 @@
/* SET FRACTION DIGITS TO B-1 */
for (i = 1; i <= MP.t; i++)
- x[i + 1] = it;
+ x->data[i + 1] = it;
/* SET SIGN AND EXPONENT */
- x[0] = 1;
- x[1] = MP.m;
+ x->data[0] = 1;
+ x->data[1] = MP.m;
}
@@ -1409,7 +1392,7 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mpmul(const int *x, const int *y, int *z)
+mpmul(const MPNumber *x, const MPNumber *y, MPNumber *z)
{
int i__1;
@@ -1420,15 +1403,15 @@
i2p = i2 + 1;
/* FORM SIGN OF PRODUCT */
- rs = x[0] * y[0];
+ rs = x->data[0] * y->data[0];
if (rs == 0) {
/* SET RESULT TO ZERO */
- z[0] = 0;
+ z->data[0] = 0;
return;
}
/* FORM EXPONENT OF PRODUCT */
- re = x[1] + y[1];
+ re = x->data[1] + y->data[1];
/* CLEAR ACCUMULATOR */
for (i = 1; i <= i2; ++i)
@@ -1438,14 +1421,14 @@
c = 8;
i__1 = MP.t;
for (i = 1; i <= i__1; ++i) {
- xi = x[i + 1];
+ xi = x->data[i + 1];
/* FOR SPEED, PUT THE NUMBER WITH MANY ZEROS FIRST */
if (xi == 0)
continue;
/* Computing MIN */
- mpmlp(&MP.r[i], &y[2], xi, min(MP.t, i2 - i));
+ mpmlp(&MP.r[i], &y->data[2], xi, min(MP.t, i2 - i));
--c;
if (c > 0)
continue;
@@ -1453,7 +1436,7 @@
/* CHECK FOR LEGAL BASE B DIGIT */
if (xi < 0 || xi >= MP.b) {
mperr("*** ILLEGAL BASE B DIGIT IN CALL TO MPMUL.\nPOSSIBLE OVERWRITING PROBLEM ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
@@ -1465,7 +1448,7 @@
ri = MP.r[j1 - 1] + c;
if (ri < 0) {
mperr("*** INTEGER OVERFLOW IN MPMUL, B TOO LARGE ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
c = ri / MP.b;
@@ -1473,7 +1456,7 @@
}
if (c != 0) {
mperr("*** ILLEGAL BASE B DIGIT IN CALL TO MPMUL.\nPOSSIBLE OVERWRITING PROBLEM ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
c = 8;
@@ -1482,7 +1465,7 @@
if (c != 8) {
if (xi < 0 || xi >= MP.b) {
mperr("*** ILLEGAL BASE B DIGIT IN CALL TO MPMUL.\nPOSSIBLE OVERWRITING PROBLEM ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
@@ -1492,7 +1475,7 @@
ri = MP.r[j1 - 1] + c;
if (ri < 0) {
mperr("*** INTEGER OVERFLOW IN MPMUL, B TOO LARGE ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
c = ri / MP.b;
@@ -1501,7 +1484,7 @@
if (c != 0) {
mperr("*** ILLEGAL BASE B DIGIT IN CALL TO MPMUL.\nPOSSIBLE OVERWRITING PROBLEM ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
}
@@ -1517,14 +1500,14 @@
* RESULT IS ROUNDED IF TRUNC == 0, OTHERWISE TRUNCATED.
*/
void
-mpmul2(int *x, int iy, int *z, int trunc)
+mpmul2(MPNumber *x, int iy, MPNumber *z, int trunc)
{
int c, i, c1, c2, j1, j2;
int t1, t3, t4, ij, re, ri = 0, is, ix, rs;
- rs = x[0];
+ rs = x->data[0];
if (rs == 0 || iy == 0) {
- z[0] = 0;
+ z->data[0] = 0;
return;
}
@@ -1534,10 +1517,10 @@
/* CHECK FOR MULTIPLICATION BY B */
if (iy == MP.b) {
- if (x[1] < MP.m) {
+ if (x->data[1] < MP.m) {
mp_set_from_mp(x, z);
- z[0] = rs;
- z[1] = x[1] + 1;
+ z->data[0] = rs;
+ z->data[1] = x->data[1] + 1;
}
else {
mpchk(1, 4);
@@ -1548,7 +1531,7 @@
}
/* SET EXPONENT TO EXPONENT(X) + 4 */
- re = x[1] + 4;
+ re = x->data[1] + 4;
/* FORM PRODUCT IN ACCUMULATOR */
c = 0;
@@ -1573,7 +1556,7 @@
i = t1 - ij;
ix = 0;
if (i > 0)
- ix = x[i + 1];
+ ix = x->data[i + 1];
ri = j2 * ix + c2;
is = ri / MP.b;
c = j1 * ix + c1 + is;
@@ -1584,7 +1567,7 @@
{
for (ij = 1; ij <= MP.t; ++ij) {
i = t1 - ij;
- ri = iy * x[i + 1] + c;
+ ri = iy * x->data[i + 1] + c;
c = ri / MP.b;
MP.r[i + 3] = ri - MP.b * c;
}
@@ -1593,7 +1576,7 @@
if (ri < 0) {
mpchk(1, 4);
mperr("*** INTEGER OVERFLOW IN MPMUL2, B TOO LARGE ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
@@ -1618,7 +1601,7 @@
if (c < 0) {
mpchk(1, 4);
mperr("*** INTEGER OVERFLOW IN MPMUL2, B TOO LARGE ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
@@ -1635,7 +1618,7 @@
void
-mpmuli(int *x, int iy, int *z)
+mpmuli(MPNumber *x, int iy, MPNumber *z)
{
/* MULTIPLIES MP X BY SINGLE-PRECISION INTEGER IY GIVING MP Z.
@@ -1650,19 +1633,19 @@
/* MULTIPLIES MP X BY I/J, GIVING MP Y */
void
-mpmulq(int *x, int i, int j, int *y)
+mpmulq(MPNumber *x, int i, int j, MPNumber *y)
{
int is, js;
if (j == 0) {
mpchk(1, 4);
mperr("*** ATTEMPTED DIVISION BY ZERO IN MPMULQ ***\n");
- y[0] = 0;
+ y->data[0] = 0;
return;
}
if (i == 0) {
- y[0] = 0;
+ y->data[0] = 0;
return;
}
@@ -1682,10 +1665,10 @@
/* SETS Y = -X FOR MP NUMBERS X AND Y */
void
-mp_invert_sign(const int *x, int *y)
+mp_invert_sign(const MPNumber *x, MPNumber *y)
{
mp_set_from_mp(x, y);
- y[0] = -y[0];
+ y->data[0] = -y->data[0];
}
@@ -1695,7 +1678,7 @@
* NOT PRESERVED. R*-ROUNDING IS USED IF TRUNC == 0
*/
void
-mp_get_normalized_register(int reg_sign, int *reg_exp, int *z, int trunc)
+mp_get_normalized_register(int reg_sign, int *reg_exp, MPNumber *z, int trunc)
{
int i__1;
@@ -1705,7 +1688,7 @@
i2 = MP.t + 4;
if (reg_sign == 0) {
/* STORE ZERO IN Z */
- z[0] = 0;
+ z->data[0] = 0;
return;
}
@@ -1713,7 +1696,7 @@
if (abs(reg_sign) > 1) {
mperr("*** SIGN NOT 0, +1 OR -1 IN CALL TO MP_GET_NORMALIZED_REGISTER.\n"
"POSSIBLE OVERWRITING PROBLEM ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
@@ -1726,7 +1709,7 @@
/* FRACTION ZERO */
if (i > i2) {
- z[0] = 0;
+ z->data[0] = 0;
return;
}
@@ -1811,10 +1794,10 @@
}
/* STORE RESULT IN Z */
- z[0] = reg_sign;
- z[1] = *reg_exp;
+ z->data[0] = reg_sign;
+ z->data[1] = *reg_exp;
for (i = 1; i <= MP.t; ++i)
- z[i + 1] = MP.r[i - 1];
+ z->data[i + 1] = MP.r[i - 1];
}
@@ -1828,7 +1811,7 @@
* M MAY HAVE BEEN OVERWRITTEN, SO CHECK B, T, M ETC.
*/
static void
-mpovfl(int *x, const char *error)
+mpovfl(MPNumber *x, const char *error)
{
if (mp_show_errors) {
fprintf(stderr, "%s", error);
@@ -1851,25 +1834,20 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mp_get_pi(int *z)
+mp_get_pi(MPNumber *z)
{
- int i2;
float prec;
-
+ MPNumber t;
mpchk(3, 8);
-/* ALLOW SPACE FOR MP_ATAN1N */
-
- i2 = (MP.t << 1) + 7;
- mp_atan1N(5, &MP.r[i2 - 1]);
- mpmuli(&MP.r[i2 - 1], 4, &MP.r[i2 - 1]);
+ mp_atan1N(5, &t);
+ mpmuli(&t, 4, &t);
mp_atan1N(239, z);
- mp_subtract(&MP.r[i2 - 1], z, z);
+ mp_subtract(&t, z, z);
mpmuli(z, 4, z);
-/* RETURN IF ERROR IS LESS THAN 0.01 */
-
+ /* RETURN IF ERROR IS LESS THAN 0.01 */
prec = fabs(mp_cast_to_float(z) - 3.1416);
if (prec < 0.01) return;
@@ -1883,19 +1861,19 @@
* (2T+6 IS ENOUGH IF N NONNEGATIVE).
*/
void
-mppwr(const int *x, int n, int *y)
+mppwr(const MPNumber *x, int n, MPNumber *y)
{
- int i2, n2, ns;
+ int n2, ns;
+ MPNumber t;
- i2 = MP.t + 5;
n2 = n;
if (n2 < 0) {
/* N < 0 */
mpchk(4, 10);
n2 = -n2;
- if (x[0] == 0) {
+ if (x->data[0] == 0) {
mperr("*** ATTEMPT TO RAISE ZERO TO NEGATIVE POWER IN CALL TO SUBROUTINE MPPWR ***\n");
- y[0] = 0;
+ y->data[0] = 0;
return;
}
} else if (n2 == 0) {
@@ -1905,8 +1883,8 @@
} else {
/* N > 0 */
mpchk(2, 6);
- if (x[0] == 0) {
- y[0] = 0;
+ if (x->data[0] == 0) {
+ y->data[0] = 0;
return;
}
}
@@ -1917,7 +1895,7 @@
/* IF N < 0 FORM RECIPROCAL */
if (n < 0)
mp_reciprocal(y, y);
- mp_set_from_mp(y, &MP.r[i2 - 1]);
+ mp_set_from_mp(y, &t);
/* SET PRODUCT TERM TO ONE */
mp_set_from_integer(1, y);
@@ -1927,11 +1905,11 @@
ns = n2;
n2 /= 2;
if (n2 << 1 != ns)
- mpmul(y, &MP.r[i2 - 1], y);
+ mpmul(y, &t, y);
if (n2 <= 0)
return;
- mpmul(&MP.r[i2 - 1], &MP.r[i2 - 1], &MP.r[i2 - 1]);
+ mpmul(&t, &t, &t);
}
}
@@ -1943,32 +1921,31 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mppwr2(int *x, int *y, int *z)
+mppwr2(MPNumber *x, MPNumber *y, MPNumber *z)
{
- int i2;
-
+ MPNumber t;
+
mpchk(7, 16);
- if (x[0] < 0) {
+ if (x->data[0] < 0) {
display_set_error(&v->display, _("Negative X and non-integer Y not supported"));
mperr("*** Negative X and non-integer Y not supported ***\n");
- z[0] = 0;
+ z->data[0] = 0;
}
- else if (x[0] == 0)
+ else if (x->data[0] == 0)
{
/* HERE X IS ZERO, RETURN ZERO IF Y POSITIVE, OTHERWISE ERROR */
- if (y[0] <= 0) {
+ if (y->data[0] <= 0) {
mperr("*** X ZERO AND Y NONPOSITIVE IN CALL TO MPPWR2 ***\n");
}
- z[0] = 0;
+ z->data[0] = 0;
}
else {
/* USUAL CASE HERE, X POSITIVE
* USE MPLN AND MPEXP TO COMPUTE POWER
*/
- i2 = MP.t * 6 + 15;
- mpln(x, &MP.r[i2 - 1]);
- mpmul(y, &MP.r[i2 - 1], z);
+ mpln(x, &t);
+ mpmul(y, &t, z);
/* IF X**Y IS TOO LARGE, MPEXP WILL PRINT ERROR MESSAGE */
mpexp(z, z);
@@ -1984,44 +1961,42 @@
* NOT BE CORRECT.
*/
void
-mp_reciprocal(const int *x, int *z)
+mp_reciprocal(const MPNumber *x, MPNumber *z)
{
/* Initialized data */
static int it[9] = { 0, 8, 6, 5, 4, 4, 4, 4, 4 };
- int tmp_x[MP_SIZE];
+ MPNumber tmp_x, t1, t2;
- int i2, i3, ex, ts, it0, ts2, ts3;
+ int ex, ts, it0, ts2, ts3;
float rx;
/* CHECK LEGALITY OF B, T, M AND MXR */
mpchk(4, 10);
/* MP_ADD_INTEGER REQUIRES 2T+6 WORDS. */
- i2 = (MP.t << 1) + 7;
- i3 = i2 + MP.t + 2;
- if (x[0] == 0) {
+ if (x->data[0] == 0) {
mperr("*** ATTEMPTED DIVISION BY ZERO IN CALL TO MP_RECIPROCAL ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
- ex = x[1];
+ ex = x->data[1];
/* TEMPORARILY INCREASE M TO AVOID OVERFLOW */
MP.m += 2;
/* SET EXPONENT TO ZERO SO RX NOT TOO LARGE OR SMALL. */
/* work-around to avoid touching X */
- mp_set_from_mp(x, tmp_x);
- tmp_x[1] = 0;
- rx = mp_cast_to_float(tmp_x);
+ mp_set_from_mp(x, &tmp_x);
+ tmp_x.data[1] = 0;
+ rx = mp_cast_to_float(&tmp_x);
/* USE SINGLE-PRECISION RECIPROCAL AS FIRST APPROXIMATION */
- mp_set_from_float((float)1. / rx, &MP.r[i2 - 1]);
+ mp_set_from_float((float)1. / rx, &t1);
/* CORRECT EXPONENT OF FIRST APPROXIMATION */
- MP.r[i2] -= ex;
+ t1.data[1] -= ex;
/* SAVE T (NUMBER OF DIGITS) */
ts = MP.t;
@@ -2035,17 +2010,17 @@
if (MP.t <= ts) {
/* MAIN ITERATION LOOP */
while(1) {
- mpmul(x, &MP.r[i2 - 1], &MP.r[i3 - 1]);
- mp_add_integer(&MP.r[i3 - 1], -1, &MP.r[i3 - 1]);
+ mpmul(x, &t1, &t2);
+ mp_add_integer(&t2, -1, &t2);
/* TEMPORARILY REDUCE T */
ts3 = MP.t;
MP.t = (MP.t + it0) / 2;
- mpmul(&MP.r[i2 - 1], &MP.r[i3 - 1], &MP.r[i3 - 1]);
+ mpmul(&t1, &t2, &t2);
/* RESTORE T */
MP.t = ts3;
- mp_subtract(&MP.r[i2 - 1], &MP.r[i3 - 1], &MP.r[i2 - 1]);
+ mp_subtract(&t1, &t2, &t1);
if (MP.t >= ts)
break;
@@ -2063,7 +2038,7 @@
}
/* RETURN IF NEWTON ITERATION WAS CONVERGING */
- if (MP.r[i3 - 1] != 0 && (MP.r[i2] - MP.r[i3]) << 1 < MP.t - it0) {
+ if (t2.data[0] != 0 && (t1.data[1] - t2.data[1]) << 1 < MP.t - it0) {
/* THE FOLLOWING MESSAGE MAY INDICATE THAT B**(T-1) IS TOO SMALL,
* OR THAT THE STARTING APPROXIMATION IS NOT ACCURATE ENOUGH.
*/
@@ -2073,11 +2048,11 @@
/* MOVE RESULT TO Y AND RETURN AFTER RESTORING T */
MP.t = ts;
- mp_set_from_mp(&MP.r[i2 - 1], z);
+ mp_set_from_mp(&t1, z);
/* RESTORE M AND CHECK FOR OVERFLOW (UNDERFLOW IMPOSSIBLE) */
MP.m += -2;
- if (z[1] <= MP.m)
+ if (z->data[1] <= MP.m)
return;
mpovfl(z, "*** OVERFLOW OCCURRED IN MP_RECIPROCAL ***\n");
@@ -2090,15 +2065,16 @@
* (BUT Z.EXP MAY BE R(3T+9))
*/
void
-mp_root(const int *x, int n, int *z)
+mp_root(const MPNumber *x, int n, MPNumber *z)
{
/* Initialized data */
static const int it[9] = { 0, 8, 6, 5, 4, 4, 4, 4, 4 };
float r__1;
- int i2, i3, ex, np, ts, it0, ts2, ts3;
+ int ex, np, ts, it0, ts2, ts3;
float rx;
+ MPNumber t1, t2;
/* CHECK LEGALITY OF B, T, M AND MXR */
mpchk(4, 10);
@@ -2110,61 +2086,58 @@
if (n == 0) {
mperr("*** N == 0 IN CALL TO MP_ROOT ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
- i2 = (MP.t << 1) + 7;
- i3 = i2 + MP.t + 2;
-
np = abs(n);
/* LOSS OF ACCURACY IF NP LARGE, SO ONLY ALLOW NP <= MAX (B, 64) */
if (np > max(MP.b, 64)) {
mperr("*** ABS(N) TOO LARGE IN CALL TO MP_ROOT ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
/* LOOK AT SIGN OF X */
- if (x[0] == 0) {
+ if (x->data[0] == 0) {
/* X == 0 HERE, RETURN 0 IF N POSITIVE, ERROR IF NEGATIVE */
- z[0] = 0;
+ z->data[0] = 0;
if (n > 0)
return;
mperr("*** X == 0 AND N NEGATIVE IN CALL TO MP_ROOT ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
- if (x[0] < 0 && np % 2 == 0) {
+ if (x->data[0] < 0 && np % 2 == 0) {
mperr("*** X NEGATIVE AND N EVEN IN CALL TO MP_ROOT ***\n");
- z[0] = 0;
+ z->data[0] = 0;
return;
}
/* DIVIDE EXPONENT BY NP */
- ex = x[1] / np;
+ ex = x->data[1] / np;
/* REDUCE EXPONENT SO RX NOT TOO LARGE OR SMALL. */
{
- int tmp_x[MP_SIZE];
- mp_set_from_mp(x, tmp_x);
- tmp_x[1] = 0;
- rx = mp_cast_to_float(tmp_x);
+ MPNumber tmp_x;
+ mp_set_from_mp(x, &tmp_x);
+ tmp_x.data[1] = 0;
+ rx = mp_cast_to_float(&tmp_x);
}
/* USE SINGLE-PRECISION ROOT FOR FIRST APPROXIMATION */
- r__1 = exp(((float) (np * ex - x[1]) * log((float) MP.b) -
+ r__1 = exp(((float) (np * ex - x->data[1]) * log((float) MP.b) -
log((fabs(rx)))) / (float) np);
- mp_set_from_float(r__1, &MP.r[i2 - 1]);
+ mp_set_from_float(r__1, &t1);
/* SIGN OF APPROXIMATION SAME AS THAT OF X */
- MP.r[i2 - 1] = x[0];
+ t1.data[0] = x->data[0];
/* CORRECT EXPONENT OF FIRST APPROXIMATION */
- MP.r[i2] -= ex;
+ t1.data[1] -= ex;
/* SAVE T (NUMBER OF DIGITS) */
ts = MP.t;
@@ -2182,19 +2155,19 @@
/* MAIN ITERATION LOOP */
while(1) {
- mppwr(&MP.r[i2 - 1], np, &MP.r[i3 - 1]);
- mpmul(x, &MP.r[i3 - 1], &MP.r[i3 - 1]);
- mp_add_integer(&MP.r[i3 - 1], -1, &MP.r[i3 - 1]);
+ mppwr(&t1, np, &t2);
+ mpmul(x, &t2, &t2);
+ mp_add_integer(&t2, -1, &t2);
/* TEMPORARILY REDUCE T */
ts3 = MP.t;
MP.t = (MP.t + it0) / 2;
- mpmul(&MP.r[i2 - 1], &MP.r[i3 - 1], &MP.r[i3 - 1]);
- mpdivi(&MP.r[i3 - 1], np, &MP.r[i3 - 1]);
+ mpmul(&t1, &t2, &t2);
+ mpdivi(&t2, np, &t2);
/* RESTORE T */
MP.t = ts3;
- mp_subtract(&MP.r[i2 - 1], &MP.r[i3 - 1], &MP.r[i2 - 1]);
+ mp_subtract(&t1, &t2, &t1);
/* FOLLOWING LOOP ALMOST DOUBLES T (POSSIBLE BECAUSE
* NEWTONS METHOD HAS 2ND ORDER CONVERGENCE).
@@ -2214,7 +2187,7 @@
/* NOW R(I2) IS X**(-1/NP)
* CHECK THAT NEWTON ITERATION WAS CONVERGING
*/
- if (MP.r[i3 - 1] != 0 && (MP.r[i2] - MP.r[i3]) << 1 < MP.t - it0) {
+ if (t2.data[0] != 0 && (t1.data[1] - t2.data[1]) << 1 < MP.t - it0) {
/* THE FOLLOWING MESSAGE MAY INDICATE THAT B**(T-1) IS TOO SMALL,
* OR THAT THE INITIAL APPROXIMATION OBTAINED USING ALOG AND EXP
* IS NOT ACCURATE ENOUGH.
@@ -2226,12 +2199,12 @@
/* RESTORE T */
MP.t = ts;
if (n >= 0) {
- mppwr(&MP.r[i2 - 1], n - 1, &MP.r[i2 - 1]);
- mpmul(x, &MP.r[i2 - 1], z);
+ mppwr(&t1, n - 1, &t1);
+ mpmul(x, &t1, z);
return;
}
- mp_set_from_mp(&MP.r[i2 - 1], z);
+ mp_set_from_mp(&t1, z);
}
@@ -2258,12 +2231,10 @@
* FIRST SET MXR
*/
void
-mpset(int idecpl, int itmax2, int maxdr)
+mpset(int idecpl, int itmax2)
{
int i, k, w, i2, w2, wn;
- MP.mxr = maxdr;
-
/* DETERMINE LARGE REPRESENTABLE INTEGER W OF FORM 2**K - 1 */
w = 0;
k = 0;
@@ -2321,23 +2292,24 @@
* CHECK LEGALITY OF B, T, M AND MXR
*/
void
-mp_sqrt(const int *x, int *z)
+mp_sqrt(const MPNumber *x, MPNumber *z)
{
int i, i2, iy3;
+ MPNumber t;
mpchk(4, 10);
/* MP_ROOT NEEDS 4T+10 WORDS, BUT CAN OVERLAP SLIGHTLY. */
i2 = MP.t * 3 + 9;
- if (x[0] < 0) {
+ if (x->data[0] < 0) {
mperr("*** X NEGATIVE IN CALL TO SUBROUTINE MP_SQRT ***\n");
- } else if (x[0] == 0) {
- z[0] = 0;
+ } else if (x->data[0] == 0) {
+ z->data[0] = 0;
} else {
- mp_root(x, -2, &MP.r[i2 - 1]);
- i = MP.r[i2 + 1];
- mpmul(x, &MP.r[i2 - 1], z);
- iy3 = z[2];
+ mp_root(x, -2, &t);
+ i = t.data[2];
+ mpmul(x, &t, z);
+ iy3 = z->data[2];
mpext(i, iy3, z);
}
}
@@ -2346,9 +2318,9 @@
* FOUR GUARD DIGITS ARE USED, AND THEN R*-ROUNDING
*/
void
-mp_subtract(const int *x, const int *y, int *z)
+mp_subtract(const MPNumber *x, const MPNumber *y, MPNumber *z)
{
- mpadd2(x, y, z, -y[0], 0);
+ mpadd2(x, y, z, -y->data[0], 0);
}
/* CALLED ON MULTIPLE-PRECISION UNDERFLOW, IE WHEN THE
@@ -2356,7 +2328,7 @@
* SINCE M MAY HAVE BEEN OVERWRITTEN, CHECK B, T, M ETC.
*/
static void
-mpunfl(int *x)
+mpunfl(MPNumber *x)
{
mpchk(1, 4);
@@ -2366,7 +2338,7 @@
* AFTER A PRESET NUMBER OF UNDERFLOWS. ACTION COULD EASILY
* BE DETERMINED BY A FLAG IN LABELLED COMMON.
*/
- x[0] = 0;
+ x->data[0] = 0;
}
static int
@@ -2387,10 +2359,11 @@
/* Calculate the factorial of MPval. */
void
-mp_factorial(int *MPval, int *MPres)
+mp_factorial(MPNumber *MPval, MPNumber *MPres)
{
double val;
- int i, MPa[MP_SIZE], MP1[MP_SIZE], MP2[MP_SIZE];
+ int i;
+ MPNumber MPa, MP1, MP2;
/* NOTE: do_factorial, on each iteration of the loop, will attempt to
* convert the current result to a double. If v->error is set,
@@ -2400,23 +2373,23 @@
* XXX: Needs to be improved. Shouldn't need to convert to a double in
* order to check this.
*/
- mp_set_from_mp(MPval, MPa);
- mpcmim(MPval, MP1);
- mp_set_from_integer(0, MP2);
- if (mp_is_equal(MPval, MP1)
- && mp_is_greater_equal(MPval, MP2)) { /* Only positive integers. */
- if (mp_is_equal(MP1, MP2)) { /* Special case for 0! */
+ mp_set_from_mp(MPval, &MPa);
+ mpcmim(MPval, &MP1);
+ mp_set_from_integer(0, &MP2);
+ if (mp_is_equal(MPval, &MP1)
+ && mp_is_greater_equal(MPval, &MP2)) { /* Only positive integers. */
+ if (mp_is_equal(&MP1, &MP2)) { /* Special case for 0! */
mp_set_from_integer(1, MPres);
return;
}
- mp_set_from_integer(1, MPa);
- i = mp_cast_to_int(MP1);
+ mp_set_from_integer(1, &MPa);
+ i = mp_cast_to_int(&MP1);
if (!i) {
matherr((struct exception *) NULL);
} else {
while (i > 0) {
- mpmuli(MPa, i, MPa);
- val = mp_cast_to_double(MPa);
+ mpmuli(&MPa, i, &MPa);
+ val = mp_cast_to_double(&MPa);
if (v->error) {
mperr("Error calculating factorial\n");
return;
@@ -2427,29 +2400,29 @@
} else {
matherr((struct exception *) NULL);
}
- mp_set_from_mp(MPa, MPres);
+ mp_set_from_mp(&MPa, MPres);
}
int
-mp_modulus_divide(int op1[MP_SIZE],
- int op2[MP_SIZE],
- int result[MP_SIZE])
+mp_modulus_divide(MPNumber *op1,
+ MPNumber *op2,
+ MPNumber *result)
{
- int MP1[MP_SIZE], MP2[MP_SIZE];
+ MPNumber MP1, MP2;
if (!mp_is_integer(op1) || !mp_is_integer(op2)) {
return -EINVAL;
}
- mpdiv(op1, op2, MP1);
- mpcmim(MP1, MP1);
- mpmul(MP1, op2, MP2);
- mp_subtract(op1, MP2, result);
-
- mp_set_from_integer(0, MP1);
- if ((mp_is_less_than(op2, MP1)
- && mp_is_greater_than(result, MP1)) ||
- mp_is_less_than(result, MP1)) {
+ mpdiv(op1, op2, &MP1);
+ mpcmim(&MP1, &MP1);
+ mpmul(&MP1, op2, &MP2);
+ mp_subtract(op1, &MP2, result);
+
+ mp_set_from_integer(0, &MP1);
+ if ((mp_is_less_than(op2, &MP1)
+ && mp_is_greater_than(result, &MP1)) ||
+ mp_is_less_than(result, &MP1)) {
mp_add(result, op2, result);
}
@@ -2458,7 +2431,7 @@
/* Do x^y */
void
-mp_xpowy(int x[MP_SIZE], int y[MP_SIZE], int res[MP_SIZE])
+mp_xpowy(MPNumber *x, MPNumber *y, MPNumber *res)
{
if (mp_is_integer(y)) {
mppwr(x, mp_cast_to_int(y), res);
@@ -2468,19 +2441,19 @@
}
void
-mp_percent(int s1[MP_SIZE], int t1[MP_SIZE])
+mp_percent(MPNumber *s1, MPNumber *t1)
{
- int MP1[MP_SIZE];
+ MPNumber MP1;
- mp_set_from_string("0.01", 10, MP1);
- mpmul(s1, MP1, t1);
+ mp_set_from_string("0.01", 10, &MP1);
+ mpmul(s1, &MP1, t1);
}
void
-mp_epowy(int s[MP_SIZE], int t[MP_SIZE])
+mp_epowy(MPNumber *s, MPNumber *t)
{
- int MP1[MP_SIZE];
+ MPNumber MP1;
- mp_set_from_mp(s, MP1);
- mpexp(MP1, t);
+ mp_set_from_mp(s, &MP1);
+ mpexp(&MP1, t);
}
Modified: trunk/gcalctool/mp.h
==============================================================================
--- trunk/gcalctool/mp.h (original)
+++ trunk/gcalctool/mp.h Mon Apr 6 01:21:05 2009
@@ -42,6 +42,15 @@
#define MP_SIZE 1000 /* Size of the multiple precision values. */
+typedef struct
+{
+ /* data[0] = sign (0, -1 or +1)
+ * data[1] = exponent (to base MP.b)
+ * data[2..MP.t+2] = normalized fraction.
+ */
+ int data[MP_SIZE];
+} MPNumber;
+
/* If we're not using GNU C, elide __attribute__ */
#ifndef __GNUC__
# define __attribute__(x) /*NOTHING*/
@@ -51,87 +60,87 @@
void mperr(const char *format, ...) __attribute__((format(printf, 1, 2)));
-int mp_compare_mp_to_mp(const int *x, const int *y);
+int mp_compare_mp_to_mp(const MPNumber *x, const MPNumber *y);
-int mp_is_zero(const int *x);
-int mp_is_negative(const int *x);
+int mp_is_zero(const MPNumber *x);
+int mp_is_negative(const MPNumber *x);
/* return true if parameter is integer */
-int mp_is_integer(int MPnum[MP_SIZE]);
+int mp_is_integer(const MPNumber *);
/* return true if parameter is natural number, that is, a positive integer */
-int mp_is_natural(int MPnum[MP_SIZE]);
+int mp_is_natural(const MPNumber *);
-int mp_is_equal(const int *, const int *);
-int mp_is_greater_equal(const int *, const int *);
-int mp_is_greater_than(const int *, const int *);
-int mp_is_less_equal(const int *, const int *);
-int mp_is_less_than(const int *, const int *);
-
-void mp_abs(const int *, int *);
-void mp_invert_sign(const int *, int *);
-
-void mp_add(const int *, const int *, int *);
-void mp_add_integer(const int *, int, int *);
-void mp_add_fraction(const int *, int, int, int *);
-void mp_subtract(const int *, const int *, int *);
-
-void mpcmf(const int *, int *);
-void mpcmim(const int *, int *);
-void mpdiv(const int *, const int *, int *);
-void mpdivi(const int *, int, int *);
-void mpexp(const int *, int *);
-void mpln(int *, int *);
-void mp_logarithm(int n, int *MPx, int *MPretval);
-void mpmul(const int *, const int *, int *);
-void mpmuli(int *, int, int *);
-void mp_get_pi(int *z);
-void mppwr(const int *, int, int *);
-void mppwr2(int *, int *, int *);
-void mpset(int, int, int);
-void mp_root(const int *x, int n, int *z);
-void mp_sqrt(const int *x, int *z);
-void mp_factorial(int *, int *);
-int mp_modulus_divide(int op1[MP_SIZE], int op2[MP_SIZE], int result[MP_SIZE]);
-void mp_percent(int s1[MP_SIZE], int t1[MP_SIZE]);
-void mp_xpowy(int MPx[MP_SIZE], int MPy[MP_SIZE], int MPres[MP_SIZE]);
-void mp_epowy(int s[MP_SIZE], int t[MP_SIZE]);
+int mp_is_equal(const MPNumber *, const MPNumber *);
+int mp_is_greater_equal(const MPNumber *, const MPNumber *);
+int mp_is_greater_than(const MPNumber *, const MPNumber *);
+int mp_is_less_equal(const MPNumber *, const MPNumber *);
+int mp_is_less_than(const MPNumber *, const MPNumber *);
+
+void mp_abs(const MPNumber *, MPNumber *);
+void mp_invert_sign(const MPNumber *, MPNumber *);
+
+void mp_add(const MPNumber *, const MPNumber *, MPNumber *);
+void mp_add_integer(const MPNumber *, int, MPNumber *);
+void mp_add_fraction(const MPNumber *, int, int, MPNumber *);
+void mp_subtract(const MPNumber *, const MPNumber *, MPNumber *);
+
+void mpcmf(const MPNumber *, MPNumber *);
+void mpcmim(const MPNumber *, MPNumber *);
+void mpdiv(const MPNumber *, const MPNumber *, MPNumber *);
+void mpdivi(const MPNumber *, int, MPNumber *);
+void mpexp(const MPNumber *, MPNumber *);
+void mpln(MPNumber *, MPNumber *);
+void mp_logarithm(int n, MPNumber *MPx, MPNumber *MPretval);
+void mpmul(const MPNumber *, const MPNumber *, MPNumber *);
+void mpmuli(MPNumber *, int, MPNumber *);
+void mp_get_pi(MPNumber *z);
+void mppwr(const MPNumber *, int, MPNumber *);
+void mppwr2(MPNumber *, MPNumber *, MPNumber *);
+void mpset(int, int);
+void mp_root(const MPNumber *x, int n, MPNumber *z);
+void mp_sqrt(const MPNumber *x, MPNumber *z);
+void mp_factorial(MPNumber *, MPNumber *);
+int mp_modulus_divide(MPNumber *op1, MPNumber *op2, MPNumber *result);
+void mp_percent(MPNumber *s1, MPNumber *t1);
+void mp_xpowy(MPNumber *MPx, MPNumber *MPy, MPNumber *MPres);
+void mp_epowy(MPNumber *s, MPNumber *t);
/* mp-convert.c */
-void mp_set_from_mp(const int *, int *);
-void mp_set_from_float(float, int *);
-void mp_set_from_double(double, int *);
-void mp_set_from_integer(int, int *);
-void mp_set_from_fraction(int, int, int *);
-void mp_set_from_random(int t[MP_SIZE]);
-void mp_set_from_string(const char *number, int base, int t[MP_SIZE]);
-float mp_cast_to_float(const int *);
-double mp_cast_to_double(const int *);
-int mp_cast_to_int(const int *);
-void mp_cast_to_string(char *, int, const int *, int, int);
+void mp_set_from_mp(const MPNumber *, MPNumber *);
+void mp_set_from_float(float, MPNumber *);
+void mp_set_from_double(double, MPNumber *);
+void mp_set_from_integer(int, MPNumber *);
+void mp_set_from_fraction(int, int, MPNumber *);
+void mp_set_from_random(MPNumber *t);
+void mp_set_from_string(const char *number, int base, MPNumber *t);
+float mp_cast_to_float(const MPNumber *);
+double mp_cast_to_double(const MPNumber *);
+int mp_cast_to_int(const MPNumber *);
+void mp_cast_to_string(char *, int, const MPNumber *, int, int);
/* mp-trigonometric.c */
-void mp_acos(const int *x, int *z);
-void mp_acosh(const int *x, int *z);
-void mp_asin(const int *x, int *z);
-void mp_asinh(const int *x, int *z);
-void mp_atan(const int *x, int *z);
-void mp_atanh(const int *x, int *z);
-void mp_cos(const int *x, int *z);
-void mp_cosh(const int *x, int *z);
-void mp_sin(const int *x, int *z);
-void mp_sinh(const int *x, int *z);
-void mp_tan(const int *x, int *z);
-void mp_tanh(const int *x, int *z);
+void mp_acos(const MPNumber *x, MPNumber *z);
+void mp_acosh(const MPNumber *x, MPNumber *z);
+void mp_asin(const MPNumber *x, MPNumber *z);
+void mp_asinh(const MPNumber *x, MPNumber *z);
+void mp_atan(const MPNumber *x, MPNumber *z);
+void mp_atanh(const MPNumber *x, MPNumber *z);
+void mp_cos(const MPNumber *x, MPNumber *z);
+void mp_cosh(const MPNumber *x, MPNumber *z);
+void mp_sin(const MPNumber *x, MPNumber *z);
+void mp_sinh(const MPNumber *x, MPNumber *z);
+void mp_tan(const MPNumber *x, MPNumber *z);
+void mp_tanh(const MPNumber *x, MPNumber *z);
/* mp-binary.c */
-void mp_and(const int s1[MP_SIZE], const int s2[MP_SIZE], int t[MP_SIZE]);
-void mp_or(const int s1[MP_SIZE], const int s2[MP_SIZE], int t[MP_SIZE]);
-void mp_xor(const int s1[MP_SIZE], const int s2[MP_SIZE], int t[MP_SIZE]);
-void mp_xnor(const int s1[MP_SIZE], const int s2[MP_SIZE], int t[MP_SIZE]);
-void mp_not(const int s1[MP_SIZE], int t[MP_SIZE]);
-void mp_mask_u32(const int s1[MP_SIZE], int t1[MP_SIZE]);
-void mp_mask_u16(const int s1[MP_SIZE], int t1[MP_SIZE]);
-void mp_shift(int s[MP_SIZE], int t[MP_SIZE], int times);
+void mp_and(const MPNumber *s1, const MPNumber *s2, MPNumber *t);
+void mp_or(const MPNumber *s1, const MPNumber *s2, MPNumber *t);
+void mp_xor(const MPNumber *s1, const MPNumber *s2, MPNumber *t);
+void mp_xnor(const MPNumber *s1, const MPNumber *s2, MPNumber *t);
+void mp_not(const MPNumber *s1, MPNumber *t);
+void mp_mask_u32(const MPNumber *s1, MPNumber *t1);
+void mp_mask_u16(const MPNumber *s1, MPNumber *t1);
+void mp_shift(MPNumber *s, MPNumber *t, int times);
#endif /* MP_H */
Modified: trunk/gcalctool/parser.c
==============================================================================
--- trunk/gcalctool/parser.c (original)
+++ trunk/gcalctool/parser.c Mon Apr 6 01:21:05 2009
@@ -31,16 +31,16 @@
void
-cp(int s[MP_SIZE], int t[MP_SIZE])
+cp(const MPNumber *s, MPNumber *t)
{
- memcpy(t, s, sizeof(int)*MP_SIZE);
+ mp_set_from_mp(s, t);
}
void
-ret(int s[MP_SIZE]) /* Copy result value. */
+ret(const MPNumber *s) /* Copy result value. */
{
- memcpy(parser_state.ret, s, sizeof(int)*MP_SIZE);
+ mp_set_from_mp(s, &parser_state.ret);
parser_state.flags |= ANS;
}
Modified: trunk/gcalctool/parser.h
==============================================================================
--- trunk/gcalctool/parser.h (original)
+++ trunk/gcalctool/parser.h Mon Apr 6 01:21:05 2009
@@ -36,13 +36,12 @@
char *buff;
int i;
int error;
- int ret[MP_SIZE];
+ MPNumber ret;
int ncount;
};
-void cp(int s[MP_SIZE], int t[MP_SIZE]);
-void ret(int s[MP_SIZE]);
-void iret(int s[MP_SIZE]);
+void cp(const MPNumber *s, MPNumber *t);
+void ret(const MPNumber *s);
void check_numbase(char *num);
Modified: trunk/gcalctool/register.c
==============================================================================
--- trunk/gcalctool/register.c (original)
+++ trunk/gcalctool/register.c Mon Apr 6 01:21:05 2009
@@ -27,12 +27,12 @@
#include "mp.h"
static char constant_names[MAX_CONSTANTS][MAXLINE]; /* Selectable constant names. */
-static int constant_values[MAX_CONSTANTS][MP_SIZE]; /* Selectable constants. */
+static MPNumber constant_values[MAX_CONSTANTS]; /* Selectable constants. */
static char function_names[MAX_FUNCTIONS][MAXLINE]; /* Function names from .gcalctoolcf. */
static char function_values[MAX_FUNCTIONS][MAXLINE]; /* Function defs from .gcalctoolcf. */
-static int registers[MAX_REGISTERS][MP_SIZE]; /* Memory register values. */
+static MPNumber registers[MAX_REGISTERS]; /* Memory register values. */
static const char *default_constants[][2] =
{
@@ -67,17 +67,17 @@
SNPRINTF(key, MAXLINE, "register%d", i);
value = get_resource(key);
if (value) {
- int temp[MP_SIZE];
- mp_set_from_string(value, 10, temp);
+ MPNumber temp;
+ mp_set_from_string(value, 10, &temp);
g_free(value);
- register_set(i, temp);
+ register_set(i, &temp);
}
}
for (i = 0; i < MAX_CONSTANTS; i++) {
char nkey[MAXLINE], *nline;
char vkey[MAXLINE], *vline = NULL;
- int value[MP_SIZE];
+ MPNumber value;
SNPRINTF(nkey, MAXLINE, "constant%1dname", i);
nline = get_resource(nkey);
@@ -89,14 +89,14 @@
}
if (nline && vline) {
- mp_set_from_string(vline, 10, value);
- constant_set(i, nline, value);
+ mp_set_from_string(vline, 10, &value);
+ constant_set(i, nline, &value);
g_free(nline);
g_free(vline);
}
else {
- mp_set_from_string(default_constants[i][1], 10, value);
- constant_set(i, default_constants[i][0], value);
+ mp_set_from_string(default_constants[i][1], 10, &value);
+ constant_set(i, default_constants[i][0], &value);
}
}
@@ -126,27 +126,27 @@
void
-register_set(int index, int value[MP_SIZE])
+register_set(int index, MPNumber *value)
{
if ((index >= 0) && (index <= 10))
- mp_set_from_mp(value, registers[index]);
+ mp_set_from_mp(value, ®isters[index]);
}
void
-register_get(int index, int value[MP_SIZE])
+register_get(int index, MPNumber *value)
{
if ((index >= 0) && (index <= 10))
- mp_set_from_mp(registers[index], value);
+ mp_set_from_mp(®isters[index], value);
}
-void constant_set(int index, const char *name, int value[MP_SIZE])
+void constant_set(int index, const char *name, MPNumber *value)
{
char key[MAXLINE], text[MAX_LOCALIZED];
STRNCPY(constant_names[index], name, MAXLINE - 1);
- mp_set_from_mp(value, constant_values[index]);
+ mp_set_from_mp(value, &constant_values[index]);
SNPRINTF(key, MAXLINE, "constant%1dname", index);
set_resource(key, name);
@@ -165,9 +165,9 @@
}
-const int *constant_get_value(int index)
+const MPNumber *constant_get_value(int index)
{
- return constant_values[index];
+ return &constant_values[index];
}
Modified: trunk/gcalctool/register.h
==============================================================================
--- trunk/gcalctool/register.h (original)
+++ trunk/gcalctool/register.h Mon Apr 6 01:21:05 2009
@@ -25,12 +25,12 @@
#include "mp.h"
void register_init();
-void register_set(int index, int value[MP_SIZE]);
-void register_get(int index, int value[MP_SIZE]);
+void register_set(int index, MPNumber *value);
+void register_get(int index, MPNumber *value);
-void constant_set(int index, const char *name, int value[MP_SIZE]);
+void constant_set(int index, const char *name, MPNumber *value);
const char *constant_get_name(int index);
-const int *constant_get_value(int index);
+const MPNumber *constant_get_value(int index);
void function_set(int index, const char *name, const char *value);
const char *function_get_name(int index);
Modified: trunk/gcalctool/unittest.c
==============================================================================
--- trunk/gcalctool/unittest.c (original)
+++ trunk/gcalctool/unittest.c Mon Apr 6 01:21:05 2009
@@ -30,10 +30,10 @@
test(char *expression, char *expected, int expected_error)
{
int error;
- int result[MP_SIZE];
+ MPNumber result;
char result_str[MAXLINE];
- error = ce_parse(expression, result);
+ error = ce_parse(expression, &result);
if(error != 0 || error != expected_error)
{
if(error == expected_error)
@@ -43,7 +43,7 @@
return;
}
- mp_cast_to_string(result_str, MAXLINE, result, basevals[v->base], 9);
+ mp_cast_to_string(result_str, MAXLINE, &result, basevals[v->base], 9);
if(strcmp(result_str, expected) != 0)
printf("FAIL: '%s' -> '%s', expected '%s'\n", expression, result_str, expected);
else
@@ -111,7 +111,12 @@
test("5!", "120", 0);
//FIXME: Need to update do_factorial() test("0.1!", "", 0);
//FIXME: Need to update do_factorial() test("-1!", "", 0);
-
+
+ test("2^0", "1", 0);
+ test("2^1", "2", 0);
+ test("2^2", "4", 0);
+ test("2^-1", "0.5", 0);
+ test("2^100", "1267650600228229401496703205376", 0);
test("Sqrt(4)", "2", 0);
test("Sqrt(2)", "1.414213562", 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]