[gcalctool/gcalctool-newui2] ...
- From: Robert Ancell <rancell src gnome org>
- To: svn-commits-list gnome org
- Subject: [gcalctool/gcalctool-newui2] ...
- Date: Fri, 26 Jun 2009 10:47:27 +0000 (UTC)
commit 8e523e28a3c914342e346b974ebbb76cf7e67008
Author: Robert Ancell <robert ancell gmail com>
Date: Fri Jun 26 20:47:15 2009 +1000
...
data/gcalctool.ui | 7 +-
src/display.c | 36 +++----
src/functions.c | 11 ++-
src/functions.h | 7 +-
src/gtk.c | 247 ++++++++++++++++++++++------------------------
src/mp-binary.c | 13 ++-
src/mp-convert.c | 191 +++++++++++++----------------------
src/mp-equation-lexer.l | 94 ++++++++++-------
src/mp-equation-parser.y | 50 ++++------
src/mp-trigonometric.c | 2 +-
src/mp.h | 4 +-
src/register.c | 4 +-
src/unittest.c | 13 ++-
13 files changed, 319 insertions(+), 360 deletions(-)
---
diff --git a/data/gcalctool.ui b/data/gcalctool.ui
index 271f450..1b2b7bb 100644
--- a/data/gcalctool.ui
+++ b/data/gcalctool.ui
@@ -2929,7 +2929,7 @@
</packing>
</child>
<child>
- <object class="GtkButton" id="calc_1s_button">
+ <object class="GtkButton" id="calc_ones_complement_button">
<property name="label" translatable="yes" comments="1's complement">ones</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -2948,7 +2948,7 @@
</packing>
</child>
<child>
- <object class="GtkButton" id="calc_2s_button">
+ <object class="GtkButton" id="calc_twos_complement_button">
<property name="label" translatable="yes" comments="2's complement">twos</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -3094,6 +3094,7 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="focus_on_click">False</property>
+ <signal name="clicked" handler="button_cb"/>
<child>
<object class="GtkLabel" id="base_2_label">
<property name="visible">True</property>
@@ -3117,6 +3118,7 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="focus_on_click">False</property>
+ <signal name="clicked" handler="button_cb"/>
<child>
<object class="GtkLabel" id="base_8_label">
<property name="visible">True</property>
@@ -3138,6 +3140,7 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="focus_on_click">False</property>
+ <signal name="clicked" handler="button_cb"/>
<child>
<object class="GtkLabel" id="base_16_label">
<property name="visible">True</property>
diff --git a/src/display.c b/src/display.c
index 5341f2d..1fa3690 100644
--- a/src/display.c
+++ b/src/display.c
@@ -673,7 +673,7 @@ void
make_eng_sci(GCDisplay *display, char *target, int target_len, const MPNumber *MPnumber, int base)
{
static char digits[] = "0123456789ABCDEF";
- char fixed[MAX_DIGITS], *optr;
+ char fixed[MAX_DIGITS];
MPNumber MP1, MPatmp, MPval;
MPNumber MP1base, MP3base, MP10base;
int i, dval, len;
@@ -681,17 +681,17 @@ make_eng_sci(GCDisplay *display, char *target, int target_len, const MPNumber *M
int ddig; /* Number of digits in exponent. */
int eng = 0; /* Set if this is an engineering number. */
int exp = 0; /* Exponent */
+ GString *string;
+
+ string = g_string_sized_new(target_len);
if (display->format == ENG) {
eng = 1;
}
- optr = target;
mp_abs(MPnumber, &MPval);
mp_set_from_integer(0, &MP1);
- if (mp_is_less_than(MPnumber, &MP1)) {
- strcpy(optr, "â??");
- optr += strlen("â??");
- }
+ if (mp_is_less_than(MPnumber, &MP1))
+ g_string_append(string, "â??");
mp_set_from_mp(&MPval, &MPmant);
mp_set_from_integer(base, &MP1base);
@@ -729,39 +729,35 @@ make_eng_sci(GCDisplay *display, char *target, int target_len, const MPNumber *M
mp_cast_to_string(&MPmant, base, v->accuracy, !v->display.show_zeroes, fixed, MAX_DIGITS);
len = strlen(fixed);
- for (i = 0; i < len; i++) {
- *optr++ = fixed[i];
- }
+ for (i = 0; i < len; i++)
+ g_string_append_c(string, fixed[i]);
- *optr++ = 'e';
+ g_string_append(string, "Ã?10^");
if (exp < 0) {
exp = -exp;
- strcpy(optr, "â??");
- optr += strlen("â??");
+ g_string_append(string, "â??");
} else {
- *optr++ = '+';
+ g_string_append(string, "+");
}
- mp_set_from_string("0.5", 10, &MP1);
+ mp_set_from_string("0.5", &MP1);
mp_add_integer(&MP1, exp, &MPval);
mp_set_from_integer(1, &MP1);
for (ddig = 0; mp_is_greater_equal(&MPval, &MP1); ddig++) {
mp_divide(&MPval, &MP1base, &MPval);
}
- if (ddig == 0) {
- *optr++ = '0';
- }
-
while (ddig-- > 0) {
mp_multiply(&MPval, &MP1base, &MPval);
dval = mp_cast_to_int(&MPval);
- *optr++ = digits[dval];
+ g_string_append_c(string, digits[dval]);
dval = -dval;
mp_add_integer(&MPval, dval, &MPval);
}
- *optr++ = '\0';
+
+ strncpy(target, string->str, target_len);
+ g_string_free(string, TRUE);
}
diff --git a/src/functions.c b/src/functions.c
index 75d0b57..9609fd0 100644
--- a/src/functions.c
+++ b/src/functions.c
@@ -71,6 +71,9 @@ static Function functions[NFUNCTIONS] = {
{ FN_NUMERIC_POINT, ".", NUMBER },
{ FN_EULERS_NUMBER, "e", 0},
{ FN_PI, "Ï?", 0},
+{ FN_BASE2, "â??", 0},
+{ FN_BASE8, "â??", 0},
+{ FN_BASE16, "â??â??", 0},
{ FN_SUPER_0, "â?°", 0 },
{ FN_SUPER_1, "¹", 0 },
{ FN_SUPER_2, "²", 0 },
@@ -122,8 +125,8 @@ static Function functions[NFUNCTIONS] = {
{ FN_ABSOLUTE_VALUE, "|", 0 },
{ FN_TRUNC, "trunc", 0 },
{ FN_MODULUS_DIVIDE, "mod", 0 },
-{ FN_1S_COMPLEMENT, "ones", 0 },
-{ FN_2S_COMPLEMENT, "twos", 0 },
+{ FN_ONES_COMPLEMENT, "ones", 0 },
+{ FN_TWOS_COMPLEMENT, "twos", 0 },
{ FN_EXPONENTIAL, "Ã?10^", 0 },
{ FN_NOT, "~", 0 },
{ FN_OR, "or", 0 },
@@ -367,7 +370,7 @@ do_expression(int function, int arg, int cursor_start, int cursor_end)
case FN_CLEAR:
display_clear(&v->display);
ui_set_error_state(FALSE);
- mp_set_from_string("0", 10, ans);
+ mp_set_from_string("0", ans);
break;
case FN_SHIFT:
@@ -429,7 +432,7 @@ do_expression(int function, int arg, int cursor_start, int cursor_end)
/* 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);
+ mp_set_from_string(buf, &MP);
display_set_number(&v->display, &MP);
}
break;
diff --git a/src/functions.h b/src/functions.h
index eecd69c..11e8893 100644
--- a/src/functions.h
+++ b/src/functions.h
@@ -34,6 +34,9 @@ enum
FN_NUMERIC_POINT,
FN_EULERS_NUMBER,
FN_PI,
+ FN_BASE2,
+ FN_BASE8,
+ FN_BASE16,
FN_SUPER_0, FN_SUPER_1, FN_SUPER_2, FN_SUPER_3,
FN_SUPER_4, FN_SUPER_5, FN_SUPER_6, FN_SUPER_7,
FN_SUPER_8, FN_SUPER_9, FN_SUPER_MINUS,
@@ -66,8 +69,8 @@ enum
FN_ABSOLUTE_VALUE,
FN_TRUNC,
FN_MODULUS_DIVIDE,
- FN_1S_COMPLEMENT,
- FN_2S_COMPLEMENT,
+ FN_ONES_COMPLEMENT,
+ FN_TWOS_COMPLEMENT,
FN_EXPONENTIAL,
FN_NOT,
FN_OR,
diff --git a/src/gtk.c b/src/gtk.c
index 3bca412..185adc1 100644
--- a/src/gtk.c
+++ b/src/gtk.c
@@ -20,6 +20,8 @@
* 02111-1307, USA.
*/
+//â?°Â¹Â²Â³â?´â?µâ?¶â?·â?¸â?¹â?»â??â??â??â??â??â??â??â??â??â??â??
+
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -98,18 +100,6 @@ static char *finc_dialog_fields[FINC_NUM_DIALOGS][5] = {
{"term_pmt", "term_fv", "term_pint", NULL, NULL},
};
-/* This table shows the keyboard values that are currently being used:
- *
- * | a b c d e f g h i j k l m n o p q r s t u v w x y z
- *-----------+-----------------------------------------------------
- * Lower: | a b c d e f g h i j k l m n o p q r s t u v w x z
- * Upper: | A C D E F G H I J K M N O P Q R S T W X Y Z
- * Numeric: | 0 1 2 3 4 5 6 7 8 9
- * Other: | @ . + - * / = % ( ) # < > [ { | & ~ ^ ? ! :
- * | BackSpace Delete Return
- *-----------+-----------------------------------------------------
- */
-
static struct button_widget button_widgets[] = {
{FN_0, "0",
{ 0, 0, 0, 0 },
@@ -152,36 +142,48 @@ static struct button_widget button_widgets[] = {
{ GDK_9, GDK_KP_9, GDK_KP_Page_Up, GDK_R9, 0 }},
{FN_A, "a",
- { 0, 0 },
- { GDK_a, 0 }},
+ { 0, 0, 0 },
+ { GDK_a, GDK_A, 0 }},
{FN_B, "b",
- { 0, 0 },
- { GDK_b, 0 }},
+ { 0, 0, 0 },
+ { GDK_b, GDK_B, 0 }},
{FN_C, "c",
- { 0, 0 },
- { GDK_c, 0 }},
+ { 0, 0, 0 },
+ { GDK_c, GDK_C, 0 }},
{FN_D, "d",
- { 0, 0 },
- { GDK_d, 0 }},
+ { 0, 0, 0 },
+ { GDK_d, GDK_D, 0 }},
{FN_E, "e",
- { 0, 0 },
- { GDK_e, 0 }},
+ { 0, 0, 0 },
+ { GDK_e, GDK_E, 0 }},
{FN_F, "f",
- { 0, 0 },
- { GDK_f, 0 }},
+ { 0, 0, 0 },
+ { GDK_f, GDK_F, 0 }},
+
+ {FN_BASE2, "base_2",
+ { 0 },
+ { 0 }},
+
+ {FN_BASE8, "base_8",
+ { 0 },
+ { 0 }},
+
+ {FN_BASE16, "base_16",
+ { 0 },
+ { 0 }},
{FN_PI, "pi",
- { 0, 0 },
- { 0, 0 }},
+ { GDK_CONTROL_MASK, 0 },
+ { GDK_p, 0 }},
{FN_EULERS_NUMBER, "eulers_number",
- { 0, 0 },
- { 0, 0 }},
+ { 0 },
+ { 0 }},
{FN_CLEAR, "clear",
{ 0, GDK_SHIFT_MASK, GDK_CONTROL_MASK, 0 },
@@ -196,12 +198,12 @@ static struct button_widget button_widgets[] = {
{ GDK_greater, 0 }},
{FN_STORE, "store",
- { 0, 0 },
- { GDK_S, 0 }},
+ { 0 },
+ { 0 }},
{FN_RECALL, "recall",
- { 0, 0 },
- { GDK_R, 0 }},
+ { 0 },
+ { 0 }},
{FN_NUMERIC_POINT, "numeric_point",
{ 0, 0, 0, 0, 0 },
@@ -236,148 +238,148 @@ static struct button_widget button_widgets[] = {
{ GDK_slash, GDK_division, GDK_KP_Divide, GDK_R5, 0 }},
{FN_INTEGER, "integer_portion",
- { 0, 0 },
- { GDK_i, 0 }},
+ { 0 },
+ { 0 }},
{FN_PERCENTAGE, "percentage",
{ 0, 0 },
{ GDK_percent, 0 }},
{FN_ROOT, "root",
- { 0, 0 },
- { GDK_s, 0 }},
+ { GDK_CONTROL_MASK, 0 },
+ { GDK_r, 0 }},
{FN_INVERSE, "inverse",
- { 0, 0 },
- { GDK_r, 0 }},
+ { GDK_CONTROL_MASK, 0 },
+ { GDK_i, 0 }},
{FN_ABSOLUTE_VALUE, "abs",
- { 0, 0 },
- { GDK_u, 0 }},
+ { 0, 0 },
+ { GDK_bar, 0 }},
{FN_TRUNC, "trunc",
- { 0, 0 },
- { GDK_bracketleft, 0 }},
+ { 0 },
+ { 0 }},
{FN_MODULUS_DIVIDE, "modulus_divide",
- { 0, 0 },
- { GDK_M, 0 }},
+ { 0 },
+ { 0 }},
- {FN_1S_COMPLEMENT, "1s",
- { 0, 0 },
- { GDK_z, 0 }},
+ {FN_ONES_COMPLEMENT, "ones_complement",
+ { 0 },
+ { 0 }},
- {FN_2S_COMPLEMENT, "2s",
- { 0, 0 },
- { GDK_Z, 0 }},
+ {FN_TWOS_COMPLEMENT, "twos_complement",
+ { 0 },
+ { 0 }},
{FN_EXPONENTIAL, "exponential",
- { 0, 0 },
- { GDK_E, 0 }},
+ { GDK_CONTROL_MASK, 0 },
+ { GDK_e, 0 }},
{FN_FACTORIAL, "factorial",
{ 0, 0 },
{ GDK_exclam, 0 }},
{FN_RANDOM, "random",
- { 0, 0 },
- { GDK_question, 0 }},
+ { 0 },
+ { 0 }},
{FN_NOT, "not",
- { 0, 0 },
- { GDK_asciitilde, 0 }},
+ { 0 },
+ { 0 }},
{FN_OR, "or",
- { 0, 0 },
- { GDK_bar, 0 }},
+ { GDK_CONTROL_MASK, 0 },
+ { GDK_bar, 0 }},
{FN_AND, "and",
- { 0, 0 },
- { GDK_ampersand, 0 }},
+ { GDK_CONTROL_MASK, 0 },
+ { GDK_ampersand, 0 }},
{FN_XOR, "xor",
- { 0, 0 },
- { GDK_x, 0 }},
+ { 0 },
+ { 0 }},
{FN_XNOR, "xnor",
- { 0, 0 },
- { GDK_braceleft, 0 }},
+ { 0 },
+ { 0 }},
{FN_SIN, "sine",
- { 0, 0 },
- { GDK_k, 0 }},
+ { 0 },
+ { 0 }},
{FN_SINH, "hyperbolic_sine",
- { 0, 0 },
- { GDK_K, 0 }},
+ { 0 },
+ { 0 }},
{FN_COS, "cosine",
- { 0, 0 },
- { GDK_j, 0 }},
+ { 0 },
+ { 0 }},
{FN_COSH, "hyperbolic_cosine",
- { 0, 0 },
- { GDK_J, 0 }},
+ { 0 },
+ { 0 }},
{FN_TAN, "tangent",
- { 0, 0 },
- { GDK_w, 0 }},
+ { 0 },
+ { 0 }},
{FN_TANH, "hyperbolic_tangent",
- { 0, 0 },
- { GDK_W, 0 }},
+ { 0 },
+ { 0 }},
{FN_NATURAL_LOGARITHM, "natural_logarithm",
- { 0, 0 },
- { GDK_n, 0 }},
+ { 0 },
+ { 0 }},
{FN_LOGARITHM, "logarithm",
- { 0, 0 },
- { GDK_g, 0 }},
+ { 0 },
+ { 0 }},
{FN_X_POW_Y, "x_pow_y",
- { 0, 0, 0, 0 },
- { GDK_o, GDK_caret, GDK_asciicircum, 0 }},
+ { 0, 0, 0 },
+ { GDK_caret, GDK_asciicircum, 0 }},
{ 0, "finc_compounding_term",
- { 0, 0 },
- { GDK_m, 0 }},
+ { 0 },
+ { 0 }},
{ 0, "finc_double_declining_depreciation",
- { 0, 0 },
- { GDK_D, 0 }},
+ { 0 },
+ { 0 }},
{ 0, "finc_future_value",
- { 0, 0 },
- { GDK_v, 0 }},
+ { 0 },
+ { 0 }},
{ 0, "finc_gross_profit_margin",
- { 0, 0 },
- { GDK_I, 0 }},
+ { 0 },
+ { 0 }},
{ 0, "finc_periodic_payment",
- { 0, 0 },
- { GDK_P, 0 }},
+ { 0 },
+ { 0 }},
{ 0, "finc_present_value",
- { 0, 0 },
- { GDK_p, 0 }},
+ { 0 },
+ { 0 }},
{ 0, "finc_periodic_interest_rate",
- { 0, 0 },
- { GDK_T, 0 }},
+ { 0 },
+ { 0 }},
{ 0, "finc_straight_line_depreciation",
- { 0, 0 },
- { GDK_l, 0 }},
+ { 0 },
+ { 0 }},
{ 0, "finc_sum_of_the_years_digits_depreciation",
- { 0, 0 },
- { GDK_Y, 0 }},
+ { 0 },
+ { 0 }},
{ 0, "finc_term",
- { 0, 0 },
- { GDK_t, 0 }}
+ { 0 },
+ { 0 }}
};
#define NBUTTONS (sizeof(button_widgets) / sizeof(struct button_widget))
@@ -1200,7 +1202,7 @@ finc_response_cb(GtkWidget *widget, gint response_id)
}
entry = GET_FINC_WIDGET(finc_dialog_fields[dialog][i]);
// FIXME: Have to delocalize the input
- 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)), &arg[i]);
gtk_entry_set_text(GTK_ENTRY(entry), "0");
}
gtk_widget_grab_focus(GET_FINC_WIDGET(finc_dialog_fields[dialog][0]));
@@ -1506,13 +1508,13 @@ main_window_key_press_cb(GtkWidget *widget, GdkEventKey *event)
{
int i, j, state;
GtkWidget *button;
+ const char *allowed_input = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*/^|!%";
- printf("'%s'\n", event->string);
-
/* Only look at the modifiers we use */
state = event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK);
// FIXME: Convert event to character
+ // FIXME: Or safer to intercept characters as they enter the text input (handles input methods)
if (check_for_localized_numeric_point(event->keyval) == TRUE) {
event->state = 0;
@@ -1520,41 +1522,42 @@ main_window_key_press_cb(GtkWidget *widget, GdkEventKey *event)
}
/* Accuracy shortcuts */
- if (state == GDK_CONTROL_MASK) {
+ if (state == GDK_CONTROL_MASK || state == GDK_MOD1_MASK) {
+ gboolean do_sub = state == GDK_MOD1_MASK;
switch (event->keyval) {
case GDK_0:
- do_button(event->state & GDK_SHIFT_MASK ? FN_SUB_0 : FN_SUPER_0, 0);
+ do_button(do_sub ? FN_SUB_0 : FN_SUPER_0, 0);
return TRUE;
case GDK_1:
- do_button(event->state & GDK_SHIFT_MASK ? FN_SUB_1 : FN_SUPER_1, 0);
+ do_button(do_sub ? FN_SUB_1 : FN_SUPER_1, 0);
return TRUE;
case GDK_2:
- do_button(event->state & GDK_SHIFT_MASK ? FN_SUB_2 : FN_SUPER_2, 0);
+ do_button(do_sub ? FN_SUB_2 : FN_SUPER_2, 0);
return TRUE;
case GDK_3:
- do_button(event->state & GDK_SHIFT_MASK ? FN_SUB_3 : FN_SUPER_3, 0);
+ do_button(do_sub ? FN_SUB_3 : FN_SUPER_3, 0);
return TRUE;
case GDK_4:
- do_button(event->state & GDK_SHIFT_MASK ? FN_SUB_4 : FN_SUPER_4, 0);
+ do_button(do_sub ? FN_SUB_4 : FN_SUPER_4, 0);
return TRUE;
case GDK_5:
- do_button(event->state & GDK_SHIFT_MASK ? FN_SUB_5 : FN_SUPER_5, 0);
+ do_button(do_sub ? FN_SUB_5 : FN_SUPER_5, 0);
return TRUE;
case GDK_6:
- do_button(event->state & GDK_SHIFT_MASK ? FN_SUB_6 : FN_SUPER_6, 0);
+ do_button(do_sub ? FN_SUB_6 : FN_SUPER_6, 0);
return TRUE;
case GDK_7:
- do_button(event->state & GDK_SHIFT_MASK ? FN_SUB_7 : FN_SUPER_7, 0);
+ do_button(do_sub ? FN_SUB_7 : FN_SUPER_7, 0);
return TRUE;
case GDK_8:
- do_button(event->state & GDK_SHIFT_MASK ? FN_SUB_8 : FN_SUPER_8, 0);
+ do_button(do_sub ? FN_SUB_8 : FN_SUPER_8, 0);
return TRUE;
case GDK_9:
- do_button(event->state & GDK_SHIFT_MASK ? FN_SUB_9 : FN_SUPER_9, 0);
+ do_button(do_sub ? FN_SUB_9 : FN_SUPER_9, 0);
return TRUE;
case GDK_minus:
case GDK_KP_Subtract:
- do_button(event->state & GDK_SHIFT_MASK ? FN_SUB_MINUS : FN_SUPER_MINUS, 0);
+ do_button(do_sub ? FN_SUB_MINUS : FN_SUPER_MINUS, 0);
return TRUE;
}
}
@@ -1582,16 +1585,6 @@ main_window_key_press_cb(GtkWidget *widget, GdkEventKey *event)
for (i = 0; i < NBUTTONS; i++) {
button = X.buttons[i];
-
- /* Check if function is available */
- if (!GTK_WIDGET_IS_SENSITIVE(button))
- continue;
-
- /* In basic mode only allow buttons that the user can see */
- if (X.mode == BASIC &&
- (!GTK_WIDGET_VISIBLE(gtk_widget_get_parent(button)) ||
- !GTK_WIDGET_VISIBLE(button)))
- continue;
// FIXME: This is a bit hacky - needs to be rethought
for (j = 0; button_widgets[i].accelerator_keys[j] != 0; j++) {
diff --git a/src/mp-binary.c b/src/mp-binary.c
index e9b10b7..153a4bd 100644
--- a/src/mp-binary.c
+++ b/src/mp-binary.c
@@ -19,13 +19,13 @@ static int hex_to_int(char digit)
static void
mp_bitwise(const MPNumber *x, const MPNumber *y, int (*bitwise_operator)(int, int), MPNumber *z, int wordlen)
{
- char text1[MAX_DIGITS], text2[MAX_DIGITS], text_out[MAX_DIGITS];
+ char text1[MAX_DIGITS], text2[MAX_DIGITS], text_out[MAX_DIGITS], text_out2[MAX_DIGITS];
int offset1, offset2, offset_out;
mp_cast_to_string(x, 16, 0, 0, text1, MAX_DIGITS);
mp_cast_to_string(y, 16, 0, 0, text2, MAX_DIGITS);
- offset1 = strlen(text1) - 1;
- offset2 = strlen(text2) - 1;
+ offset1 = strlen(text1) - 1 - strlen("â??â??");
+ offset2 = strlen(text2) - 1 - strlen("â??â??");
offset_out = wordlen / 4 - 1;
if (offset_out <= 0) {
offset_out = offset1 > offset2 ? offset1 : offset2;
@@ -50,7 +50,8 @@ mp_bitwise(const MPNumber *x, const MPNumber *y, int (*bitwise_operator)(int, in
text_out[offset_out] = digits[bitwise_operator(v1, v2)];
}
- mp_set_from_string(text_out, 16, z);
+ snprintf(text_out2, MAX_DIGITS, "%sâ??â??", text_out);
+ mp_set_from_string(text_out2, z);
}
@@ -116,10 +117,10 @@ mp_mask(const MPNumber *x, int wordlen, MPNumber *z)
/* Convert to a hexadecimal string and use last characters */
mp_cast_to_string(x, 16, 0, 0, text, MAX_DIGITS);
- len = strlen(text);
+ len = strlen(text) - strlen("â??â??");
offset = wordlen / 4;
offset = len > offset ? len - offset: 0;
- mp_set_from_string(text + offset, 16, z);
+ mp_set_from_string(text + offset, z);
}
diff --git a/src/mp-convert.c b/src/mp-convert.c
index c7d1a3f..0a01914 100644
--- a/src/mp-convert.c
+++ b/src/mp-convert.c
@@ -479,29 +479,19 @@ mp_cast_to_double(const MPNumber *x)
* maximum number of digits specified.
*/
void
-mp_cast_to_string(const MPNumber *MPnumber, int base, int accuracy, int trim_zeroes, char *buffer, int buffer_length)
+mp_cast_to_string(const MPNumber *x, int base, int accuracy, int trim_zeroes, char *buffer, int buffer_length)
{
static char digits[] = "0123456789ABCDEF";
- char *optr, *start, *end, *stopper, *last_non_zero;
MPNumber number, integer_component, fractional_component, MPbase, temp;
- int i;
-
- optr = buffer;
- stopper = buffer + buffer_length - 1;
-
- /* Insert sign */
- if (mp_is_negative(MPnumber)) {
- if (optr + strlen("â??") >= stopper) {
- mperr(_("Number too big to represent"));
- *optr = '\0';
- return;
- }
- strcpy(optr, "â??");
- optr += strlen("â??");
- mp_abs(MPnumber, &number);
- } else {
- mp_set_from_mp(MPnumber, &number);
- }
+ int i, last_non_zero;
+ GString *string;
+
+ string = g_string_sized_new(buffer_length);
+
+ if (mp_is_negative(x))
+ mp_abs(x, &number);
+ else
+ mp_set_from_mp(x, &number);
/* Add rounding factor */
mp_set_from_integer(base, &MPbase);
@@ -515,7 +505,6 @@ mp_cast_to_string(const MPNumber *MPnumber, int base, int accuracy, int trim_zer
mp_fractional_component(&number, &fractional_component);
/* Write out the integer component least significant digit to most */
- start = optr;
mp_set_from_mp(&integer_component, &temp);
do {
MPNumber t, t2, t3;
@@ -527,29 +516,13 @@ mp_cast_to_string(const MPNumber *MPnumber, int base, int accuracy, int trim_zer
mp_subtract(&temp, &t2, &t3);
mp_integer_component(&t3, &t3);
- if (optr == stopper) {
- mperr(_("Number too big to represent"));
- *optr = '\0';
- return;
- }
- *optr++ = digits[mp_cast_to_int(&t3)];
+ g_string_prepend_c(string, digits[mp_cast_to_int(&t3)]);
mp_set_from_mp(&t, &temp);
} while (!mp_is_zero(&temp));
-
- /* Reverse digits */
- end = optr - 1;
- while(start < end) {
- char t;
- t = *start;
- *start = *end;
- *end = t;
- start++;
- end--;
- }
-
- last_non_zero = optr;
- *optr++ = '.';
+
+ last_non_zero = string->len;
+ g_string_append_c(string, '.');
/* Write out the fractional component */
mp_set_from_mp(&fractional_component, &temp);
@@ -561,29 +534,40 @@ mp_cast_to_string(const MPNumber *MPnumber, int base, int accuracy, int trim_zer
mp_integer_component(&temp, &digit);
d = mp_cast_to_int(&digit);
- if (optr == stopper) {
- mperr(_("Number too big to represent"));
- *optr = '\0';
- return;
- }
- *optr++ = digits[d];
+ g_string_append_c(string, digits[d]);
if(d != 0)
- last_non_zero = optr;
+ last_non_zero = string->len;
mp_subtract(&temp, &digit, &temp);
}
/* Strip trailing zeroes */
if (trim_zeroes || accuracy == 0)
- optr = last_non_zero;
-
- *optr = '\0';
+ g_string_truncate(string, last_non_zero);
/* Remove negative sign if the number was rounded down to zero */
- if (strcmp(buffer, "â??0") == 0) {
- buffer[0] = '0';
- buffer[1] = '\0';
+ if (mp_is_negative(x) && strcmp(string->str, "0") != 0)
+ g_string_prepend(string, "â??");
+
+ switch(base)
+ {
+ case 2:
+ g_string_append(string, "â??");
+ break;
+ case 8:
+ g_string_append(string, "â??");
+ break;
+ default:
+ case 10:
+ break;
+ case 16:
+ g_string_append(string, "â??â??");
+ break;
}
+
+ // FIXME: Check for truncation
+ strncpy(buffer, string->str, buffer_length);
+ g_string_free(string, TRUE);
}
@@ -606,97 +590,64 @@ char_val(char chr, int base)
}
-/* Convert string into an MP number, in the given base
- */
+/* Convert string into an MP number */
void
-mp_set_from_string(const char *str, int base, MPNumber *MPval)
+mp_set_from_string(const char *str, MPNumber *MPval)
{
- const char *optr;
- int inum;
- int negate = 0;
-
- optr = str;
-
- /* Remove leading whitespace */
- while (isspace(*optr)) {
- optr++;
+ int i, base, negate = 0;
+ const char *c, *end;
+ const char *base_suffixes[] = {"â??", "â??", "â??â??", NULL};
+ int base_values[] = {2, 8, 16, 10};
+
+ /* Find the base */
+ end = str;
+ while (*end != '\0')
+ end++;
+ for (i = 0; base_suffixes[i] != NULL; i++) {
+ if (end - strlen(base_suffixes[i]) < str)
+ continue;
+ if (strcmp(end - strlen(base_suffixes[i]), base_suffixes[i]) == 0)
+ break;
}
+ base = base_values[i];
- /* Check if this is a negative number. */
- if (*optr == '-') {
+ /* Check if this is a negative number */
+ c = str;
+ if (*c == '-') {
negate = 1;
- optr++;
- } else if (strncmp(optr, "â??", strlen("â??")) == 0) {
+ c++;
+ } else if (strncmp(c, "â??", strlen("â??")) == 0) {
negate = 1;
- optr += strlen("â??");
+ c += strlen("â??");
}
-
+
/* Convert integer part */
mp_set_from_integer(0, MPval);
- while ((inum = char_val(*optr, base)) >= 0) {
+ while ((i = char_val(*c, base)) >= 0) {
mp_multiply_integer(MPval, base, MPval);
- mp_add_integer(MPval, inum, MPval);
- optr++;
+ mp_add_integer(MPval, i, MPval);
+ c++;
}
/* Convert fractional part */
- if (*optr == '.') {
+ if (*c == '.') {
MPNumber numerator, denominator;
- optr++;
+ c++;
mp_set_from_integer(0, &numerator);
mp_set_from_integer(1, &denominator);
- while ((inum = char_val(*optr, base)) >= 0) {
+ while ((i = char_val(*c, base)) >= 0) {
mp_multiply_integer(&denominator, base, &denominator);
mp_multiply_integer(&numerator, base, &numerator);
- mp_add_integer(&numerator, inum, &numerator);
- optr++;
+ mp_add_integer(&numerator, i, &numerator);
+ c++;
}
mp_divide(&numerator, &denominator, &numerator);
mp_add(MPval, &numerator, MPval);
}
- /* Convert exponential part */
- if (*optr == 'e' || *optr == 'E') {
- int negate = 0;
- MPNumber MPbase, MPexponent, temp;
-
- optr++;
-
- /* Get sign */
- if (*optr == '-') {
- negate = 1;
- optr++;
- } else if (strncmp(optr, "â??", strlen("â??")) == 0) {
- negate = 1;
- optr += strlen("â??");
- } else if (*optr == '+') {
- optr++;
- }
-
- /* Get magnitude */
- mp_set_from_integer(0, &MPexponent);
- while ((inum = char_val(*optr, base)) >= 0) {
- mp_multiply_integer(&MPexponent, base, &MPexponent);
- mp_add_integer(&MPexponent, inum, &MPexponent);
- optr++;
- }
- if (negate) {
- mp_invert_sign(&MPexponent, &MPexponent);
- }
-
- mp_set_from_integer(base, &MPbase);
- mp_pwr(&MPbase, &MPexponent, &temp);
- mp_multiply(MPval, &temp, MPval);
- }
-
- /* Strip trailing whitespace */
- while (isspace(*optr)) {
- optr++;
- }
-
- if (*optr != '\0') {
+ if (c != end) {
// FIXME: Error decoding
}
diff --git a/src/mp-equation-lexer.l b/src/mp-equation-lexer.l
index d9462db..e5edb3e 100644
--- a/src/mp-equation-lexer.l
+++ b/src/mp-equation-lexer.l
@@ -10,6 +10,7 @@
/* $Header: /cvs/gnome/gcalctool/gcalctool/ce_tokeniser.l,v 1.16 2006/12/15 15:27:37 richb Exp $
*
* Copyright (C) 2004-2008 Sami Pietila
+ * Copyright (C) 2008-2009 Robert Ancell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -35,18 +36,57 @@
#include "calctool.h"
#include "mp-equation.h"
#include "mp-equation-parser.h"
+
+static int super_atoi(const char *data)
+{
+ int i, value = 0;
+ const char *digits[11] = {"�", "¹", "²", "³", "�", "�", "�", "�", "�", "�", NULL};
+
+ while(*data != '\0') {
+ for(i = 0; digits[i] != NULL && strncmp(data, digits[i], strlen(digits[i])) != 0; i++);
+ if(digits[i] == NULL)
+ return 0;
+ value = value * 10 + i;
+ data += strlen(digits[i]);
+ }
+
+ return value;
+}
+
+static int sub_atoi(const char *data)
+{
+ int i, value = 0;
+ const char *digits[11] = {"â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", NULL};
+
+ while(*data != '\0') {
+ for(i = 0; digits[i] != NULL && strncmp(data, digits[i], strlen(digits[i])) != 0; i++);
+ if(digits[i] == NULL)
+ return 0;
+ data += strlen(digits[i]);
+ value = value * 10 + i;
+ }
+
+ return value;
+}
%}
-DECIMAL "."|","
-SIGN "+"|"-"|"â??"
-BIN [0-1]
-OCT [0-7]
-DEC [0-9]
-HEX [0-9]|[A-F]|[a-f]
-HEX_NUM {HEX}+|{HEX}*{DECIMAL}{HEX}*
-DEC_NUM{DEC}+|{DEC}*{DECIMAL}{DEC}*
-OCT_NUM{OCT}+|{OCT}*{DECIMAL}{OCT}*
-BIN_NUM{BIN}+|{BIN}*{DECIMAL}{BIN}*
+DECIMAL "."|","
+BIN [0-1]
+BIN_SUFFIX "â??"
+OCT [0-7]
+OCT_SUFFIX "â??"
+DEC [0-9]
+HEX [0-9]|[A-F]|[a-f]
+HEX_SUFFIX "â??â??"
+SUPER_DIGITS "�"|"¹"|"²"|"³"|"�"|"�"|"�"|"�"|"�"|"�"
+SUB_DIGITS "â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"|"â??"
+
+HEX_NUM {HEX}+{HEX_SUFFIX}|{HEX}*{DECIMAL}{HEX}+{HEX_SUFFIX}
+DEC_NUM {DEC}+|{DEC}*{DECIMAL}{DEC}+
+OCT_NUM {OCT}+{OCT_SUFFIX}|{OCT}*{DECIMAL}{OCT}+{OCT_SUFFIX}
+BIN_NUM {BIN}+{BIN_SUFFIX}|{BIN}*{DECIMAL}{BIN}+{BIN_SUFFIX}
+SUP_NUM {SUPER_DIGITS}+
+SUB_NUM {SUB_DIGITS}+
%%
@@ -70,14 +110,12 @@ BIN_NUM{BIN}+|{BIN}*{DECIMAL}{BIN}*
"tanh�¹"|"atanh"|"Atanh"|"ATANH" {return tATANH;}
"â?§"|"and"|"And"|"AND" {return tAND;}
"ans"|"Ans"|"ANS" {return tANS;}
-"chs"|"Chs"|"CHS" {return tCHS;}
"clr"|"Clr"|"CLR" {return tCLR;}
"eng"|"Eng"|"ENG" {return tEXP;}
"frac"|"Frac"|"FRAC" {return tFRAC;}
"int"|"Int"|"INT" {return tINT;}
"ln"|"Ln"|"LN" {return tLN;}
-"log"|"Log"|"LOG" {return tLOG10;}
-"logâ??"|"Logâ??"|"log_2"|"Log_2"|"LOG_2" {return tLOG2;}
+"log"|"Log"|"LOG" {return tLOG;}
"mod"|"Mod"|"MOD" {return tMOD;}
"¬"|"~" {return tNOT;}
"â?¨"|"or"|"Or"|"OR" {return tOR;}
@@ -87,8 +125,6 @@ BIN_NUM{BIN}+|{BIN}*{DECIMAL}{BIN}*
"â??"|"sqrt"|"Sqrt"|"SQRT" {return tROOT;}
"â??"|"cbrt"|"Cbrt"|"CBRT" {return tROOT3;}
"â??" {return tROOT4;}
-"²" {return tSQUARED;}
-"³" {return tCUBED;}
"sto"|"Sto"|"STO" {return tSTO;}
"trunc"|"Trunc"|"TRUNC" {return tTRUNC;}
"ones" {return t1S;}
@@ -101,35 +137,15 @@ yylval->integer = atoi(yytext+1);
return tREG;
}
-{BIN_NUM} {
-if (_mp_equation_get_extra(yyscanner)->base != 2) REJECT;
-if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->base, &yylval->int_t);
-return tNUMBER;
-}
-
-{OCT_NUM} {
-if (_mp_equation_get_extra(yyscanner)->base != 8) REJECT;
-if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->base, &yylval->int_t);
-return tNUMBER;
-}
+{SUP_NUM} { yylval->integer = super_atoi(yytext); return tSUPNUM; }
+{SUB_NUM} { yylval->integer = sub_atoi(yytext); return tSUBNUM; }
-{DEC_NUM} {
-if (_mp_equation_get_extra(yyscanner)->base != 10) REJECT;
+{BIN_NUM}|{OCT_NUM}|{DEC_NUM}|{HEX_NUM} {
if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->base, &yylval->int_t);
+mp_set_from_string(yytext, &yylval->int_t);
return tNUMBER;
}
-{HEX_NUM} {
-if (_mp_equation_get_extra(yyscanner)->base != 16) REJECT;
-if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->base, &yylval->int_t);
-return tNUMBER;
-}
-
-
[ \t\n]
. {return *yytext; }
diff --git a/src/mp-equation-parser.y b/src/mp-equation-parser.y
index b539d5b..fff7456 100644
--- a/src/mp-equation-parser.y
+++ b/src/mp-equation-parser.y
@@ -3,6 +3,7 @@
/* $Header: /cvs/gnome/gcalctool/gcalctool/ce_parser.y,v 1.16 2006/12/08 15:54:43 richb Exp $
*
* Copyright (C) 2004-2008 Sami Pietila
+ * Copyright (C) 2008-2009 Robert Ancell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -65,8 +66,7 @@
%token tFRAC
%token tINT
%token tLN
-%token tLOG10
-%token tLOG2
+%token tLOG
%token tMOD
%token t1S
%token t2S
@@ -80,8 +80,6 @@
%token tROOT
%token tROOT3
%token tROOT4
-%token tSQUARED
-%token tCUBED
%token tSQRT
%token tSTO
%token tTAN
@@ -92,10 +90,11 @@
%token <int_t> tNUMBER
%token <integer> tREG
+%token <integer> tSUBNUM tSUPNUM
%token NEG
-%type <int_t> exp rcl value term reg func number parenthesis
+%type <int_t> exp rcl value term func number
%start statement
%left tADD tSUBTRACT tMULTIPLY tDIVIDE
@@ -148,17 +147,13 @@ value:
exp:
term {mp_set_from_mp(&$1, &$$);}
-
| exp tADD term '%' {mp_add_integer(&$3, 100, &$3); mp_divide_integer(&$3, 100, &$3); mp_multiply(&$1, &$3, &$$);}
| exp tSUBTRACT term '%' {mp_add_integer(&$3, -100, &$3); mp_divide_integer(&$3, -100, &$3); mp_multiply(&$1, &$3, &$$);}
-
| exp tROOT term {MPNumber t; mp_sqrt(&$3, &t); mp_multiply(&$1, &t, &$$);}
| exp tROOT3 term {MPNumber t; mp_root(&$3, 3, &t); mp_multiply(&$1, &t, &$$);}
| exp tROOT4 term {MPNumber t; mp_root(&$3, 4, &t); mp_multiply(&$1, &t, &$$);}
-
| exp tADD exp {mp_add(&$1, &$3, &$$);}
| exp tSUBTRACT exp {mp_subtract(&$1, &$3, &$$);}
-
| exp tMOD exp %prec MED {
if (!mp_is_integer(&$1) || !mp_is_integer(&$3)) {
(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_MODULUSOP;
@@ -168,7 +163,6 @@ exp:
}
}
}
-
| exp tAND exp {
if (!mp_is_natural(&$1) || !mp_is_natural(&$3)) {
(_mp_equation_get_extra(yyscanner))->error = -PARSER_ERR_BITWISEOP;
@@ -201,6 +195,7 @@ term:
| 'e' {mp_get_eulers(&$$);}
| tPI {mp_get_pi(&$$);}
| rcl {mp_set_from_mp(&$1, &$$);}
+| tSUBNUM tROOT term {mp_root(&$3, $1, &$$);}
| tROOT term {mp_sqrt(&$2, &$$);}
| tROOT3 term {mp_root(&$2, 3, &$$);}
| tROOT4 term {mp_root(&$2, 4, &$$);}
@@ -208,8 +203,7 @@ term:
| term tMULTIPLY term {mp_multiply(&$1, &$3, &$$);}
| tABS exp tABS {mp_abs(&$2, &$$);}
| term '!' {mp_factorial(&$1, &$$);}
-| term tSQUARED {mp_pwr_integer(&$1, 2, &$$);}
-| term tCUBED {mp_pwr_integer(&$1, 3, &$$);}
+| term tSUPNUM {mp_pwr_integer(&$1, $2, &$$);}
| term '%' {mp_divide_integer(&$1, 100, &$$);}
| tNOT term %prec LNEG {
if (!mp_is_natural(&$2)) {
@@ -219,49 +213,41 @@ term:
}
mp_not(&$2, _mp_equation_get_extra(yyscanner)->wordlen, &$$);
}
-| tSUBTRACT term %prec NEG {mp_invert_sign(&$2, &$$);}
-| tADD term %prec POS {mp_set_from_mp(&$2, &$$);}
+| tSUBTRACT term {mp_invert_sign(&$2, &$$);}
+| tADD term {mp_set_from_mp(&$2, &$$);}
| term '^' term {mp_xpowy(&$1, &$3, &$$);}
-
| term func {mp_multiply(&$1, &$2, &$$);}
| func {mp_set_from_mp(&$1, &$$);}
-| reg {mp_set_from_mp(&$1, &$$);}
-
-| parenthesis {mp_set_from_mp(&$1, &$$);}
+| tREG {mp_set_from_mp(register_get_value($1), &$$);}
+| '(' exp ')' {mp_set_from_mp(&$2, &$$);}
;
-parenthesis:
- '(' exp ')' {mp_set_from_mp(&$2, &$$);}
- ;
-
-reg:
- tREG {mp_set_from_mp(register_get_value($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, &$$);}
+ tLOG term %prec HIGH {mp_logarithm(10, &$2, &$$);}
| tLN term %prec HIGH {mp_ln(&$2, &$$);}
+| tLOG tSUBNUM term %prec HIGH {mp_logarithm($2, &$3, &$$);}
| tRAND %prec HIGH {mp_set_from_random(&$$);}
| tABS_FUNC term %prec HIGH {mp_abs(&$2, &$$);}
| tFRAC term %prec HIGH {mp_fractional_component(&$2, &$$);}
| tINT term %prec HIGH {mp_integer_component(&$2, &$$);}
-| tCHS term %prec HIGH {mp_invert_sign(&$2, &$$);}
-
| tSIN term %prec HIGH {mp_sin(&$2, _mp_equation_get_extra(yyscanner)->angle_units, &$$);}
| tCOS term %prec HIGH {mp_cos(&$2, _mp_equation_get_extra(yyscanner)->angle_units, &$$);}
| tTAN term %prec HIGH {mp_tan(&$2, _mp_equation_get_extra(yyscanner)->angle_units, &$$);}
+| tSIN tSUPNUM term %prec HIGH {MPNumber t; mp_sin(&$3, _mp_equation_get_extra(yyscanner)->angle_units, &t); mp_pwr_integer(&t, $2, &$$);}
+| tCOS tSUPNUM term %prec HIGH {MPNumber t; mp_cos(&$3, _mp_equation_get_extra(yyscanner)->angle_units, &t); mp_pwr_integer(&t, $2, &$$);}
+| tTAN tSUPNUM term %prec HIGH {MPNumber t; mp_tan(&$3, _mp_equation_get_extra(yyscanner)->angle_units, &t); mp_pwr_integer(&t, $2, &$$);}
| tASIN term %prec HIGH {mp_asin(&$2, _mp_equation_get_extra(yyscanner)->angle_units, &$$);}
| tACOS term %prec HIGH {mp_acos(&$2, _mp_equation_get_extra(yyscanner)->angle_units, &$$);}
| tATAN term %prec HIGH {mp_atan(&$2, _mp_equation_get_extra(yyscanner)->angle_units, &$$);}
| tSINH term %prec HIGH {mp_sinh(&$2, &$$);}
| tCOSH term %prec HIGH {mp_cosh(&$2, &$$);}
| tTANH term %prec HIGH {mp_tanh(&$2, &$$);}
+| tSINH tSUPNUM term %prec HIGH {MPNumber t; mp_sinh(&$3, &t); mp_pwr_integer(&t, $2, &$$);}
+| tCOSH tSUPNUM term %prec HIGH {MPNumber t; mp_cosh(&$3, &t); mp_pwr_integer(&t, $2, &$$);}
+| tTANH tSUPNUM term %prec HIGH {MPNumber t; mp_tanh(&$3, &t); mp_pwr_integer(&t, $2, &$$);}
| tASINH term %prec HIGH {mp_asinh(&$2, &$$);}
| tACOSH term %prec HIGH {mp_acosh(&$2, &$$);}
| tATANH term %prec HIGH {mp_atanh(&$2, &$$);}
-
| tTRUNC term %prec HIGH {mp_mask(&$2, _mp_equation_get_extra(yyscanner)->wordlen, &$$);}
| t1S term %prec HIGH {
if (!mp_is_natural(&$2)) {
diff --git a/src/mp-trigonometric.c b/src/mp-trigonometric.c
index ddfaaf7..698d60f 100644
--- a/src/mp-trigonometric.c
+++ b/src/mp-trigonometric.c
@@ -657,7 +657,7 @@ mp_atanh(const MPNumber *x, MPNumber *z)
mp_subtract(&MP1, x, &MP3);
mp_divide(&MP2, &MP3, &MP3);
mp_ln(&MP3, &MP3);
- mp_set_from_string("0.5", 10, &MP1);
+ mp_set_from_string("0.5", &MP1);
mp_multiply(&MP1, &MP3, z);
}
}
diff --git a/src/mp.h b/src/mp.h
index d435028..f01b7fa 100644
--- a/src/mp.h
+++ b/src/mp.h
@@ -193,8 +193,8 @@ void mp_set_from_fraction(int numerator, int denominator, MPNumber *z);
/* Sets z to be a uniform random number in the range [0, 1] */
void mp_set_from_random(MPNumber *z);
-/* Sets z from a string representation in 'text' in base 'base' */
-void mp_set_from_string(const char *text, int base, MPNumber *z);
+/* Sets z from a string representation in 'text' */
+void mp_set_from_string(const char *text, MPNumber *z);
/* Returns x as a native single-precision floating point number */
float mp_cast_to_float(const MPNumber *x);
diff --git a/src/register.c b/src/register.c
index 9b2da9f..5ea69a6 100644
--- a/src/register.c
+++ b/src/register.c
@@ -76,14 +76,14 @@ void register_init()
}
if (nline && vline) {
- mp_set_from_string(vline, 10, &value);
+ mp_set_from_string(vline, &value);
register_set_name(i, nline);
register_set_value(i, &value);
g_free(nline);
g_free(vline);
}
else {
- mp_set_from_string(default_registers[i][1], 10, &value);
+ mp_set_from_string(default_registers[i][1], &value);
register_set_name(i, default_registers[i][0]);
register_set_value(i, &value);
}
diff --git a/src/unittest.c b/src/unittest.c
index a3f3f56..1c02e48 100644
--- a/src/unittest.c
+++ b/src/unittest.c
@@ -184,6 +184,8 @@ test_parser()
test("â??4â??2", "0", 0);
test("â??8", "2", 0);
test("â??16", "2", 0);
+ test("â??â??8", "2", 0);
+ test("â??â??â??1024", "2", 0);
test("â??(2+2)", "2", 0);
test("2â??4", "4", 0);
test("2Ã?â??4", "4", 0);
@@ -232,6 +234,7 @@ test_parser()
test("sin 90", "1", 0);
test("sin 180", "0", 0);
test("2 sin 90", "2", 0);
+ test("sin²45", "0.5", 0);
test("cos 0", "1", 0);
test("cos 45 â?? 1÷â??2", "0", 0);
@@ -239,10 +242,13 @@ test_parser()
test("cos 90", "0", 0);
test("cos 180", "â??1", 0);
test("2 cos 0", "2", 0);
+ test("cos²45", "0.5", 0);
test("tan 0", "0", 0);
test("tan 10 â?? sin 10÷cos 10", "0", 0);
test("tan 90", "", -20001);
+ test("tan 10", "0.176326981", 0);
+ test("tan²10", "0.031091204", 0);
test("cos�¹ 0", "90", 0);
test("cos�¹ 1", "0", 0);
@@ -277,12 +283,13 @@ test_parser()
v->ttype = MP_GRADIANS;
test("sin 100", "1", 0);
- v->base = 16;
test("3 And 5", "1", 0);
test("3 Or 5", "7", 0);
test("3 Xor 5", "6", 0);
- test("3 Xnor 5", "FFFFFFF9", 0);
- test("~7A", "FFFFFF85", 0);
+
+ v->base = 16;
+ test("3 Xnor 5", "FFFFFFF9â??â??", 0);
+ test("~7Aâ??â??", "FFFFFF85â??â??", 0);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]