port code from +17 branch, fix operator *=
[novacoin.git] / src / uint256.h
index 3bb0167..4d60835 100644 (file)
@@ -5,15 +5,11 @@
 #ifndef BITCOIN_UINT256_H
 #define BITCOIN_UINT256_H
 
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
+#include <limits>
 #include <string>
 #include <vector>
-#include <stdint.h>
-
-inline int Testuint256AdHoc(std::vector<std::string> vArg);
-
+#include <iomanip>
+#include <sstream>
 
 
 /** Base class without constructors for uint256 and uint160.
@@ -27,6 +23,14 @@ protected:
     uint32_t pn[WIDTH];
 public:
 
+    const base_uint max()
+    {
+        base_uint ret;
+        for (int i = 0; i < WIDTH; i++)
+            ret.pn[i] = std::numeric_limits<uint32_t>::max();
+        return ret;
+    }
+
     bool operator!() const
     {
         for (int i = 0; i < WIDTH; i++)
@@ -291,10 +295,11 @@ public:
 
     std::string GetHex() const
     {
-        char psz[sizeof(pn)*2 + 1];
-        for (unsigned int i = 0; i < sizeof(pn); i++)
-            sprintf(psz + i*2, "%02x", ((unsigned char*)pn)[sizeof(pn) - i - 1]);
-        return std::string(psz, psz + sizeof(pn)*2);
+        std::stringstream ss;
+        size_t pn_size = sizeof(pn) / sizeof(pn[0]);
+        for (size_t i = 1; i <= pn_size; i++)
+             ss << std::setfill('0') << std::setw(8) << std::setbase(16) << pn[pn_size-i];
+        return ss.str();
     }
 
     void SetHex(const char* psz)
@@ -339,12 +344,12 @@ public:
         return (GetHex());
     }
 
-    unsigned char* begin()
+    unsigned char* begin() const
     {
         return (unsigned char*)&pn[0];
     }
 
-    unsigned char* end()
+    unsigned char* end() const
     {
         return (unsigned char*)&pn[WIDTH];
     }
@@ -354,7 +359,7 @@ public:
         return std::vector<unsigned char>(begin(), end());
     }
 
-    size_t size()
+    size_t size() const
     {
         return sizeof(pn);
     }
@@ -374,6 +379,20 @@ public:
         return sizeof(pn);
     }
 
+    unsigned int bits() const
+    {
+        for (int pos = WIDTH - 1; pos >= 0; pos--) {
+            if (pn[pos]) {
+                for (int bits = 31; bits > 0; bits--) {
+                    if (pn[pos] & 1 << bits)
+                        return 32 * pos + bits + 1;
+                }
+                return 32 * pos + 1;
+            }
+        }
+        return 0;
+    }
+
     template<typename Stream>
     void Serialize(Stream& s, int nType, int nVersion) const
     {
@@ -388,7 +407,6 @@ public:
 
     friend class uint160;
     friend class uint256;
-    friend inline int Testuint256AdHoc(std::vector<std::string> vArg);
 };
 
 typedef base_uint<160> base_uint160;
@@ -412,54 +430,13 @@ class uint160 : public base_uint160
 public:
     typedef base_uint160 basetype;
 
-    uint160()
-    {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = 0;
-    }
-
-    uint160(const basetype& b)
-    {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = b.pn[i];
-    }
-
-    uint160& operator=(const basetype& b)
-    {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = b.pn[i];
-        return *this;
-    }
-
-    uint160(uint64_t b)
-    {
-        pn[0] = (uint32_t)b;
-        pn[1] = (uint32_t)(b >> 32);
-        for (int i = 2; i < WIDTH; i++)
-            pn[i] = 0;
-    }
-
-    uint160& operator=(uint64_t b)
-    {
-        pn[0] = (uint32_t)b;
-        pn[1] = (uint32_t)(b >> 32);
-        for (int i = 2; i < WIDTH; i++)
-            pn[i] = 0;
-        return *this;
-    }
-
-    explicit uint160(const std::string& str)
-    {
-        SetHex(str);
-    }
-
-    explicit uint160(const std::vector<unsigned char>& vch)
-    {
-        if (vch.size() == sizeof(pn))
-            memcpy(pn, &vch[0], sizeof(pn));
-        else
-            *this = 0;
-    }
+    uint160();
+    uint160(const basetype& b);
+    uint160& operator=(const basetype& b);
+    uint160(uint64_t b);
+    uint160& operator=(uint64_t b);
+    explicit uint160(const std::string& str);
+    explicit uint160(const std::vector<unsigned char>& vch);
 };
 
 inline bool operator==(const uint160& a, uint64_t b)                           { return (base_uint160)a == b; }
@@ -521,60 +498,37 @@ inline const uint160 operator-(const uint160& a, const uint160& b)      { return
 // uint256
 //
 
+
+/** Errors thrown by the uint256 class */
+class uint256_error : public std::exception
+{
+public:
+        explicit uint256_error(const std::string& error_message)  : what_(error_message) {}
+
+        virtual const char* what() const throw () { return what_.c_str(); }
+        virtual ~uint256_error() throw () {}
+private:
+        std::string what_;
+};
+
 /** 256-bit unsigned integer */
 class uint256 : public base_uint256
 {
 public:
     typedef base_uint256 basetype;
 
-    uint256()
-    {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = 0;
-    }
-
-    uint256(const basetype& b)
-    {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = b.pn[i];
-    }
-
-    uint256& operator=(const basetype& b)
-    {
-        for (int i = 0; i < WIDTH; i++)
-            pn[i] = b.pn[i];
-        return *this;
-    }
-
-    uint256(uint64_t b)
-    {
-        pn[0] = (uint32_t)b;
-        pn[1] = (uint32_t)(b >> 32);
-        for (int i = 2; i < WIDTH; i++)
-            pn[i] = 0;
-    }
-
-    uint256& operator=(uint64_t b)
-    {
-        pn[0] = (uint32_t)b;
-        pn[1] = (uint32_t)(b >> 32);
-        for (int i = 2; i < WIDTH; i++)
-            pn[i] = 0;
-        return *this;
-    }
-
-    explicit uint256(const std::string& str)
-    {
-        SetHex(str);
-    }
-
-    explicit uint256(const std::vector<unsigned char>& vch)
-    {
-        if (vch.size() == sizeof(pn))
-            memcpy(pn, &vch[0], sizeof(pn));
-        else
-            *this = 0;
-    }
+    uint256();
+    uint256(const basetype& b);
+    uint256& operator=(const basetype& b);
+    uint256(uint64_t b);
+    uint256& operator=(uint64_t b);
+    uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL);
+    uint32_t GetCompact(bool fNegative = false) const;
+    uint256& operator*=(uint32_t b32);
+    uint256& operator*=(const uint256& b);
+    uint256& operator/=(const uint256& b);
+    explicit uint256(const std::string& str);
+    explicit uint256(const std::vector<unsigned char>& vch);
 };
 
 inline bool operator==(const uint256& a, uint64_t b)                           { return (base_uint256)a == b; }
