Explorar o código

Adding string constructor for things that are completely out of bounds.
Changing to_string to use sprintf.

Samuel Jaffe %!s(int64=8) %!d(string=hai) anos
pai
achega
fc5c2fc543
Modificáronse 1 ficheiros con 35 adicións e 8 borrados
  1. 35 8
      src/biginteger.cpp

+ 35 - 8
src/biginteger.cpp

@@ -7,6 +7,11 @@
 
 #include "biginteger.h"
 
+#include <cmath>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
 using namespace math;
 
 namespace detail {
@@ -37,6 +42,29 @@ biginteger(value < 0, static_cast<uint64_t>(value < 0 ? -value : value)) {}
 biginteger::biginteger(uint64_t value)
 : biginteger(false, value) {}
 
+biginteger::biginteger(char const * number)
+: is_negative(number[0] == '-') {
+  // 999,999,996,000,000,005,999,999,996,000,000,001
+  if (is_negative) ++number;
+  auto len = strlen(number);
+  auto elems = len/SEG_DIGITS;
+  data.resize(elems);
+  {
+    auto small = len-(elems*SEG_DIGITS);
+    if (small > 0) {
+      char seg[SEG_DIGITS+1] = "";
+      strncpy(seg, number, small);
+      data.push_back(atoi(seg));
+      number += small;
+    }
+  }
+  for (data_type::size_type idx = elems; idx > 0; --idx, number += SEG_DIGITS) {
+    char seg[SEG_DIGITS+1] = "";
+    strncpy(seg, number, SEG_DIGITS);
+    data[idx-1] = atoi(seg);
+  }
+}
+
 biginteger::biginteger(bool neg, uint64_t value) :
 is_negative(neg) {
   uint64_t next{0};
@@ -207,15 +235,14 @@ bool math::operator==(biginteger const & rhs, biginteger const & lhs) {
 
 biginteger const biginteger::ZERO{0}, biginteger::ONE{1}, biginteger::NEGATIVE_ONE{-1};
 
-#include <iomanip>
-#include <sstream>
 
 std::string biginteger::to_string() const {
-  std::stringstream ss;
-  if (is_negative) ss << '-';
-  ss << data[data.size()-1];
-  for (data_type::size_type i = data.size()-1; i > 0; --i) {
-    ss << std::setw(SEG_DIGITS) << std::setfill('0') << data[i-1];
+  std::vector<char> output(biginteger::SEG_DIGITS * data.size() + 1, '\0');
+  std::ptrdiff_t idx = 0;
+  if (is_negative) { output[0] = '-'; ++idx; }
+  idx += sprintf(output.data() + idx, "%d", data[data.size()-1]);
+  for (size_t i = data.size()-1; i > 0; --i, idx+=SEG_DIGITS) {
+    sprintf(output.data() + idx, "%0.*d", SEG_DIGITS, data[i-1]);
   }
-  return ss.str();
+  return output.data();
 }