[gcalctool] Add a prime factorization function (Robin Sonefors, Bug #563217)



commit a6ba6319f99b901ac7c493f2302128d63020dde3
Author: Robert Ancell <robert ancell gmail com>
Date:   Mon Sep 28 12:19:17 2009 +1000

    Add a prime factorization function (Robin Sonefors, Bug #563217)

 ChangeLog         |    1 +
 data/gcalctool.ui |   25 +++++++++++++++-----
 src/display.c     |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/display.h     |    1 +
 src/gtk.c         |   12 ++++++++++
 5 files changed, 97 insertions(+), 6 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 0293bc3..98040a8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -10,6 +10,7 @@ gcalctool change history.
 2009-09-28 Robert Ancell <robert ancell gmail com>
 
     * Revamped the user interface
+    * Add a prime factorization function (Robin Sonefors, Bug #563217)
 
 2009-09-22 Robert Ancell <robert ancell gmail com>
 
diff --git a/data/gcalctool.ui b/data/gcalctool.ui
index 4ed75e7..70406df 100644
--- a/data/gcalctool.ui
+++ b/data/gcalctool.ui
@@ -96,7 +96,6 @@
                         <property name="label" translatable="yes" comments="View|Basic menu item">_Basic</property>
                         <property name="use_underline">True</property>
                         <property name="active">True</property>
-                        <accelerator key="B" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                         <signal name="activate" handler="mode_radio_cb"/>
                       </object>
                     </child>
@@ -107,7 +106,6 @@
                         <property name="label" translatable="yes" comments="View|Advanced menu item">_Advanced</property>
                         <property name="use_underline">True</property>
                         <property name="group">view_basic_menu</property>
-                        <accelerator key="A" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                         <signal name="activate" handler="mode_radio_cb"/>
                       </object>
                     </child>
@@ -118,7 +116,6 @@
                         <property name="label" translatable="yes" comments="View|Financial menu item">_Financial</property>
                         <property name="use_underline">True</property>
                         <property name="group">view_basic_menu</property>
-                        <accelerator key="F" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                         <signal name="activate" handler="mode_radio_cb"/>
                       </object>
                     </child>
@@ -129,7 +126,6 @@
                         <property name="label" translatable="yes" comments="View|Scientific menu item">_Scientific</property>
                         <property name="use_underline">True</property>
                         <property name="group">view_basic_menu</property>
-                        <accelerator key="S" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                         <signal name="activate" handler="mode_radio_cb"/>
                       </object>
                     </child>
@@ -140,7 +136,6 @@
                         <property name="label" translatable="yes" comments="View|Programming menu item">_Programming</property>
                         <property name="use_underline">True</property>
                         <property name="group">view_basic_menu</property>
-                        <accelerator key="P" signal="activate" modifiers="GDK_CONTROL_MASK"/>
                         <signal name="activate" handler="mode_radio_cb"/>
                       </object>
                     </child>
@@ -3006,7 +3001,25 @@
                   </packing>
                 </child>
                 <child>
-                  <placeholder/>
+                  <object class="GtkButton" id="calc_factor_button">
+                    <property name="label">fact</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="tooltip_text" translatable="yes" comments="Tooltip for the fractional portion button">Factorize into prime numbers (Ctrl+F)</property>
+                    <property name="border_width">3</property>
+                    <property name="use_underline">True</property>
+                    <property name="focus_on_click">False</property>
+                    <signal name="clicked" handler="factorize_cb"/>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">3</property>
+                    <property name="bottom_attach">4</property>
+                    <property name="x_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                    <property name="y_options">GTK_EXPAND | GTK_SHRINK | GTK_FILL</property>
+                  </packing>
                 </child>
               </object>
               <packing>
diff --git a/src/display.c b/src/display.c
index 1b7c714..6ded7c1 100644
--- a/src/display.c
+++ b/src/display.c
@@ -854,6 +854,66 @@ do_shift(GCDisplay *display, int count)
 }
 
 
+void
+do_factorize()
+{
+    MPNumber value, divisor, tmp, root;
+
+    mp_set_from_integer(2, &divisor);
+    if (!display_is_usable_number(&v->display, &value)) {
+        /* Translators: Error displayed when trying to factorize a non-integer value */
+        ui_set_statusbar(_("Need an integer to factorize"));
+        return;
+    }
+
+    display_clear(&v->display);
+
+    if (mp_is_negative(&value)) {
+        display_insert(&v->display, -1, -1, "â??");
+        mp_invert_sign(&value, &value);
+    }
+    
+    mp_set_from_integer(1, &tmp);
+    if (mp_is_equal(&value, &tmp)) {
+        display_insert(&v->display, -1, -1, v->digits[1]);
+        return;
+    }
+
+    while (TRUE) {
+        mp_divide(&value, &divisor, &tmp);
+        if (mp_is_integer(&tmp)) {
+            value = tmp;
+            display_insert_number(&v->display, -1, -1, &divisor);
+            display_insert(&v->display, -1, -1, "Ã?");
+        } else {
+            break;
+        }
+    }
+
+    mp_set_from_integer(3, &divisor);
+    mp_sqrt(&value, &root);
+    while (mp_is_less_equal(&divisor, &root)) {
+        mp_divide(&value, &divisor, &tmp);
+        if (mp_is_integer(&tmp)) {
+            value = tmp;
+            mp_sqrt(&value, &root);
+            display_insert_number(&v->display, -1, -1, &divisor);
+            display_insert(&v->display, -1, -1, "Ã?");
+        } else {
+            mp_add_integer(&divisor, 2, &tmp);
+            divisor = tmp;
+        }
+    }
+
+    mp_set_from_integer(1, &tmp);
+    if (mp_is_greater_than(&value, &tmp)) {
+        display_insert_number(&v->display, -1, -1, &value);
+    } else {
+        display_backspace(&v->display, -1, -1);
+    }
+}
+
+
 static void
 do_sto(GCDisplay *display, int index)
 {
@@ -904,6 +964,10 @@ display_do_function(GCDisplay *display, int function, int arg, int cursor_start,
             do_shift(display, arg);
             break;
 
+        case FN_FACTORIZE:
+            do_factorize(display, arg);
+            break;
+
         case FN_PASTE:
             do_paste(display, cursor_start, cursor_end, (const char *)arg); // FIXME: Probably not 64 bit safe
             return;
diff --git a/src/display.h b/src/display.h
index 57a95a6..c1817fe 100644
--- a/src/display.h
+++ b/src/display.h
@@ -68,6 +68,7 @@ enum
     FN_DELETE,        
     FN_TOGGLE_BIT,
     FN_SHIFT,
+    FN_FACTORIZE,
     FN_STORE,
     FN_RECALL,
     FN_UNDO,
diff --git a/src/gtk.c b/src/gtk.c
index 7bfe074..2607d40 100644
--- a/src/gtk.c
+++ b/src/gtk.c
@@ -904,6 +904,15 @@ popup_cb(GtkWidget *widget, GdkEventButton *event)
     }
 }
 
+
+G_MODULE_EXPORT
+void
+factorize_cb(GtkWidget *widget, GdkEventButton *event)
+{
+    do_button(FN_FACTORIZE, 0);
+}
+
+
 G_MODULE_EXPORT
 void
 digit_cb(GtkWidget *widget, GdkEventButton *event)
@@ -995,6 +1004,9 @@ main_window_key_press_cb(GtkWidget *widget, GdkEventKey *event)
         case GDK_e:
             do_text("Ã?10^");
             return TRUE;
+        case GDK_f:
+            do_button(FN_FACTORIZE, 0);
+            return TRUE;
         case GDK_r:
             do_text("â??");
             return TRUE;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]