[gcalctool/gcalctool-newui2] ...
- From: Robert Ancell <rancell src gnome org>
- To: svn-commits-list gnome org
- Subject: [gcalctool/gcalctool-newui2] ...
- Date: Tue, 14 Jul 2009 07:33:31 +0000 (UTC)
commit d7978ab1a0333fac4b42663bd056c48f27915393
Author: Robert Ancell <robert ancell gmail com>
Date: Tue Jul 14 17:32:51 2009 +1000
...
src/functions.c | 16 ++++++++---
src/mp-binary.c | 6 ++--
src/mp-equation-lexer.l | 3 +-
src/mp-equation-parser.y | 24 ++++++++--------
src/mp-equation.c | 44 +++++++++++++++++++++++--------
src/mp-equation.h | 16 ++++++-----
src/mp.c | 65 +++++++++++++++++++++++++++++++++++++++------
src/mp.h | 6 ++--
8 files changed, 130 insertions(+), 50 deletions(-)
---
diff --git a/src/functions.c b/src/functions.c
index d71780e..48ff9da 100644
--- a/src/functions.c
+++ b/src/functions.c
@@ -388,10 +388,6 @@ do_expression(int function, int arg, int cursor_start, int cursor_end)
display_set_answer(&v->display);
break;
- case -PARSER_ERR_INVALID_BASE:
- message = _("Invalid number for the current base");
- break;
-
case -PARSER_ERR_TOO_LONG_NUMBER:
message = _("Too long number");
break;
@@ -417,6 +413,18 @@ do_expression(int function, int arg, int cursor_start, int cursor_end)
message = _("Overflow. Try a bigger word size");
break;
+ case -PARSER_ERR_UNKNOWN_VARIABLE:
+ /* Translators; Error displayd to user when they
+ * an unknown variable is entered */
+ message = _("Unknown variable");
+ break;
+
+ case -PARSER_ERR_UNKNOWN_FUNCTION:
+ /* Translators; Error displayd to user when they
+ * an unknown function is entered */
+ message = _("Unknown function");
+ break;
+
case -MPMATH_ERR:
message = v->math_error_text;
break;
diff --git a/src/mp-binary.c b/src/mp-binary.c
index e3499c0..5b6914f 100644
--- a/src/mp-binary.c
+++ b/src/mp-binary.c
@@ -139,7 +139,7 @@ mp_shift(const MPNumber *x, int count, MPNumber *z)
void
-mp_1s_complement(const MPNumber *x, int wordlen, MPNumber *z)
+mp_ones_complement(const MPNumber *x, int wordlen, MPNumber *z)
{
MPNumber t;
mp_set_from_integer(0, &t);
@@ -149,8 +149,8 @@ mp_1s_complement(const MPNumber *x, int wordlen, MPNumber *z)
void
-mp_2s_complement(const MPNumber *x, int wordlen, MPNumber *z)
+mp_twos_complement(const MPNumber *x, int wordlen, MPNumber *z)
{
- mp_1s_complement (x, wordlen, z);
+ mp_ones_complement (x, wordlen, z);
mp_add_integer (z, 1, z);
}
diff --git a/src/mp-equation-lexer.l b/src/mp-equation-lexer.l
index cb02f49..2f99417 100644
--- a/src/mp-equation-lexer.l
+++ b/src/mp-equation-lexer.l
@@ -101,7 +101,8 @@ SUB_NUM {SUB_DIGITS}+
NUMBER {BIN_NUM}|{OCT_NUM}|{DEC_NUM}|{HEX_NUM}
GREEKS "α"|"β"|"γ"|"δ"|"ε"|"ζ"|"η"|"θ"|"ι"|"κ"|"λ"|"μ"|"ν"|"ξ"|"ο"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"|"Ï?"
REGISTERS "Râ??"|"Râ??"|"Râ??"|"Râ??"|"Râ??"|"Râ??"|"Râ??"|"Râ??"|"Râ??"|"Râ??"
-VARIABLE {REGISTERS}|{GREEKS}|"e"
+ANS [aA][nN][sS]
+VARIABLE {REGISTERS}|{GREEKS}|"e"|{ANS}
VARIABLE_NAME [a-zA-Z]+
FUNCTION {VARIABLE_NAME}|{VARIABLE_NAME}{INVERSE}|{VARIABLE_NAME}{SUB_NUM}
diff --git a/src/mp-equation-parser.y b/src/mp-equation-parser.y
index 86329ea..66aee9f 100644
--- a/src/mp-equation-parser.y
+++ b/src/mp-equation-parser.y
@@ -32,9 +32,15 @@
// treat exp NAME exp as a function always and pass both arguments, i.e.
// can do mod using both and all others use $1 * NAME($3)
+static void set_error(yyscan_t yyscanner, int error)
+{
+ _mp_equation_get_extra(yyscanner)->error = error;
+}
+
static void get_variable(yyscan_t yyscanner, const char *name, MPNumber *z)
{
- _mp_equation_get_extra(yyscanner)->get_variable(_mp_equation_get_extra(yyscanner), name, z);
+ if (!_mp_equation_get_extra(yyscanner)->get_variable(_mp_equation_get_extra(yyscanner), name, z))
+ set_error(yyscanner, -PARSER_ERR_UNKNOWN_VARIABLE);
}
static void set_variable(yyscan_t yyscanner, const char *name, MPNumber *x)
@@ -44,12 +50,8 @@ static void set_variable(yyscan_t yyscanner, const char *name, MPNumber *x)
static void get_function(yyscan_t yyscanner, const char *name, const MPNumber *x, MPNumber *z)
{
- _mp_equation_get_extra(yyscanner)->get_function(_mp_equation_get_extra(yyscanner), name, x, z);
-}
-
-static void set_error(yyscan_t yyscanner, int error)
-{
- _mp_equation_get_extra(yyscanner)->error = error;
+ if (!_mp_equation_get_extra(yyscanner)->get_function(_mp_equation_get_extra(yyscanner), name, x, z))
+ set_error(yyscanner, -PARSER_ERR_UNKNOWN_FUNCTION);
}
static void do_bitwise(yyscan_t yyscanner, void (*mp_fn)(const MPNumber *x, const MPNumber *y, MPNumber *z), const MPNumber *x, const MPNumber *y, MPNumber *z)
@@ -75,9 +77,7 @@ static void do_mod(yyscan_t yyscanner, const MPNumber *x, const MPNumber *y, MPN
if (!mp_is_integer(x) || !mp_is_integer(y)) {
set_error(yyscanner, -PARSER_ERR_MODULUSOP);
} else {
- if (mp_modulus_divide(x, y, z)) {
- set_error(yyscanner, -EINVAL);
- }
+ mp_modulus_divide(x, y, z);
}
}
%}
@@ -114,8 +114,8 @@ static void do_mod(yyscan_t yyscanner, const MPNumber *x, const MPNumber *y, MPN
%%
statement:
- exp { mp_set_from_mp(&$1, &(_mp_equation_get_extra(yyscanner))->ret); set_error(yyscanner, 0);}
-| tVARIABLE '=' exp {set_variable(yyscanner, $1, &$3); set_error(yyscanner, 0);}
+ exp { mp_set_from_mp(&$1, &(_mp_equation_get_extra(yyscanner))->ret);}
+| tVARIABLE '=' exp {set_variable(yyscanner, $1, &$3);}
;
exp:
diff --git a/src/mp-equation.c b/src/mp-equation.c
index fa52d22..0ff8d58 100644
--- a/src/mp-equation.c
+++ b/src/mp-equation.c
@@ -30,19 +30,30 @@
extern int _mp_equation_parse(yyscan_t yyscanner);
-static void
+static int
get_variable(MPEquationParserState *state, const char *name, MPNumber *z)
{
- if (name[0] == 'R' || name[0] == 'r')
+ char *c, *lower_name;
+ int result = 1;
+
+ lower_name = strdup(name);
+ for (c = lower_name; *c; c++)
+ *c = tolower(*c);
+
+ if (lower_name[0] == 'r')
mp_set_from_mp(register_get_value(atoi(name+1)), z);
- else if (strcmp(name, "ans") == 0)
+ else if (strcmp(lower_name, "ans") == 0)
mp_set_from_mp(display_get_answer(&v->display), z);
else if (strcmp(name, "e") == 0)
mp_get_eulers(z);
else if (strcmp(name, "Ï?") == 0)
mp_get_pi(z);
else
- mp_set_from_integer(0, z); // FIXME
+ result = 0;
+
+ free(lower_name);
+
+ return result;
}
static void
@@ -58,10 +69,11 @@ set_variable(MPEquationParserState *state, const char *name, MPNumber *x)
// letters+numbers = numbers+letters+numbers = function
-static void
+static int
get_function(MPEquationParserState *state, const char *name, const MPNumber *x, MPNumber *z)
{
char *c, *lower_name;
+ int result = 1;
lower_name = strdup(name);
for (c = lower_name; *c; c++)
@@ -105,17 +117,23 @@ get_function(MPEquationParserState *state, const char *name, const MPNumber *x,
mp_acosh(x, z);
else if (strcmp(lower_name, "tanh�¹") == 0 || strcmp(lower_name, "atanh") == 0)
mp_atanh(x, z);
+ else if (strcmp(lower_name, "ones") == 0)
+ mp_ones_complement(x, state->wordlen, z);
+ else if (strcmp(lower_name, "twos") == 0)
+ mp_twos_complement(x, state->wordlen, z);
else
- mp_set_from_integer(0, z); // FIXME
+ result = 0;
free(lower_name);
+
+ return result;
}
int
mp_equation_parse(const char *expression, MPNumber *result)
{
- int ret = 0;
+ int ret;
MPEquationParserState state;
yyscan_t yyscanner;
YY_BUFFER_STATE buffer;
@@ -130,9 +148,9 @@ mp_equation_parse(const char *expression, MPNumber *result)
state.get_variable = get_variable;
state.set_variable = set_variable;
state.get_function = get_function;
- state.error = -EINVAL;
+ state.error = 0;
v->math_error = 0;
-
+
_mp_equation_lex_init_extra(&state, &yyscanner);
buffer = _mp_equation__scan_string(expression, yyscanner);
@@ -141,9 +159,13 @@ mp_equation_parse(const char *expression, MPNumber *result)
_mp_equation__delete_buffer(buffer, yyscanner);
_mp_equation_lex_destroy(yyscanner);
- ret = (state.error) ? state.error : ret;
+ /* Failed to parse */
if (ret)
- return ret;
+ return -PARSER_ERR_INVALID;
+
+ /* Error during parsing */
+ if (state.error)
+ return state.error;
if (v->math_error)
return v->math_error;
diff --git a/src/mp-equation.h b/src/mp-equation.h
index 41f9d9c..e43d768 100644
--- a/src/mp-equation.h
+++ b/src/mp-equation.h
@@ -25,11 +25,13 @@
#include "mp.h"
-#define PARSER_ERR_INVALID_BASE 10000
-#define PARSER_ERR_TOO_LONG_NUMBER 10001
-#define PARSER_ERR_BITWISEOP 10002
-#define PARSER_ERR_MODULUSOP 10003
-#define PARSER_ERR_OVERFLOW 10004
+#define PARSER_ERR_INVALID 1
+#define PARSER_ERR_TOO_LONG_NUMBER 2
+#define PARSER_ERR_BITWISEOP 3
+#define PARSER_ERR_MODULUSOP 4
+#define PARSER_ERR_OVERFLOW 5
+#define PARSER_ERR_UNKNOWN_VARIABLE 6
+#define PARSER_ERR_UNKNOWN_FUNCTION 7
typedef struct MPEquationParserState MPEquationParserState;
@@ -45,13 +47,13 @@ struct MPEquationParserState {
MPAngleUnit angle_units;
/* Function to get variable values */
- void (*get_variable)(MPEquationParserState *state, const char *name, MPNumber *z);
+ int (*get_variable)(MPEquationParserState *state, const char *name, MPNumber *z);
/* Function to set variable values */
void (*set_variable)(MPEquationParserState *state, const char *name, MPNumber *x);
/* Function to solve functions */
- void (*get_function)(MPEquationParserState *state, const char *name, const MPNumber *x, MPNumber *z);
+ int (*get_function)(MPEquationParserState *state, const char *name, const MPNumber *x, MPNumber *z);
// FIXME: get_operator??
diff --git a/src/mp.c b/src/mp.c
index 69cf983..e9f8044 100644
--- a/src/mp.c
+++ b/src/mp.c
@@ -1227,6 +1227,58 @@ mp_multiply(const MPNumber *x, const MPNumber *y, MPNumber *z)
}
+void
+mp_multiply_new(const MPNumber *x, const MPNumber *y, MPNumber *z)
+{
+ int i, j, offset, y_length;
+ int fraction[MP_SIZE*2];
+
+ /* x*0 or 0*y or 0*0 = 0 */
+ if (x->sign * y->sign == 0) {
+ mp_set_from_integer(0, z);
+ return;
+ }
+
+ /* Calculate length of each fraction */
+ y_length = MP_SIZE;
+ while (y_length > 0 && y->fraction[y_length - 1] == 0)
+ y_length--;
+
+ /* Multiply together */
+ memset(fraction, 0, sizeof(fraction));
+ for (i = MP_SIZE - 1; i >= 0; i--) {
+ if (x->fraction[i] == 0)
+ continue;
+ for (j = y_length - 1; j >= 0; j--) {
+ int pos = i + j + 1;
+
+ fraction[pos] += x->fraction[i] * y->fraction[j];
+ fraction[pos-1] += fraction[pos] / MP_BASE;
+ fraction[pos] = fraction[pos] % MP_BASE;
+ }
+ }
+
+ offset = 0;
+ for (i = 0; i < MP_SIZE && fraction[offset] == 0; i++)
+ offset++;
+ z->sign = x->sign * y->sign;
+ z->exponent = x->exponent + y->exponent - offset;
+ for (i = 0; i < MP_SIZE; i++) {
+ if (i + offset >= MP_SIZE*2)
+ z->fraction[i] = 0;
+ else
+ z->fraction[i] = fraction[i + offset];
+ }
+
+ /*for (i = MP_SIZE + offset; i < MP_SIZE * 2; i++) {
+ if (fraction[i] != 0) {
+ printf("truncated\n");
+ break;
+ }
+ }*/
+}
+
+
/* MULTIPLIES MP X BY SINGLE-PRECISION INTEGER IY GIVING MP Z.
* MULTIPLICATION BY 1 MAY BE USED TO NORMALIZE A NUMBER
* EVEN IF SOME DIGITS ARE GREATER THAN B-1.
@@ -1799,15 +1851,12 @@ mp_factorial(const MPNumber *x, MPNumber *z)
mp_multiply_integer(z, i, z);
}
-int
+
+void
mp_modulus_divide(const MPNumber *x, const MPNumber *y, MPNumber *z)
{
MPNumber t1, t2;
- if (!mp_is_integer(x) || !mp_is_integer(y)) {
- return -EINVAL;
- }
-
mp_divide(x, y, &t1);
mp_integer_component(&t1, &t1);
mp_multiply(&t1, y, &t2);
@@ -1817,8 +1866,6 @@ mp_modulus_divide(const MPNumber *x, const MPNumber *y, MPNumber *z)
if ((mp_is_less_than(y, &t1) && mp_is_greater_than(z, &t1)) || mp_is_less_than(z, &t1)) {
mp_add(z, y, z);
}
-
- return 0;
}
@@ -1864,8 +1911,8 @@ mp_xpowy_integer(const MPNumber *x, int n, MPNumber *z)
mp_set_from_mp(x, &t);
/* Multply x n times */
+ // FIXME: Can do mp_multiply(z, z, z) until close to answer (each call doubles number of multiples) */
mp_set_from_integer(1, z);
- for (i = 0; i < n; i++) {
+ for (i = 0; i < n; i++)
mp_multiply(z, &t, z);
- }
}
diff --git a/src/mp.h b/src/mp.h
index 1cede21..377cc57 100644
--- a/src/mp.h
+++ b/src/mp.h
@@ -168,7 +168,7 @@ void mp_sqrt(const MPNumber *x, MPNumber *z);
void mp_factorial(const MPNumber *x, MPNumber *z);
/* Sets z = x mod y */
-int mp_modulus_divide(const MPNumber *x, const MPNumber *y, MPNumber *z);
+void mp_modulus_divide(const MPNumber *x, const MPNumber *y, MPNumber *z);
/* Sets z = x^y */
void mp_xpowy(const MPNumber *x, const MPNumber *y, MPNumber *z);
@@ -279,9 +279,9 @@ void mp_mask(const MPNumber *x, int wordlen, MPNumber *z);
void mp_shift(const MPNumber *x, int count, MPNumber *z);
/* Sets z to be the ones complement of x for word of length 'wordlen' */
-void mp_1s_complement(const MPNumber *x, int wordlen, MPNumber *z);
+void mp_ones_complement(const MPNumber *x, int wordlen, MPNumber *z);
/* Sets z to be the twos complement of x for word of length 'wordlen' */
-void mp_2s_complement(const MPNumber *x, int wordlen, MPNumber *z);
+void mp_twos_complement(const MPNumber *x, int wordlen, MPNumber *z);
#endif /* MP_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]