浏览代码

Use size_t explicitly instead of data_type::size_type.
Make add and subtract_nounderflow a little cleaner.

Samuel Jaffe 8 年之前
父节点
当前提交
0fd7aabb24
共有 1 个文件被更改,包括 37 次插入34 次删除
  1. 37 34
      src/biginteger.cpp

+ 37 - 34
src/biginteger.cpp

@@ -13,8 +13,8 @@ namespace detail {
   using data_type = biginteger::data_type;
   // 1 => GREATER, 0 => EQUAL, -1 => LESS
   int compare(data_type const & rhs, data_type const & lhs);
-  data_type add(data_type const & rhs, data_type const & lhs);
-  data_type subtract_nounderflow(data_type const & rhs, data_type const & lhs);
+  data_type add(data_type rhs, data_type const & lhs);
+  data_type subtract_nounderflow(data_type rhs, data_type const & lhs);
   data_type multiply(data_type const & rhs, data_type const & lhs);
 }
 
@@ -121,62 +121,65 @@ namespace detail {
   
   int compare(data_type const & rhs, data_type const & lhs) {
     IMPL_COMPARE(.size());
-    for (data_type::size_type i = rhs.size(); i > 0; --i) {
+    for (size_t i = rhs.size(); i > 0; --i) {
       IMPL_COMPARE([i-1]);
     }
     return 0;
   }
 #undef IMPL_COMPARE
   
-  data_type add(data_type const & rhs, data_type const & lhs) {
-    data_type::size_type const rbnd = rhs.size(), lbnd = lhs.size();
-    data_type::size_type const ubnd = std::max(rbnd, lbnd);
-    data_type rval(ubnd+1);
+  void add_into(data_type & rhs, data_type const & lhs) {
+    rhs.resize(std::max(rhs.size(), lhs.size())+1);
+    auto const lbnd = lhs.size(), ubnd = rhs.size() - 1;
     // Add
-    for (data_type::size_type i = 0; i < rbnd; ++i) {
-      rval[i] += rhs[i];
-    }
-    for (data_type::size_type i = 0; i < lbnd; ++i) {
-      rval[i] += lhs[i];
+    for (size_t i = 0; i < lbnd; ++i) {
+      rhs[i] += lhs[i];
     }
     // Carry
-    for (data_type::size_type i = 0; i < ubnd; ++i) {
-      if (rval[i] > biginteger::MAX_SEG) {
-        rval[i] -= biginteger::OVER_SEG;
-        rval[i+1] += 1;
+    for (size_t i = 0; i < ubnd; ++i) {
+      if (rhs[i] > biginteger::MAX_SEG) {
+        rhs[i] -= biginteger::OVER_SEG;
+        rhs[i+1] += 1;
       }
     }
-    if (rval[ubnd] == 0) { rval.pop_back(); }
-    return rval;
+    if (rhs[ubnd] == 0) { rhs.pop_back(); }
+  }
+  
+  data_type add(data_type rhs, data_type const & lhs) {
+    add_into(rhs, lhs);
+    return rhs;
   }
   
-  data_type subtract_nounderflow(data_type const & rhs, data_type const & lhs) {
-    data_type::size_type const rbnd = rhs.size(), lbnd = lhs.size();
-    data_type rval{rhs};
+  void subtract_from(data_type & rhs, data_type const & lhs) {
+    size_t const rbnd = rhs.size(), lbnd = lhs.size();
     // Subtract
-    for (data_type::size_type i = 0; i < lbnd; ++i) {
-      rval[i] -= lhs[i];
+    for (size_t i = 0; i < lbnd; ++i) {
+      rhs[i] -= lhs[i];
     }
     // Borrow
-    for (data_type::size_type i = 0; i < rbnd; ++i) {
-      if (rval[i] < 0) {
-        rval[i] += biginteger::OVER_SEG;
-        rval[i+1] -= 1;
+    for (size_t i = 0; i < rbnd; ++i) {
+      if (rhs[i] < 0) {
+        rhs[i] += biginteger::OVER_SEG;
+        rhs[i+1] -= 1;
       }
     }
-    if (rval[rbnd-1] == 0 && rbnd > 1) { rval.pop_back(); }
-    return rval;
+    if (rhs[rbnd-1] == 0 && rbnd > 1) { rhs.pop_back(); }
+  }
+  
+  data_type subtract_nounderflow(data_type rhs, data_type const & lhs) {
+    subtract_from(rhs, lhs);
+    return rhs;
   }
   
   data_type multiply(data_type const & rhs, data_type const & lhs) {
     if (compare(rhs, {1}) == 0) { return lhs; }
     else if (compare(lhs, {1}) == 0) { return rhs; }
-    data_type::size_type const rbnd = rhs.size(), lbnd = lhs.size();
-    data_type::size_type const ubnd = rbnd + lbnd;
+    size_t const rbnd = rhs.size(), lbnd = lhs.size();
+    size_t const ubnd = rbnd + lbnd;
     data_type rval(ubnd + 1);
     // Multiply
-    for (data_type::size_type i = 0; i < rbnd; ++i) {
-      for (data_type::size_type j = 0; j < lbnd; ++j) {
+    for (size_t i = 0; i < rbnd; ++i) {
+      for (size_t j = 0; j < lbnd; ++j) {
         // Max input              999,999,999
         // Max output 999,999,998,000,000,001
         int64_t product = static_cast<int64_t>(rhs[i]) * static_cast<int64_t>(lhs[j]);
@@ -186,7 +189,7 @@ namespace detail {
       }
     }
     // Carry
-    for (data_type::size_type i = 0; i < ubnd; ++i) {
+    for (size_t i = 0; i < ubnd; ++i) {
       if (rval[i] > biginteger::MAX_SEG) {
         int32_t overflow = rval[i] / biginteger::OVER_SEG;
         rval[i] -= (overflow * biginteger::OVER_SEG);