@@ -588,6 +542,8 @@ inline const uint256 operator^(const base_uint256& a, const base_uint256& b) { r
 inline const uint256 operator&(const base_uint256& a, const base_uint256& b) { return uint256(a) &= b; }
 inline const uint256 operator|(const base_uint256& a, const base_uint256& b) { return uint256(a) |= b; }
 inline const uint256 operator+(const base_uint256& a, const base_uint256& b) { return uint256(a) += b; }
+inline const uint256 operator*(const base_uint256& a, const base_uint256& b) { return uint256(a) *= b; }
+inline const uint256 operator/(const base_uint256& a, const base_uint256& b) { return uint256(a) /= b; }
 inline const uint256 operator-(const base_uint256& a, const base_uint256& b) { return uint256(a) -= b; }
 
 inline bool operator<(const base_uint256& a, const uint256& b)          { return (base_uint256)a <  (base_uint256)b; }
@@ -600,6 +556,8 @@ inline const uint256 operator^(const base_uint256& a, const uint256& b) { return
 inline const uint256 operator&(const base_uint256& a, const uint256& b) { return (base_uint256)a &  (base_uint256)b; }
 inline const uint256 operator|(const base_uint256& a, const uint256& b) { return (base_uint256)a |  (base_uint256)b; }
 inline const uint256 operator+(const base_uint256& a, const uint256& b) { return (base_uint256)a +  (base_uint256)b; }
+inline const uint256 operator*(const base_uint256& a, const uint256& b) { return (base_uint256)a *  (base_uint256)b; }
+inline const uint256 operator/(const base_uint256& a, const uint256& b) { return (base_uint256)a /  (base_uint256)b; }
 inline const uint256 operator-(const base_uint256& a, const uint256& b) { return (base_uint256)a -  (base_uint256)b; }
 
 inline bool operator<(const uint256& a, const base_uint256& b)          { return (base_uint256)a <  (base_uint256)b; }
@@ -626,4 +584,6 @@ inline const uint256 operator|(const uint256& a, const uint256& b)      { return
 inline const uint256 operator+(const uint256& a, const uint256& b)      { return (base_uint256)a +  (base_uint256)b; }
 inline const uint256 operator-(const uint256& a, const uint256& b)      { return (base_uint256)a -  (base_uint256)b; }
 
+uint256 GetRandHash();
+
 #endif