]> gitweb.factorcode.org Git - factor.git/commitdiff
VM: fixed bignum_divide_unsigned_large_denominator so that it wont data_root-protect...
authorBjörn Lindqvist <bjourne@gmail.com>
Tue, 18 Nov 2014 00:55:42 +0000 (01:55 +0100)
committerJohn Benediktsson <mrjbq7@gmail.com>
Tue, 18 Nov 2014 01:27:36 +0000 (17:27 -0800)
vm/bignum.cpp
vm/vm.hpp

index 1e26b7966e5e80e86bf37dfd8cb23df8fa0b52ad..3229d58679875fe85abff706134706936d78f9b9 100644 (file)
@@ -488,10 +488,9 @@ enum bignum_comparison factor_vm::bignum_compare_unsigned(bignum* x,
 
 /* Addition */
 
-/* Allocates memory, fixed! */
+/* Allocates memory */
 bignum* factor_vm::bignum_add_unsigned(bignum* x_, bignum* y_, int negative_p) {
 
-
   data_root<bignum> x(x_, this);
   data_root<bignum> y(y_, this);
   if ((BIGNUM_LENGTH(y)) > (BIGNUM_LENGTH(x))) {
@@ -620,7 +619,7 @@ bignum* factor_vm::bignum_multiply_unsigned(bignum* x_, bignum* y_,
   data_root<bignum> x(x_, this);
   data_root<bignum> y(y_, this);
 
-  if (BIGNUM_LENGTH(x) > BIGNUM_LENGTH(y)) {
+  if (BIGNUM_LENGTH(y) > BIGNUM_LENGTH(x)) {
     swap(x, y);
   }
   {
@@ -743,68 +742,76 @@ void factor_vm::bignum_destructive_scale_up(bignum* bn,
 
 /* Allocates memory */
 void factor_vm::bignum_divide_unsigned_large_denominator(
-    bignum* numerator_, bignum* denominator_, bignum** quotient,
-    bignum** remainder, int q_negative_p, int r_negative_p) {
+    bignum* numerator_, bignum* denominator_,
+    bignum** quotient, bignum** remainder,
+    int q_negative_p, int r_negative_p) {
 
   data_root<bignum> numerator(numerator_, this);
   data_root<bignum> denominator(denominator_, this);
 
-  bignum_length_type length_n = ((BIGNUM_LENGTH(numerator)) + 1);
-  bignum_length_type length_d = (BIGNUM_LENGTH(denominator));
-
-  bignum *q_ = NULL;
-  if (quotient != ((bignum**)0)) {
-    q_ = allot_bignum(length_n - length_d, q_negative_p);
-  } else {
-    q_ = BIGNUM_OUT_OF_BAND;
-  }
-
-  data_root<bignum> q(q_, this);
+  bignum_length_type length_n = BIGNUM_LENGTH(numerator) + 1;
+  bignum_length_type length_d = BIGNUM_LENGTH(denominator);
 
   data_root<bignum> u(allot_bignum(length_n, r_negative_p), this);
 
   int shift = 0;
   BIGNUM_ASSERT(length_d > 1);
   {
-    bignum_digit_type v1 = (BIGNUM_REF((denominator), (length_d - 1)));
+    bignum_digit_type v1 = BIGNUM_REF(denominator.untagged(), length_d - 1);
     while (v1 < (BIGNUM_RADIX / 2)) {
       v1 <<= 1;
       shift += 1;
     }
   }
-  if (shift == 0) {
-    bignum_destructive_copy(numerator.untagged(), u.untagged());
-    (BIGNUM_REF(u, (length_n - 1))) = 0;
-    bignum_divide_unsigned_normalized(u.untagged(),
-                                      denominator.untagged(),
-                                      q.untagged());
-  } else {
-    bignum* v = (allot_bignum(length_d, 0));
-
-    bignum_destructive_normalization(numerator.untagged(),
-                                     u.untagged(),
-                                     shift);
-    bignum_destructive_normalization(denominator.untagged(),
-                                     v,
-                                     shift);
-    bignum_divide_unsigned_normalized(u.untagged(), v, q.untagged());
-    if (remainder != ((bignum**)0))
-      bignum_destructive_unnormalization(u.untagged(), shift);
-  }
 
-  if (q.untagged()) {
-    q = bignum_trim(q.untagged());
-  }
+  if (quotient != NULL) {
+    bignum *q_ = allot_bignum(length_n - length_d, q_negative_p);
+    data_root<bignum> q(q_, this);
 
-  u = bignum_trim(u.untagged());
+    if (shift == 0) {
+      bignum_destructive_copy(numerator.untagged(), u.untagged());
+      (BIGNUM_REF(u.untagged(), (length_n - 1))) = 0;
+      bignum_divide_unsigned_normalized(u.untagged(),
+                                        denominator.untagged(),
+                                        q.untagged());
+    } else {
+      bignum* v = allot_bignum(length_d, 0);
+      bignum_destructive_normalization(numerator.untagged(),
+                                       u.untagged(),
+                                       shift);
+      bignum_destructive_normalization(denominator.untagged(), v, shift);
+      bignum_divide_unsigned_normalized(u.untagged(), v, q.untagged());
+      if (remainder != NULL)
+        bignum_destructive_unnormalization(u.untagged(), shift);
+    }
 
-  if (quotient != ((bignum**)0))
-    (*quotient) = q.untagged();
+    q = bignum_trim(q.untagged());
+    *quotient = q.untagged();
+  } else {
 
-  if (remainder != ((bignum**)0))
-    (*remainder) = u.untagged();
+    if (shift == 0) {
+        bignum_destructive_copy(numerator.untagged(), u.untagged());
+        (BIGNUM_REF(u.untagged(), (length_n - 1))) = 0;
+        bignum_divide_unsigned_normalized(u.untagged(),
+                                          denominator.untagged(),
+                                          NULL);
+      } else {
+        bignum* v = allot_bignum(length_d, 0);
+        bignum_destructive_normalization(numerator.untagged(),
+                                         u.untagged(),
+                                         shift);
+        bignum_destructive_normalization(denominator.untagged(),
+                                         v,
+                                         shift);
+        bignum_divide_unsigned_normalized(u.untagged(), v, NULL);
+        if (remainder != NULL)
+          bignum_destructive_unnormalization(u.untagged(), shift);
+      }
+  }
 
-  return;
+  u = bignum_trim(u.untagged());
+  if (remainder != NULL)
+    *remainder = u.untagged();
 }
 
 void factor_vm::bignum_divide_unsigned_normalized(bignum* u, bignum* v,
index 2643cc5eafe19eda633705f058a1c130a6ee399b..87a8c878e245cde4e9ac5529f37a80779d0f3626 100644 (file)
--- a/vm/vm.hpp
+++ b/vm/vm.hpp
@@ -254,7 +254,7 @@ struct factor_vm {
   void bignum_destructive_add(bignum* bn, bignum_digit_type n);
   void bignum_destructive_scale_up(bignum* bn, bignum_digit_type factor);
   void bignum_divide_unsigned_large_denominator(
-      bignum* numerator, bignum* denominator, bignum** quotient,
+      bignum* numerator_, bignum* denominator_, bignum** quotient,
       bignum** remainder, int q_negative_p, int r_negative_p);
   void bignum_divide_unsigned_normalized(bignum* u, bignum* v, bignum* q);
   bignum_digit_type bignum_divide_subtract(bignum_digit_type* v_start,