Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
BigInt.cpp@7:1aad58757705, 2013-10-04 (annotated)
- Committer:
- feb11
- Date:
- Fri Oct 04 15:10:31 2013 +0000
- Revision:
- 7:1aad58757705
- Parent:
- 6:29e78b169f40
- Child:
- 8:2a361f1b41da
AND, OR bits operators
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| feb11 | 0:9d554894785b | 1 | #include "BigInt.h" |
| feb11 | 0:9d554894785b | 2 | #include <string.h> |
| feb11 | 0:9d554894785b | 3 | #include <stdio.h> |
| feb11 | 0:9d554894785b | 4 | #include <stdlib.h> |
| feb11 | 0:9d554894785b | 5 | #include <iostream> |
| feb11 | 0:9d554894785b | 6 | #include <climits> |
| feb11 | 0:9d554894785b | 7 | |
| feb11 | 0:9d554894785b | 8 | |
| feb11 | 0:9d554894785b | 9 | static uint32_t max(const uint32_t a, const uint32_t b) |
| feb11 | 0:9d554894785b | 10 | { |
| feb11 | 0:9d554894785b | 11 | return a < b ? b : a; |
| feb11 | 0:9d554894785b | 12 | } |
| feb11 | 0:9d554894785b | 13 | |
| feb11 | 0:9d554894785b | 14 | static uint32_t num(const uint32_t a) |
| feb11 | 0:9d554894785b | 15 | { |
| feb11 | 0:9d554894785b | 16 | return a/4 + (a%4 ? 1:0); |
| feb11 | 0:9d554894785b | 17 | } |
| feb11 | 0:9d554894785b | 18 | |
| feb11 | 0:9d554894785b | 19 | BigInt::BigInt(): |
| feb11 | 0:9d554894785b | 20 | size(0), |
| feb11 | 0:9d554894785b | 21 | bits(0) |
| feb11 | 0:9d554894785b | 22 | { |
| feb11 | 0:9d554894785b | 23 | } |
| feb11 | 0:9d554894785b | 24 | |
| feb11 | 2:1001793a090d | 25 | BigInt::BigInt(const uint32_t a) |
| feb11 | 2:1001793a090d | 26 | { |
| feb11 | 2:1001793a090d | 27 | if(a >> 24) |
| feb11 | 2:1001793a090d | 28 | size = 4; |
| feb11 | 2:1001793a090d | 29 | else if(a >> 16) |
| feb11 | 2:1001793a090d | 30 | size = 3; |
| feb11 | 2:1001793a090d | 31 | else if(a >> 8) |
| feb11 | 2:1001793a090d | 32 | size = 2; |
| feb11 | 2:1001793a090d | 33 | else |
| feb11 | 2:1001793a090d | 34 | size = 1; |
| feb11 | 2:1001793a090d | 35 | bits = new uint32_t[1]; |
| feb11 | 2:1001793a090d | 36 | bits[0] = a; |
| feb11 | 2:1001793a090d | 37 | } |
| feb11 | 2:1001793a090d | 38 | |
| feb11 | 0:9d554894785b | 39 | BigInt::BigInt(const BigInt &a): |
| feb11 | 0:9d554894785b | 40 | size(a.size) |
| feb11 | 0:9d554894785b | 41 | { |
| feb11 | 0:9d554894785b | 42 | uint32_t l = num(size); |
| feb11 | 0:9d554894785b | 43 | bits = new uint32_t[l]; |
| feb11 | 0:9d554894785b | 44 | for(int i = 0; i < l; ++i) |
| feb11 | 0:9d554894785b | 45 | bits[i] = a.bits[i]; |
| feb11 | 0:9d554894785b | 46 | } |
| feb11 | 0:9d554894785b | 47 | |
| feb11 | 0:9d554894785b | 48 | |
| feb11 | 0:9d554894785b | 49 | BigInt::~BigInt() |
| feb11 | 0:9d554894785b | 50 | { |
| feb11 | 0:9d554894785b | 51 | if(bits) |
| feb11 | 0:9d554894785b | 52 | delete[] bits; |
| feb11 | 0:9d554894785b | 53 | bits = 0; |
| feb11 | 0:9d554894785b | 54 | } |
| feb11 | 0:9d554894785b | 55 | |
| feb11 | 0:9d554894785b | 56 | BigInt& BigInt::operator=(const BigInt& a) |
| feb11 | 0:9d554894785b | 57 | { |
| feb11 | 0:9d554894785b | 58 | size = a.size; |
| feb11 | 0:9d554894785b | 59 | uint32_t l = num(size); |
| feb11 | 0:9d554894785b | 60 | if(bits) |
| feb11 | 0:9d554894785b | 61 | delete[] bits; |
| feb11 | 0:9d554894785b | 62 | bits = new uint32_t[l]; |
| feb11 | 0:9d554894785b | 63 | for(int i = 0; i < l; ++i) |
| feb11 | 0:9d554894785b | 64 | bits[i] = a.bits[i]; |
| feb11 | 0:9d554894785b | 65 | return *this; |
| feb11 | 0:9d554894785b | 66 | } |
| feb11 | 0:9d554894785b | 67 | |
| feb11 | 0:9d554894785b | 68 | void BigInt::import(uint8_t *data, uint32_t length) |
| feb11 | 0:9d554894785b | 69 | { |
| feb11 | 0:9d554894785b | 70 | size = length; |
| feb11 | 0:9d554894785b | 71 | size_t l = size/4; |
| feb11 | 0:9d554894785b | 72 | if(size % 4 != 0) |
| feb11 | 0:9d554894785b | 73 | l++; |
| feb11 | 0:9d554894785b | 74 | if(bits) |
| feb11 | 0:9d554894785b | 75 | delete[] bits; |
| feb11 | 0:9d554894785b | 76 | bits = new uint32_t[l]; |
| feb11 | 0:9d554894785b | 77 | memset(bits, 0, sizeof(uint32_t)*l); |
| feb11 | 4:773aed3156c5 | 78 | for(int i = length-1; i >=0; --i) |
| feb11 | 0:9d554894785b | 79 | bits[i/4] |= data[i] << ((i%4)*8); |
| feb11 | 0:9d554894785b | 80 | } |
| feb11 | 0:9d554894785b | 81 | |
| feb11 | 0:9d554894785b | 82 | BigInt operator+(const BigInt &a, const BigInt& b) |
| feb11 | 0:9d554894785b | 83 | { |
| feb11 | 0:9d554894785b | 84 | BigInt result; |
| feb11 | 0:9d554894785b | 85 | |
| feb11 | 0:9d554894785b | 86 | result.size = a.size > b.size ? a.size : b.size; |
| feb11 | 0:9d554894785b | 87 | size_t l = result.size/4; |
| feb11 | 0:9d554894785b | 88 | if(result.size % 4 != 0) |
| feb11 | 0:9d554894785b | 89 | l++; |
| feb11 | 0:9d554894785b | 90 | result.bits = new uint32_t[l]; |
| feb11 | 0:9d554894785b | 91 | memset(result.bits, 0, sizeof(uint32_t)*l); |
| feb11 | 0:9d554894785b | 92 | uint32_t al = num(a.size); |
| feb11 | 0:9d554894785b | 93 | uint32_t bl = num(b.size); |
| feb11 | 0:9d554894785b | 94 | uint32_t carry = 0; |
| feb11 | 0:9d554894785b | 95 | for(int i = 0; i < l; ++i) |
| feb11 | 0:9d554894785b | 96 | { |
| feb11 | 0:9d554894785b | 97 | uint32_t tmpA = 0, tmpB = 0; |
| feb11 | 0:9d554894785b | 98 | if(i < al) |
| feb11 | 0:9d554894785b | 99 | tmpA = a.bits[i]; |
| feb11 | 0:9d554894785b | 100 | if(i < bl) |
| feb11 | 0:9d554894785b | 101 | tmpB = b.bits[i]; |
| feb11 | 0:9d554894785b | 102 | result.bits[i] = tmpA + tmpB + carry; |
| feb11 | 0:9d554894785b | 103 | carry = result.bits[i] < max(tmpA, tmpB); |
| feb11 | 0:9d554894785b | 104 | } |
| feb11 | 0:9d554894785b | 105 | if(carry) |
| feb11 | 0:9d554894785b | 106 | { |
| feb11 | 0:9d554894785b | 107 | result.size++; |
| feb11 | 0:9d554894785b | 108 | if(result.size > l*4) |
| feb11 | 0:9d554894785b | 109 | { |
| feb11 | 0:9d554894785b | 110 | l++; |
| feb11 | 0:9d554894785b | 111 | result.bits = (uint32_t*)realloc(result.bits, l * sizeof(uint32_t)); |
| feb11 | 0:9d554894785b | 112 | result.bits[l-1] = 0x00000001; |
| feb11 | 0:9d554894785b | 113 | } |
| feb11 | 0:9d554894785b | 114 | else |
| feb11 | 0:9d554894785b | 115 | { |
| feb11 | 0:9d554894785b | 116 | result.bits[l-1] += 1 << (8 *((result.size-1)%4)); |
| feb11 | 0:9d554894785b | 117 | } |
| feb11 | 0:9d554894785b | 118 | } |
| feb11 | 0:9d554894785b | 119 | |
| feb11 | 0:9d554894785b | 120 | return result; |
| feb11 | 0:9d554894785b | 121 | } |
| feb11 | 0:9d554894785b | 122 | |
| feb11 | 0:9d554894785b | 123 | BigInt& BigInt::operator+=(const BigInt &b) |
| feb11 | 0:9d554894785b | 124 | { |
| feb11 | 0:9d554894785b | 125 | return (*this = (*this) + b); |
| feb11 | 0:9d554894785b | 126 | } |
| feb11 | 0:9d554894785b | 127 | |
| feb11 | 0:9d554894785b | 128 | BigInt& BigInt::operator++() |
| feb11 | 0:9d554894785b | 129 | { |
| feb11 | 3:3fa3ceb0c69d | 130 | return (*this += 1); |
| feb11 | 0:9d554894785b | 131 | } |
| feb11 | 0:9d554894785b | 132 | |
| feb11 | 0:9d554894785b | 133 | BigInt BigInt::operator++(int) |
| feb11 | 0:9d554894785b | 134 | { |
| feb11 | 0:9d554894785b | 135 | BigInt t = *this; |
| feb11 | 3:3fa3ceb0c69d | 136 | *this += 1; |
| feb11 | 0:9d554894785b | 137 | return t; |
| feb11 | 0:9d554894785b | 138 | } |
| feb11 | 0:9d554894785b | 139 | |
| feb11 | 0:9d554894785b | 140 | // a - b, if b >= a, returns 0 |
| feb11 | 0:9d554894785b | 141 | // No negative number allowed |
| feb11 | 0:9d554894785b | 142 | BigInt operator-(const BigInt &a, const BigInt& b) |
| feb11 | 0:9d554894785b | 143 | { |
| feb11 | 0:9d554894785b | 144 | BigInt result; |
| feb11 | 0:9d554894785b | 145 | |
| feb11 | 0:9d554894785b | 146 | if(b >= a) |
| feb11 | 0:9d554894785b | 147 | { |
| feb11 | 3:3fa3ceb0c69d | 148 | return result = 0; |
| feb11 | 0:9d554894785b | 149 | } |
| feb11 | 0:9d554894785b | 150 | else |
| feb11 | 0:9d554894785b | 151 | { |
| feb11 | 0:9d554894785b | 152 | result.size = a.size; |
| feb11 | 0:9d554894785b | 153 | uint32_t l = num(a.size); |
| feb11 | 0:9d554894785b | 154 | result.bits = new uint32_t[l]; |
| feb11 | 0:9d554894785b | 155 | memset(result.bits, 0, sizeof(uint32_t)*l); |
| feb11 | 0:9d554894785b | 156 | uint32_t bl = num(b.size); |
| feb11 | 0:9d554894785b | 157 | uint8_t borrow = 0; |
| feb11 | 0:9d554894785b | 158 | for(uint32_t i = 0; i < l; ++i) |
| feb11 | 0:9d554894785b | 159 | { |
| feb11 | 0:9d554894785b | 160 | uint32_t tmpA = a.bits[i], tmpB = 0; |
| feb11 | 0:9d554894785b | 161 | if(i < bl) |
| feb11 | 0:9d554894785b | 162 | tmpB = b.bits[i]; |
| feb11 | 0:9d554894785b | 163 | if(borrow) |
| feb11 | 0:9d554894785b | 164 | { |
| feb11 | 0:9d554894785b | 165 | if(tmpA == 0) |
| feb11 | 0:9d554894785b | 166 | tmpA = ULONG_MAX; |
| feb11 | 0:9d554894785b | 167 | else |
| feb11 | 0:9d554894785b | 168 | --tmpA; |
| feb11 | 0:9d554894785b | 169 | |
| feb11 | 0:9d554894785b | 170 | if(tmpA < tmpB) |
| feb11 | 0:9d554894785b | 171 | result.bits[i] = tmpA + 1 + (ULONG_MAX - tmpB); |
| feb11 | 0:9d554894785b | 172 | else |
| feb11 | 0:9d554894785b | 173 | result.bits[i] = tmpA - tmpB; |
| feb11 | 0:9d554894785b | 174 | |
| feb11 | 0:9d554894785b | 175 | if(a.bits[i] != 0 && tmpA > tmpB) |
| feb11 | 0:9d554894785b | 176 | borrow = 0; |
| feb11 | 0:9d554894785b | 177 | } |
| feb11 | 0:9d554894785b | 178 | else |
| feb11 | 0:9d554894785b | 179 | { |
| feb11 | 0:9d554894785b | 180 | if(tmpA < tmpB) |
| feb11 | 0:9d554894785b | 181 | result.bits[i] = tmpA + 1 + (ULONG_MAX - tmpB); |
| feb11 | 0:9d554894785b | 182 | else |
| feb11 | 0:9d554894785b | 183 | result.bits[i] = tmpA - tmpB; |
| feb11 | 0:9d554894785b | 184 | borrow = tmpA < tmpB; |
| feb11 | 0:9d554894785b | 185 | } |
| feb11 | 0:9d554894785b | 186 | } |
| feb11 | 0:9d554894785b | 187 | |
| feb11 | 0:9d554894785b | 188 | // trim result |
| feb11 | 0:9d554894785b | 189 | uint8_t *tmp = (uint8_t*)result.bits; |
| feb11 | 0:9d554894785b | 190 | uint32_t newSize = result.size; |
| feb11 | 0:9d554894785b | 191 | while(tmp[newSize-1] == 0 && newSize > 0) |
| feb11 | 0:9d554894785b | 192 | newSize--; |
| feb11 | 0:9d554894785b | 193 | result.size = newSize; |
| feb11 | 0:9d554894785b | 194 | uint32_t tmpL = num(result.size); |
| feb11 | 0:9d554894785b | 195 | if(tmpL < l) |
| feb11 | 0:9d554894785b | 196 | result.bits = (uint32_t*)realloc(result.bits, sizeof(uint32_t)*tmpL); |
| feb11 | 0:9d554894785b | 197 | |
| feb11 | 0:9d554894785b | 198 | return result; |
| feb11 | 0:9d554894785b | 199 | } |
| feb11 | 0:9d554894785b | 200 | } |
| feb11 | 0:9d554894785b | 201 | |
| feb11 | 0:9d554894785b | 202 | BigInt& BigInt::operator-=(const BigInt &b) |
| feb11 | 0:9d554894785b | 203 | { |
| feb11 | 0:9d554894785b | 204 | return (*this = (*this) - b); |
| feb11 | 0:9d554894785b | 205 | } |
| feb11 | 0:9d554894785b | 206 | |
| feb11 | 0:9d554894785b | 207 | BigInt& BigInt::operator--() |
| feb11 | 0:9d554894785b | 208 | { |
| feb11 | 3:3fa3ceb0c69d | 209 | return (*this -= 1); |
| feb11 | 0:9d554894785b | 210 | } |
| feb11 | 0:9d554894785b | 211 | |
| feb11 | 0:9d554894785b | 212 | BigInt BigInt::operator--(int) |
| feb11 | 0:9d554894785b | 213 | { |
| feb11 | 0:9d554894785b | 214 | BigInt t = *this; |
| feb11 | 3:3fa3ceb0c69d | 215 | *this -= 1; |
| feb11 | 0:9d554894785b | 216 | return t; |
| feb11 | 0:9d554894785b | 217 | } |
| feb11 | 3:3fa3ceb0c69d | 218 | |
| feb11 | 1:00f2c40d46ed | 219 | BigInt operator*(const BigInt &a, const BigInt& b) |
| feb11 | 1:00f2c40d46ed | 220 | { |
| feb11 | 1:00f2c40d46ed | 221 | BigInt result; |
| feb11 | 1:00f2c40d46ed | 222 | |
| feb11 | 1:00f2c40d46ed | 223 | // if a == 0 or b == 0 then result = 0 |
| feb11 | 1:00f2c40d46ed | 224 | if(!a || !b) |
| feb11 | 3:3fa3ceb0c69d | 225 | return result = 0; |
| feb11 | 1:00f2c40d46ed | 226 | |
| feb11 | 1:00f2c40d46ed | 227 | // if a == 1, then result = b |
| feb11 | 3:3fa3ceb0c69d | 228 | if(a == 1) |
| feb11 | 1:00f2c40d46ed | 229 | return (result = b); |
| feb11 | 1:00f2c40d46ed | 230 | |
| feb11 | 1:00f2c40d46ed | 231 | // if b == 1, then result = a |
| feb11 | 3:3fa3ceb0c69d | 232 | if(b == 1) |
| feb11 | 1:00f2c40d46ed | 233 | return (result = a); |
| feb11 | 1:00f2c40d46ed | 234 | |
| feb11 | 4:773aed3156c5 | 235 | |
| feb11 | 4:773aed3156c5 | 236 | result.size = a.size + b.size; |
| feb11 | 4:773aed3156c5 | 237 | result.bits = new uint32_t[num(result.size)]; |
| feb11 | 4:773aed3156c5 | 238 | memset(result.bits, 0, sizeof(uint32_t)*num(result.size)); |
| feb11 | 4:773aed3156c5 | 239 | uint32_t carry = 0; |
| feb11 | 4:773aed3156c5 | 240 | for(int i = 0; i < num(result.size); ++i) |
| feb11 | 4:773aed3156c5 | 241 | { |
| feb11 | 4:773aed3156c5 | 242 | uint32_t tmpA = 0, tmpB = 0; |
| feb11 | 4:773aed3156c5 | 243 | if(i < num(a.size)) |
| feb11 | 4:773aed3156c5 | 244 | tmpA = a.bits[i]; |
| feb11 | 4:773aed3156c5 | 245 | |
| feb11 | 4:773aed3156c5 | 246 | if(i < num(b.size)) |
| feb11 | 4:773aed3156c5 | 247 | tmpB = b.bits[i]; |
| feb11 | 4:773aed3156c5 | 248 | |
| feb11 | 4:773aed3156c5 | 249 | uint64_t tmp = (uint64_t)tmpA * (uint64_t)tmpB + (uint64_t)carry; |
| feb11 | 4:773aed3156c5 | 250 | result.bits[i] = tmp; |
| feb11 | 4:773aed3156c5 | 251 | carry = tmp >> 32; |
| feb11 | 4:773aed3156c5 | 252 | } |
| feb11 | 4:773aed3156c5 | 253 | |
| feb11 | 4:773aed3156c5 | 254 | // trim result |
| feb11 | 4:773aed3156c5 | 255 | uint8_t *tmp = (uint8_t*)result.bits; |
| feb11 | 4:773aed3156c5 | 256 | uint32_t newSize = result.size; |
| feb11 | 4:773aed3156c5 | 257 | while(tmp[newSize-1] == 0 && newSize > 0) |
| feb11 | 4:773aed3156c5 | 258 | newSize--; |
| feb11 | 4:773aed3156c5 | 259 | if(num(newSize) < num(result.size)) |
| feb11 | 4:773aed3156c5 | 260 | result.bits = (uint32_t*)realloc(result.bits, sizeof(uint32_t)*num(newSize)); |
| feb11 | 4:773aed3156c5 | 261 | result.size = newSize; |
| feb11 | 1:00f2c40d46ed | 262 | |
| feb11 | 1:00f2c40d46ed | 263 | return result; |
| feb11 | 1:00f2c40d46ed | 264 | } |
| feb11 | 1:00f2c40d46ed | 265 | |
| feb11 | 1:00f2c40d46ed | 266 | BigInt& BigInt::operator*=(const BigInt &b) |
| feb11 | 1:00f2c40d46ed | 267 | { |
| feb11 | 1:00f2c40d46ed | 268 | return (*this = (*this) * b); |
| feb11 | 1:00f2c40d46ed | 269 | } |
| feb11 | 1:00f2c40d46ed | 270 | |
| feb11 | 1:00f2c40d46ed | 271 | BigInt operator>>(const BigInt &a, const uint32_t m) |
| feb11 | 1:00f2c40d46ed | 272 | { |
| feb11 | 1:00f2c40d46ed | 273 | BigInt result; |
| feb11 | 1:00f2c40d46ed | 274 | if(m == 0) |
| feb11 | 1:00f2c40d46ed | 275 | return result = a; |
| feb11 | 1:00f2c40d46ed | 276 | if(m/8 >= a.size) |
| feb11 | 3:3fa3ceb0c69d | 277 | return result = 0; |
| feb11 | 1:00f2c40d46ed | 278 | |
| feb11 | 1:00f2c40d46ed | 279 | result.size = a.size - m/8; |
| feb11 | 1:00f2c40d46ed | 280 | result.bits = new uint32_t[num(result.size)]; |
| feb11 | 1:00f2c40d46ed | 281 | uint8_t s = m%32; |
| feb11 | 1:00f2c40d46ed | 282 | for(uint32_t i = 0; i < num(result.size); ++i) |
| feb11 | 1:00f2c40d46ed | 283 | { |
| feb11 | 1:00f2c40d46ed | 284 | if(m/32+i+1 < num(a.size)) |
| feb11 | 1:00f2c40d46ed | 285 | result.bits[i] = (a.bits[m/32+i+1] << (32-s)) | (a.bits[m/32+i] >> s); |
| feb11 | 1:00f2c40d46ed | 286 | else |
| feb11 | 1:00f2c40d46ed | 287 | result.bits[i] = (a.bits[m/32+i] >> s); |
| feb11 | 1:00f2c40d46ed | 288 | } |
| feb11 | 1:00f2c40d46ed | 289 | |
| feb11 | 1:00f2c40d46ed | 290 | |
| feb11 | 1:00f2c40d46ed | 291 | return result; |
| feb11 | 1:00f2c40d46ed | 292 | } |
| feb11 | 1:00f2c40d46ed | 293 | |
| feb11 | 1:00f2c40d46ed | 294 | BigInt& BigInt::operator>>=(const uint32_t m) |
| feb11 | 1:00f2c40d46ed | 295 | { |
| feb11 | 1:00f2c40d46ed | 296 | return *this = *this >> m; |
| feb11 | 1:00f2c40d46ed | 297 | } |
| feb11 | 1:00f2c40d46ed | 298 | |
| feb11 | 1:00f2c40d46ed | 299 | BigInt operator<<(const BigInt &a, const uint32_t m) |
| feb11 | 1:00f2c40d46ed | 300 | { |
| feb11 | 1:00f2c40d46ed | 301 | BigInt result; |
| feb11 | 1:00f2c40d46ed | 302 | |
| feb11 | 1:00f2c40d46ed | 303 | if(m == 0) |
| feb11 | 1:00f2c40d46ed | 304 | return result = a; |
| feb11 | 1:00f2c40d46ed | 305 | |
| feb11 | 1:00f2c40d46ed | 306 | result.size = m/8 + a.size; |
| feb11 | 1:00f2c40d46ed | 307 | uint32_t h = a.bits[num(a.size)-1]; |
| feb11 | 1:00f2c40d46ed | 308 | if((h << (m%32)) < h) |
| feb11 | 1:00f2c40d46ed | 309 | ++result.size; |
| feb11 | 1:00f2c40d46ed | 310 | uint32_t l = num(result.size); |
| feb11 | 1:00f2c40d46ed | 311 | result.bits = new uint32_t[l]; |
| feb11 | 1:00f2c40d46ed | 312 | memset(result.bits, 0, sizeof(uint32_t)*l); |
| feb11 | 1:00f2c40d46ed | 313 | uint32_t s = m % 32; |
| feb11 | 1:00f2c40d46ed | 314 | for(uint32_t i = 0; i < num(a.size); ++i) |
| feb11 | 1:00f2c40d46ed | 315 | { |
| feb11 | 1:00f2c40d46ed | 316 | if(i == 0) |
| feb11 | 1:00f2c40d46ed | 317 | result.bits[m/32+i] = a.bits[i] << s; |
| feb11 | 1:00f2c40d46ed | 318 | else |
| feb11 | 1:00f2c40d46ed | 319 | result.bits[m/32+i] = (a.bits[i] << s) | (a.bits[i-1] >> (32-s)); |
| feb11 | 1:00f2c40d46ed | 320 | } |
| feb11 | 1:00f2c40d46ed | 321 | if(a.bits[num(a.size)-1] << s < a.bits[num(a.size)-1]) |
| feb11 | 1:00f2c40d46ed | 322 | result.bits[num(result.size)-1] = a.bits[num(a.size)-1] >> (32-s); |
| feb11 | 1:00f2c40d46ed | 323 | |
| feb11 | 1:00f2c40d46ed | 324 | |
| feb11 | 1:00f2c40d46ed | 325 | return result; |
| feb11 | 1:00f2c40d46ed | 326 | } |
| feb11 | 1:00f2c40d46ed | 327 | |
| feb11 | 1:00f2c40d46ed | 328 | BigInt& BigInt::operator<<=(const uint32_t m) |
| feb11 | 1:00f2c40d46ed | 329 | { |
| feb11 | 1:00f2c40d46ed | 330 | return (*this = *this << m); |
| feb11 | 1:00f2c40d46ed | 331 | } |
| feb11 | 0:9d554894785b | 332 | |
| feb11 | 5:beeb31f340a7 | 333 | BigInt operator%(const BigInt &a, const BigInt &b) |
| feb11 | 5:beeb31f340a7 | 334 | { |
| feb11 | 5:beeb31f340a7 | 335 | BigInt result = a; |
| feb11 | 5:beeb31f340a7 | 336 | while(result > b) |
| feb11 | 5:beeb31f340a7 | 337 | result -= b; |
| feb11 | 5:beeb31f340a7 | 338 | |
| feb11 | 6:29e78b169f40 | 339 | // trim result |
| feb11 | 6:29e78b169f40 | 340 | uint8_t *tmp = (uint8_t*)result.bits; |
| feb11 | 6:29e78b169f40 | 341 | uint32_t newSize = result.size; |
| feb11 | 6:29e78b169f40 | 342 | while(tmp[newSize-1] == 0 && newSize > 0) |
| feb11 | 6:29e78b169f40 | 343 | newSize--; |
| feb11 | 6:29e78b169f40 | 344 | if(num(newSize) < num(result.size)) |
| feb11 | 6:29e78b169f40 | 345 | result.bits = (uint32_t*)realloc(result.bits, sizeof(uint32_t)*num(newSize)); |
| feb11 | 6:29e78b169f40 | 346 | result.size = newSize; |
| feb11 | 6:29e78b169f40 | 347 | |
| feb11 | 5:beeb31f340a7 | 348 | return result; |
| feb11 | 5:beeb31f340a7 | 349 | } |
| feb11 | 5:beeb31f340a7 | 350 | |
| feb11 | 5:beeb31f340a7 | 351 | BigInt& BigInt::operator%=(const BigInt &a) |
| feb11 | 5:beeb31f340a7 | 352 | { |
| feb11 | 5:beeb31f340a7 | 353 | return (*this = *this % a); |
| feb11 | 5:beeb31f340a7 | 354 | } |
| feb11 | 5:beeb31f340a7 | 355 | |
| feb11 | 0:9d554894785b | 356 | bool operator==(const BigInt &a, const BigInt &b) |
| feb11 | 0:9d554894785b | 357 | { |
| feb11 | 0:9d554894785b | 358 | if(a.size != b.size) |
| feb11 | 0:9d554894785b | 359 | return false; |
| feb11 | 0:9d554894785b | 360 | |
| feb11 | 0:9d554894785b | 361 | uint32_t l = num(a.size); |
| feb11 | 0:9d554894785b | 362 | for(int i = 0; i < l; ++i) |
| feb11 | 0:9d554894785b | 363 | if(a.bits[i] != b.bits[i]) |
| feb11 | 0:9d554894785b | 364 | return false; |
| feb11 | 0:9d554894785b | 365 | return true; |
| feb11 | 0:9d554894785b | 366 | } |
| feb11 | 0:9d554894785b | 367 | |
| feb11 | 0:9d554894785b | 368 | bool operator!=(const BigInt &a, const BigInt &b) |
| feb11 | 0:9d554894785b | 369 | { |
| feb11 | 0:9d554894785b | 370 | return ! (a==b); |
| feb11 | 0:9d554894785b | 371 | } |
| feb11 | 0:9d554894785b | 372 | |
| feb11 | 0:9d554894785b | 373 | bool operator<(const BigInt &a, const BigInt &b) |
| feb11 | 0:9d554894785b | 374 | { |
| feb11 | 0:9d554894785b | 375 | if(a.size < b.size) |
| feb11 | 0:9d554894785b | 376 | return true; |
| feb11 | 0:9d554894785b | 377 | if(a.size > b.size) |
| feb11 | 0:9d554894785b | 378 | return false; |
| feb11 | 0:9d554894785b | 379 | uint32_t l = num(a.size); |
| feb11 | 0:9d554894785b | 380 | for(int i = l-1; i >= 0; --i) |
| feb11 | 0:9d554894785b | 381 | if(a.bits[i] < b.bits[i]) |
| feb11 | 0:9d554894785b | 382 | return true; |
| feb11 | 0:9d554894785b | 383 | return false; |
| feb11 | 0:9d554894785b | 384 | } |
| feb11 | 0:9d554894785b | 385 | |
| feb11 | 0:9d554894785b | 386 | bool operator<=(const BigInt &a, const BigInt &b) |
| feb11 | 0:9d554894785b | 387 | { |
| feb11 | 0:9d554894785b | 388 | return (a < b) || (a == b); |
| feb11 | 0:9d554894785b | 389 | } |
| feb11 | 0:9d554894785b | 390 | |
| feb11 | 0:9d554894785b | 391 | bool operator>(const BigInt &a, const BigInt &b) |
| feb11 | 0:9d554894785b | 392 | { |
| feb11 | 0:9d554894785b | 393 | if(a.size > b.size) |
| feb11 | 0:9d554894785b | 394 | return true; |
| feb11 | 0:9d554894785b | 395 | if(a.size < b.size) |
| feb11 | 0:9d554894785b | 396 | return false; |
| feb11 | 0:9d554894785b | 397 | uint32_t l = num(a.size); |
| feb11 | 0:9d554894785b | 398 | for(int i = l-1; i >= 0; --i) |
| feb11 | 0:9d554894785b | 399 | if(a.bits[i] > b.bits[i]) |
| feb11 | 0:9d554894785b | 400 | return true; |
| feb11 | 0:9d554894785b | 401 | return false; |
| feb11 | 0:9d554894785b | 402 | } |
| feb11 | 0:9d554894785b | 403 | |
| feb11 | 0:9d554894785b | 404 | bool operator>=(const BigInt &a, const BigInt &b) |
| feb11 | 0:9d554894785b | 405 | { |
| feb11 | 0:9d554894785b | 406 | return (a > b) || (a == b); |
| feb11 | 0:9d554894785b | 407 | } |
| feb11 | 0:9d554894785b | 408 | |
| feb11 | 1:00f2c40d46ed | 409 | bool operator!(const BigInt &a) |
| feb11 | 0:9d554894785b | 410 | { |
| feb11 | 1:00f2c40d46ed | 411 | if(a.size != 1) |
| feb11 | 0:9d554894785b | 412 | return false; |
| feb11 | 1:00f2c40d46ed | 413 | return a.bits[0] == 0; |
| feb11 | 0:9d554894785b | 414 | } |
| feb11 | 0:9d554894785b | 415 | |
| feb11 | 7:1aad58757705 | 416 | |
| feb11 | 7:1aad58757705 | 417 | BigInt operator&(const BigInt &a, const BigInt &b) |
| feb11 | 7:1aad58757705 | 418 | { |
| feb11 | 7:1aad58757705 | 419 | BigInt result; |
| feb11 | 7:1aad58757705 | 420 | |
| feb11 | 7:1aad58757705 | 421 | result.size = a.size < b.size ? a.size : b.size; |
| feb11 | 7:1aad58757705 | 422 | uint32_t l = num(result.size); |
| feb11 | 7:1aad58757705 | 423 | result.bits = new uint32_t[l]; |
| feb11 | 7:1aad58757705 | 424 | memset(result.bits, 0, l); |
| feb11 | 7:1aad58757705 | 425 | |
| feb11 | 7:1aad58757705 | 426 | for(uint32_t i = 0; i < l; ++i) |
| feb11 | 7:1aad58757705 | 427 | result.bits[i] = a.bits[i] & b.bits[i]; |
| feb11 | 7:1aad58757705 | 428 | |
| feb11 | 7:1aad58757705 | 429 | |
| feb11 | 7:1aad58757705 | 430 | // trim result |
| feb11 | 7:1aad58757705 | 431 | uint8_t *tmp = (uint8_t*)result.bits; |
| feb11 | 7:1aad58757705 | 432 | uint32_t newSize = result.size; |
| feb11 | 7:1aad58757705 | 433 | while(tmp[newSize-1] == 0 && newSize > 0) |
| feb11 | 7:1aad58757705 | 434 | newSize--; |
| feb11 | 7:1aad58757705 | 435 | if(num(newSize) < num(result.size)) |
| feb11 | 7:1aad58757705 | 436 | result.bits = (uint32_t*)realloc(result.bits, sizeof(uint32_t)*num(newSize)); |
| feb11 | 7:1aad58757705 | 437 | result.size = newSize; |
| feb11 | 7:1aad58757705 | 438 | |
| feb11 | 7:1aad58757705 | 439 | return result; |
| feb11 | 7:1aad58757705 | 440 | } |
| feb11 | 7:1aad58757705 | 441 | |
| feb11 | 7:1aad58757705 | 442 | BigInt& BigInt::operator&=(const BigInt &a) |
| feb11 | 7:1aad58757705 | 443 | { |
| feb11 | 7:1aad58757705 | 444 | return (*this = *this & a); |
| feb11 | 7:1aad58757705 | 445 | } |
| feb11 | 7:1aad58757705 | 446 | |
| feb11 | 7:1aad58757705 | 447 | BigInt operator|(const BigInt &a, const BigInt &b) |
| feb11 | 7:1aad58757705 | 448 | { |
| feb11 | 7:1aad58757705 | 449 | BigInt result; |
| feb11 | 7:1aad58757705 | 450 | |
| feb11 | 7:1aad58757705 | 451 | uint32_t na = num(a.size); |
| feb11 | 7:1aad58757705 | 452 | uint32_t nb = num(b.size); |
| feb11 | 7:1aad58757705 | 453 | uint32_t l = max(na,nb); |
| feb11 | 7:1aad58757705 | 454 | result.size = max(a.size, b.size); |
| feb11 | 7:1aad58757705 | 455 | result.bits = new uint32_t[l]; |
| feb11 | 7:1aad58757705 | 456 | memset(result.bits, 0, l); |
| feb11 | 7:1aad58757705 | 457 | |
| feb11 | 7:1aad58757705 | 458 | for(uint32_t i = 0; i < l; ++i) |
| feb11 | 7:1aad58757705 | 459 | { |
| feb11 | 7:1aad58757705 | 460 | if(i < na && i < nb) |
| feb11 | 7:1aad58757705 | 461 | result.bits[i] = a.bits[i] | b.bits[i]; |
| feb11 | 7:1aad58757705 | 462 | else if(i < na) |
| feb11 | 7:1aad58757705 | 463 | result.bits[i] = a.bits[i]; |
| feb11 | 7:1aad58757705 | 464 | else |
| feb11 | 7:1aad58757705 | 465 | result.bits[i] = b.bits[i]; |
| feb11 | 7:1aad58757705 | 466 | } |
| feb11 | 7:1aad58757705 | 467 | |
| feb11 | 7:1aad58757705 | 468 | return result; |
| feb11 | 7:1aad58757705 | 469 | } |
| feb11 | 7:1aad58757705 | 470 | |
| feb11 | 7:1aad58757705 | 471 | BigInt& BigInt::operator|=(const BigInt &a) |
| feb11 | 7:1aad58757705 | 472 | { |
| feb11 | 7:1aad58757705 | 473 | return (*this = *this | a); |
| feb11 | 7:1aad58757705 | 474 | } |
| feb11 | 7:1aad58757705 | 475 | |
| feb11 | 0:9d554894785b | 476 | void BigInt::print() |
| feb11 | 0:9d554894785b | 477 | { |
| feb11 | 0:9d554894785b | 478 | printf("size: %d bytes\n", size); |
| feb11 | 0:9d554894785b | 479 | uint32_t n = num(size); |
| feb11 | 0:9d554894785b | 480 | for(int i = n-1; i >= 0; --i) |
| feb11 | 0:9d554894785b | 481 | { |
| feb11 | 1:00f2c40d46ed | 482 | printf("%08x ", bits[i]); |
| feb11 | 0:9d554894785b | 483 | } |
| feb11 | 0:9d554894785b | 484 | printf("\n"); |
| feb11 | 0:9d554894785b | 485 | } |