[gcalctool] Move factorization code to mp.c
- From: Robin Sonefors <rsonefors src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gcalctool] Move factorization code to mp.c
- Date: Mon, 28 Sep 2009 16:18:37 +0000 (UTC)
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]