Merge pull request #346 from svost/c++11
[novacoin.git] / src / uint256.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #include <limits>
7 #include <stdio.h>
8 #include <string.h>
9 #include <cassert>
10 #include  <stdexcept>
11
12 #include "uint256.h"
13
14 using namespace std;
15
16 //////////////////////////////////////////////////////////////////////////////
17 //
18 // uint160
19 //
20
21 uint160::uint160()
22 {
23     for (int i = 0; i < WIDTH; i++)
24         pn[i] = 0;
25 }
26
27 uint160::uint160(const basetype& b)
28 {
29     for (int i = 0; i < WIDTH; i++)
30         pn[i] = b.pn[i];
31 }
32
33 uint160& uint160::operator=(const basetype& b)
34 {
35     for (int i = 0; i < WIDTH; i++)
36         pn[i] = b.pn[i];
37     return *this;
38 }
39
40 uint160::uint160(uint64_t b)
41 {
42     pn[0] = (uint32_t)b;
43     pn[1] = (uint32_t)(b >> 32);
44     for (int i = 2; i < WIDTH; i++)
45         pn[i] = 0;
46 }
47
48 uint160& uint160::operator=(uint64_t b)
49 {
50     pn[0] = (uint32_t)b;
51     pn[1] = (uint32_t)(b >> 32);
52     for (int i = 2; i < WIDTH; i++)
53         pn[i] = 0;
54     return *this;
55 }
56
57 uint160::uint160(const std::string& str)
58 {
59     SetHex(str);
60 }
61
62 uint160::uint160(const std::vector<unsigned char>& vch)
63 {
64     if (vch.size() == sizeof(pn))
65         memcpy(pn, &vch[0], sizeof(pn));
66     else
67         *this = 0;
68 }
69
70 //////////////////////////////////////////////////////////////////////////////
71 //
72 // uint256
73 //
74
75 uint256::uint256()
76 {
77     for (int i = 0; i < WIDTH; i++)
78         pn[i] = 0;
79 }
80
81 uint256::uint256(const basetype& b)
82 {
83     for (int i = 0; i < WIDTH; i++)
84         pn[i] = b.pn[i];
85 }
86
87 uint256& uint256::operator=(const basetype& b)
88 {
89     for (int i = 0; i < WIDTH; i++)
90         pn[i] = b.pn[i];
91     return *this;
92 }
93
94 uint256::uint256(uint64_t b)
95 {
96     pn[0] = (uint32_t)b;
97     pn[1] = (uint32_t)(b >> 32);
98     for (int i = 2; i < WIDTH; i++)
99         pn[i] = 0;
100 }
101
102 uint256& uint256::operator=(uint64_t b)
103 {
104     pn[0] = (uint32_t)b;
105     pn[1] = (uint32_t)(b >> 32);
106     for (int i = 2; i < WIDTH; i++)
107         pn[i] = 0;
108     return *this;
109 }
110
111 uint256& uint256::SetCompact(uint32_t nCompact, bool *pfNegative, bool *pfOverflow)
112 {
113     int nSize = nCompact >> 24;
114     uint32_t nWord = nCompact & 0x007fffff;
115     if (nSize <= 3) {
116         nWord >>= 8*(3-nSize);
117         *this = nWord;
118     } else {
119         *this = nWord;
120         *this <<= 8*(nSize-3);
121     }
122     if (pfNegative)
123         *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
124     if (pfOverflow)
125         *pfOverflow = nWord != 0 && ((nSize > 34) ||
126                                  (nWord > 0xff && nSize > 33) ||
127                                  (nWord > 0xffff && nSize > 32));
128     return *this;
129 }
130
131 uint32_t uint256::GetCompact(bool fNegative) const
132 {
133     int nSize = (bits() + 7) / 8;
134     uint32_t nCompact = 0;
135     if (nSize <= 3) {
136         nCompact = Get64(0) << 8*(3-nSize);
137     } else {
138         uint256 n = *this;
139         uint256 bn = n >> 8*(nSize-3);
140         nCompact = bn.Get64(0);
141     }
142     // The 0x00800000 bit denotes the sign.
143     // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
144     if (nCompact & 0x00800000) {
145         nCompact >>= 8;
146         nSize++;
147     }
148     assert((nCompact & ~0x007fffff) == 0);
149     assert(nSize < 256);
150     nCompact |= nSize << 24;
151     nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
152     return nCompact;
153 }
154
155 uint256& uint256::operator*=(uint32_t b32)
156 {
157     uint64_t carry = 0;
158     for (int i = 0; i < WIDTH; i++) {
159         uint64_t n = carry + (uint64_t)b32 * pn[i];
160         pn[i] = n & 0xffffffff;
161         carry = n >> 32;
162     }
163     return *this;
164 }
165
166 uint256& uint256::operator*=(const uint256& b)
167 {
168     uint256 a = *this;
169     *this = 0;
170     for (int j = 0; j < WIDTH; j++) {
171         uint64_t carry = 0;
172         for (int i = 0; i + j < WIDTH; i++) {
173             uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i];
174             pn[i + j] = n & 0xffffffff;
175             carry = n >> 32;
176         }
177     }
178     return *this;
179 }
180
181 uint256& uint256::operator/=(const uint256& b)
182 {
183     uint256 div = b;     // make a copy, so we can shift.
184     uint256 num = *this; // make a copy, so we can subtract.
185     *this = 0;                   // the quotient.
186     int num_bits = num.bits();
187     int div_bits = div.bits();
188     if (div_bits == 0)
189         throw uint256_error("Division by zero");
190     if (div_bits > num_bits) // the result is certainly 0.
191         return *this;
192     int shift = num_bits - div_bits;
193     div <<= shift; // shift so that div and num align.
194     while (shift >= 0) {
195         if (num >= div) {
196             num -= div;
197             pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result.
198         }
199         div >>= 1; // shift back.
200         shift--;
201     }
202     // num now contains the remainder of the division.
203     return *this;
204 }
205
206 uint256::uint256(const std::string& str)
207 {
208     SetHex(str);
209 }
210
211 uint256::uint256(const std::vector<unsigned char>& vch)
212 {
213     if (vch.size() == sizeof(pn))
214         memcpy(pn, &vch[0], sizeof(pn));
215     else
216         *this = 0;
217 }