[gcalctool] Move factorization code to mp.c



commit 1d44242e1d3313a7e948c4ea2bdd34c4c9c31811
Author: Robin Sonefors <ozamosi flukkost nu>
Date:   Mon Sep 28 18:14:20 2009 +0200

    Move factorization code to mp.c

 ChangeLog     |    4 +++
 src/display.c |   49 ++++++------------------------------------
 src/mp.c      |   66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/mp.h      |    5 ++++
 4 files changed, 82 insertions(+), 42 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 31f2c73..4e79603 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,10 @@
 gcalctool change history.
 =========================
 
+2009-09-28 Robin Sonefors <ozamosi flukkost nu>
+    * Make numbers written with a keyboard respect sub/superscript toggles
+    * Move factorization code to mp.c
+
 2009-09-28 Robert Ancell <robert ancell gmail com>
 
     * Revamped the user interface (Robert Ancell, Bug #336609, Bug #587897,
diff --git a/src/display.c b/src/display.c
index d886c5e..4d223f6 100644
--- a/src/display.c
+++ b/src/display.c
@@ -854,59 +854,24 @@ do_shift(GCDisplay *display, int count)
 void
 do_factorize()
 {
-    MPNumber value, divisor, tmp, root;
+    MPNumber value;
 
-    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;
-    }
+    GList *factors = mp_factorize(&value);
 
-    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;
-        }
-    }
+    display_insert_number(&v->display, -1, -1, factors->data);
+    factors = factors->next;
 
-    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);
+    for (; factors != NULL; factors = factors->next) {
             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);
+            display_insert_number(&v->display, -1, -1, factors->data);
+            g_slice_free(MPNumber, factors->data);
     }
 }
 
diff --git a/src/mp.c b/src/mp.c
index e1c4041..6a335a9 100644
--- a/src/mp.c
+++ b/src/mp.c
@@ -1839,3 +1839,69 @@ mp_xpowy_integer(const MPNumber *x, int n, MPNumber *z)
     for (i = 0; i < n; i++)
         mp_multiply(z, &t, z);
 }
+
+GList*
+mp_factorize(const MPNumber *orig_value)
+{
+    GList *list = NULL;
+    MPNumber *factor = g_slice_alloc0(sizeof(MPNumber));
+    MPNumber value, tmp, divisor, root;
+
+    mp_abs(orig_value, &value);
+
+    if (mp_is_zero(&value)) {
+        mp_set_from_mp(&value, factor);
+        list = g_list_append(list, factor);
+        return list;
+    }
+
+    mp_set_from_integer(1, &tmp);
+    if (mp_is_equal(&value, &tmp)) {
+        mp_set_from_mp(orig_value, factor);
+        list = g_list_append(list, factor);
+        return list;
+    }
+
+    mp_set_from_integer(2, &divisor);
+    while (TRUE) {
+        mp_divide(&value, &divisor, &tmp);
+        if (mp_is_integer(&tmp)) {
+            value = tmp;
+            mp_set_from_mp(&divisor, factor);
+            list = g_list_append(list, factor);
+            factor = g_slice_alloc0(sizeof(MPNumber));
+        } 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);
+            mp_set_from_mp(&divisor, factor);
+            list = g_list_append(list, factor);
+            factor = g_slice_alloc0(sizeof(MPNumber));
+        } else {
+            mp_add_integer(&divisor, 2, &tmp);
+            divisor = tmp;
+        }
+    }
+
+    mp_set_from_integer(1, &tmp);
+    if (mp_is_greater_than(&value, &tmp)) {
+        mp_set_from_mp(&value, factor);
+        list = g_list_append(list, factor);
+    } else {
+        g_slice_free(MPNumber, factor);
+    }
+
+    if (mp_is_negative(orig_value)) {
+        mp_invert_sign(list->data, list->data);
+    }
+
+    return list;
+}
diff --git a/src/mp.h b/src/mp.h
index 14a270b..f3e9d29 100644
--- a/src/mp.h
+++ b/src/mp.h
@@ -39,6 +39,8 @@
 #ifndef MP_H
 #define MP_H
 
+#include <glib.h>
+
 /* Size of the multiple precision values */
 #define MP_SIZE 1000
 
@@ -184,6 +186,9 @@ void   mp_xpowy_integer(const MPNumber *x, int y, MPNumber *z);
 /* Sets z = e^x */
 void   mp_epowy(const MPNumber *x, MPNumber *z);
 
+/* Returns a list of all prime factors in value as MPNumbers */
+GList* mp_factorize(const MPNumber *value);
+
 /* Sets z = x */
 void   mp_set_from_mp(const MPNumber *x, MPNumber *z);
 



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