标签:
写文件管理的时候看到书上的Demo代码居然是用qunit64写的。。。坑爹啊,文件大小表示居然用qunit64,太不严谨了吧,想了下还是写了这个东西,本来想写浮点的,后来想下算了还蛮复杂的,先用着吧。稍微测试了一下感觉还行,可能有BUG,如果发现了还望告诉我
1 #pragma once 2 #ifndef BigIntNums_H 3 #define BigIntNums_H 4 5 #include <vector> 6 #include <iostream> 7 #include <algorithm> 8 #include <iomanip> 9 #include <sstream> 10 #include <string> 11 12 using std::reverse; 13 using std::right; 14 using std::left; 15 using std::setw; 16 using std::setfill; 17 using std::stringstream; 18 using std::string; 19 20 using std::ostream; 21 using std::istream; 22 23 class BigIntNums; 24 25 bool operator==(const BigIntNums &, const BigIntNums &); 26 bool operator!=(const BigIntNums &, const BigIntNums &); 27 bool operator<(const BigIntNums &, const BigIntNums &); 28 bool operator>(const BigIntNums &, const BigIntNums &); 29 bool operator<=(const BigIntNums &, const BigIntNums &); 30 bool operator>=(const BigIntNums &, const BigIntNums &); 31 ostream &operator<<(ostream &, const BigIntNums &); 32 istream &operator>>(istream &, BigIntNums &); 33 BigIntNums operator+(const BigIntNums &, const BigIntNums &); 34 BigIntNums operator*(const BigIntNums &, const BigIntNums &); 35 BigIntNums operator-(const BigIntNums &, const BigIntNums &); 36 BigIntNums operator/(const BigIntNums &, const BigIntNums &); 37 BigIntNums operator%(const BigIntNums &, const BigIntNums &); 38 BigIntNums operator-(const BigIntNums &); 39 BigIntNums abs(const BigIntNums &); 40 41 class BigIntNums 42 { 43 friend ostream &operator<<(ostream &, const BigIntNums &); 44 friend istream &operator>>(istream &, BigIntNums &); 45 friend BigIntNums operator-(const BigIntNums &); 46 friend BigIntNums operator+(const BigIntNums &, const BigIntNums &); 47 friend BigIntNums operator*(const BigIntNums &, const BigIntNums &); 48 friend BigIntNums operator-(const BigIntNums &, const BigIntNums &); 49 friend BigIntNums operator/(const BigIntNums &, const BigIntNums &); 50 friend BigIntNums operator%(const BigIntNums &, const BigIntNums &); 51 friend bool operator<(const BigIntNums &, const BigIntNums &); 52 friend bool operator>(const BigIntNums &, const BigIntNums &); 53 friend bool operator<=(const BigIntNums &, const BigIntNums &); 54 friend bool operator>=(const BigIntNums &, const BigIntNums &); 55 friend bool operator==(const BigIntNums &, const BigIntNums &); 56 friend bool operator!=(const BigIntNums &, const BigIntNums &); 57 public: 58 BigIntNums() = default; 59 BigIntNums(const BigIntNums &); 60 BigIntNums(const string &); 61 BigIntNums(const int &); 62 BigIntNums(const unsigned int &); 63 BigIntNums(const long long &); 64 BigIntNums(const unsigned long long &); 65 66 operator bool(); 67 BigIntNums &operator++(); 68 BigIntNums &operator--(); 69 BigIntNums &operator=(const BigIntNums &); 70 BigIntNums &operator+=(const BigIntNums &); 71 BigIntNums &operator*=(const BigIntNums &); 72 BigIntNums &operator-=(const BigIntNums &); 73 BigIntNums &operator/=(const BigIntNums &); 74 private: 75 static constexpr size_t gap_ = 10000; 76 static constexpr size_t base_ = 10; 77 78 std::vector<int> numMem; 79 bool npFlag = true; 80 81 void combineStrToBigInt(const string &); 82 template<typename T>void loadNums(T); 83 void clear(); 84 }; 85 86 template<typename T>void BigIntNums::loadNums(T num) 87 { 88 numMem.clear(); 89 while (num / gap_) 90 { 91 numMem.push_back(static_cast<int>(num%gap_)); 92 num /= gap_; 93 } 94 numMem.push_back(static_cast<int>(num)); 95 } 96 97 #endif // BigIntNums_H
1 #include "bigIntNum.h" 2 3 ostream &operator<<(ostream &os, const BigIntNums &num) 4 { 5 if (num.npFlag == false) 6 os << ‘-‘; 7 os << num.numMem[num.numMem.size() - 1] << " "; 8 os << setfill(‘0‘) << right; 9 int cut = static_cast<int>(log10(BigIntNums::gap_)); 10 for(int i = num.numMem.size() - 2;i >=0 ;i--) 11 os << setw(cut) << num.numMem[i] << " "; 12 os << setfill(‘ ‘) << left; 13 return os; 14 } 15 16 istream &operator>>(istream &is, BigIntNums &num) 17 { 18 num.clear(); 19 string str; 20 is >> str; 21 num.combineStrToBigInt(str); 22 return is; 23 } 24 25 BigIntNums::BigIntNums(const BigIntNums &ob) 26 :numMem(ob.numMem) 27 , npFlag(ob.npFlag) 28 { } 29 30 BigIntNums::BigIntNums(const int &num) 31 { 32 loadNums(num); 33 npFlag = num >= 0 ? true : false; 34 } 35 36 BigIntNums::BigIntNums(const unsigned int &num) 37 { 38 loadNums(num); 39 npFlag = true; 40 } 41 42 BigIntNums::BigIntNums(const long long &num) 43 { 44 loadNums(num); 45 npFlag = num >= 0 ? true : false; 46 } 47 48 BigIntNums::BigIntNums(const unsigned long long &num) 49 { 50 loadNums(num); 51 npFlag = true; 52 } 53 54 BigIntNums::BigIntNums(const string &str_org) 55 { 56 combineStrToBigInt(str_org); 57 } 58 59 inline void BigIntNums::clear() 60 { 61 numMem.clear(); 62 npFlag = true; 63 } 64 65 void BigIntNums::combineStrToBigInt(const string &str_org) 66 { 67 int base_Count = static_cast<int>(log10(BigIntNums::gap_)); 68 69 string str = str_org; 70 reverse(str.begin(), str.end()); 71 if (!isalnum(str.back())) 72 { 73 npFlag = str.back() == ‘+‘ ? 1 : 0; 74 str.pop_back(); 75 } 76 int cnt = str.size() - base_Count, i; 77 for (i = 0; i < cnt; i += 4) 78 { 79 string cast = str.substr(i, base_Count); 80 reverse(cast.begin(), cast.end()); 81 int tmp = atoi(cast.c_str()); 82 numMem.push_back(tmp); 83 } 84 string cast = str.substr(i, str.size()); 85 reverse(cast.begin(), cast.end()); 86 int tmp = atoi(cast.c_str()); 87 numMem.push_back(tmp); 88 } 89 90 BigIntNums::operator bool() 91 { 92 return *this != BigIntNums(0); 93 } 94 95 bool operator==(const BigIntNums &A, const BigIntNums &B) 96 { 97 if (A.npFlag != B.npFlag) 98 return false; 99 else if (A.numMem.size() != B.numMem.size()) 100 return false; 101 else 102 { 103 for (int i = 0;i < A.numMem.size();i++) 104 if (A.numMem[i] != B.numMem[i]) 105 return false; 106 } 107 return true; 108 } 109 110 bool operator!=(const BigIntNums &A, const BigIntNums &B) 111 { 112 return !(A == B); 113 } 114 115 bool operator<(const BigIntNums &A, const BigIntNums &B) 116 { 117 if (A.npFlag == true && B.npFlag == false) 118 return false; 119 else if (A.npFlag == false && B.npFlag == true) 120 return true; 121 else 122 { 123 auto ret = A.npFlag && B.npFlag; 124 if (A.numMem.size() > B.numMem.size()) 125 return !ret; 126 else if (A.numMem.size() < B.numMem.size()) 127 return ret; 128 else if (A.numMem.size() == B.numMem.size()) 129 { 130 for (int i = A.numMem.size() - 1;i >= 0;i--) 131 { 132 if (A.numMem[i] > B.numMem[i]) 133 return !ret; 134 else if (A.numMem[i] < B.numMem[i]) 135 return ret; 136 } 137 } 138 return false;//相等 139 } 140 } 141 142 bool operator>(const BigIntNums &A, const BigIntNums &B) 143 { 144 if (A.npFlag == false && B.npFlag == true) 145 return false; 146 else if (A.npFlag == true && B.npFlag == false) 147 return true; 148 else 149 { 150 auto ret = A.npFlag && B.npFlag; 151 if (A.numMem.size() > B.numMem.size()) 152 return ret; 153 else if (A.numMem.size() < B.numMem.size()) 154 return !ret; 155 else if (A.numMem.size() == B.numMem.size()) 156 { 157 for (int i = A.numMem.size() - 1;i >= 0;i--) 158 { 159 if (A.numMem[i] > B.numMem[i]) 160 return !ret; 161 else if (A.numMem[i] < B.numMem[i]) 162 return ret; 163 } 164 } 165 return false;//相等 166 } 167 } 168 169 bool operator<=(const BigIntNums &A, const BigIntNums &B) 170 { 171 return A < B || A == B; 172 } 173 174 bool operator>=(const BigIntNums &A, const BigIntNums &B) 175 { 176 return A > B || A == B; 177 } 178 179 BigIntNums abs(const BigIntNums &i) 180 { 181 return i >= 0 ? i : -i; 182 } 183 184 BigIntNums operator-(const BigIntNums &num) 185 { 186 BigIntNums newNum(num); 187 newNum.npFlag = !num.npFlag; 188 return newNum; 189 } 190 191 BigIntNums operator+(const BigIntNums &A, const BigIntNums &B) 192 { 193 BigIntNums C; 194 195 if (A.npFlag == true && B.npFlag == true) 196 C.npFlag = true; 197 else if (A.npFlag == false && B.npFlag == false) 198 C.npFlag = false; 199 else if (A.npFlag == true && B.npFlag == false) 200 return A - (-B); 201 else if (A.npFlag == false && B.npFlag == true) 202 return B - (-A); 203 204 std::vector<int> &CM = C.numMem; 205 const std::vector<int> &AM = A.numMem, &BM = B.numMem; 206 207 int up = 0, tmp; 208 size_t cnt = std::min(A.numMem.size(), B.numMem.size()), i = 0; 209 210 for (;i < cnt; i++) 211 { 212 tmp = AM[i] + BM[i] + up; 213 CM.push_back(tmp % BigIntNums::gap_); 214 up = tmp / BigIntNums::gap_; 215 } 216 //要注意可能会出现1+999999999999999999999999999的情况 217 for (;i < AM.size(); i++) 218 { 219 tmp = AM[i] + up; 220 CM.push_back((AM[i] + up) % BigIntNums::gap_); 221 up = (AM[i] + up) / BigIntNums::gap_; 222 } 223 for (;i < BM.size(); i++) 224 { 225 tmp = BM[i] + up; 226 CM.push_back((BM[i] + up) % BigIntNums::gap_); 227 up = (BM[i] + up) / BigIntNums::gap_; 228 } 229 if(up) 230 CM.push_back(up); 231 return C; 232 } 233 234 BigIntNums operator-(const BigIntNums &A, const BigIntNums &B) 235 { 236 BigIntNums C; 237 C.npFlag = true; 238 if (A.npFlag == true && B.npFlag == true && A < B) 239 { 240 C = B - A; 241 C.npFlag = false; 242 return C; 243 } 244 else if (A.npFlag == false && B.npFlag == false) 245 return (-B) - (-A); 246 else if (A.npFlag == true && B.npFlag == false) 247 return A + (-B); 248 else if (A.npFlag == false && B.npFlag == true) 249 { 250 C = (-A) + B; 251 C.npFlag = false; 252 return C; 253 } 254 255 std::vector<int> &CM = C.numMem; 256 const std::vector<int> &AM = A.numMem, &BM = B.numMem; 257 258 int down = 0, tmp; 259 size_t cnt = B.numMem.size(), i = 0; 260 261 for (;i < cnt; i++) 262 { 263 if (AM[i] - BM[i] - down >= 0) 264 { 265 tmp = AM[i] - BM[i] - down; 266 down = 0; 267 } 268 else 269 { 270 tmp = BigIntNums::gap_ + AM[i] - BM[i] - down; 271 down = 1; 272 } 273 CM.push_back(tmp); 274 } 275 //注意1000000000000000-1的情况 276 for (;i < A.numMem.size();i++) 277 { 278 if (AM[i] - down >= 0) 279 { 280 tmp = AM[i] - down; 281 down = 0; 282 } 283 else 284 { 285 tmp = BigIntNums::gap_ + AM[i] - down; 286 down = 1; 287 } 288 CM.push_back(tmp); 289 } 290 while(C.numMem.back() == 0 && CM.size() != 1) 291 //如果只剩下0,那还是要保留0 292 C.numMem.pop_back(); 293 return C; 294 } 295 296 BigIntNums operator*(const BigIntNums &A, const BigIntNums &B) 297 { 298 BigIntNums C; 299 C.npFlag = true; 300 301 if (A.npFlag == false && B.npFlag == true 302 || A.npFlag == true && B.npFlag == false) 303 C.npFlag = false; 304 305 if (abs(A) < abs(B)) 306 return B*A; 307 308 if (A == 0 || B == 0) 309 return BigIntNums(0); 310 311 const std::vector<int> &AM = A.numMem, &BM = B.numMem; 312 std::vector<int> &CM = C.numMem; 313 314 int up = 0, tmp; 315 316 for (int i = 0; i < AM.size();i++,up = 0) 317 { 318 for (int j = 0; j < BM.size();j++) 319 { 320 tmp = AM[i] * BM[j] + up; 321 if (i + j < CM.size()) 322 { 323 up = (tmp + CM[i + j]) / BigIntNums::gap_; 324 CM[i + j] = (tmp + CM[i + j]) % BigIntNums::gap_; 325 } 326 else 327 { 328 up = tmp / BigIntNums::gap_; 329 CM.push_back(tmp % BigIntNums::gap_); 330 } 331 } 332 if (up) 333 CM.push_back(up); 334 } 335 return C; 336 } 337 338 BigIntNums operator/(const BigIntNums &A, const BigIntNums &B) 339 { 340 int base_Count = static_cast<int>(log10(BigIntNums::gap_)); 341 342 if (abs(A) < abs(B)) 343 return BigIntNums(0); 344 BigIntNums C; 345 C.npFlag = true; 346 347 if (A.npFlag == false && B.npFlag == true 348 || A.npFlag == true && B.npFlag == false) 349 C.npFlag = false; 350 351 int base_Map, tmp; 352 std::vector<int> rCM; 353 std::vector<int> &CM = C.numMem; 354 const std::vector<int> &AM = A.numMem, &BM = B.numMem; 355 BigIntNums dividend = 0, divisor; 356 auto CM_Iter = CM.rbegin(); 357 358 for (int i = AM.size() - 1; i >= 0;) 359 { 360 do { 361 dividend *= static_cast<int>(pow(BigIntNums::base_, base_Count)); 362 dividend += AM[i--]; 363 } while (dividend < B && i >= 0); 364 365 tmp = 0; 366 for (int j = base_Count - 1;j >= 0;j--) 367 { 368 for (int k = BigIntNums::base_ - 1;;k--) 369 { 370 base_Map = static_cast<int>(pow(BigIntNums::base_, j)) * k; 371 BigIntNums y = abs(B) * BigIntNums(base_Map); 372 if (y <= dividend) 373 break; 374 } 375 dividend -= abs(B) * BigIntNums(base_Map); 376 tmp += base_Map; 377 } 378 rCM.push_back(tmp); 379 } 380 for (auto i = rCM.crbegin();i != rCM.crend();++i) 381 CM.push_back(*i); 382 while (C.numMem.back() == 0 && CM.size() != 1) 383 C.numMem.pop_back(); 384 385 return C; 386 } 387 388 BigIntNums operator%(const BigIntNums &A, const BigIntNums &B) 389 { 390 auto ret = A / B; 391 return A - ret*B; 392 } 393 394 BigIntNums &BigIntNums::operator++() 395 { 396 *this = *this + BigIntNums(1); 397 return *this; 398 } 399 400 BigIntNums &BigIntNums::operator--() 401 { 402 *this = *this - BigIntNums(1); 403 return *this; 404 } 405 406 BigIntNums &BigIntNums::operator=(const BigIntNums &ob) 407 { 408 if (&ob != this) 409 { 410 this->numMem = ob.numMem; 411 this->npFlag = ob.npFlag; 412 } 413 return *this; 414 } 415 416 BigIntNums &BigIntNums::operator+=(const BigIntNums &ob) 417 { 418 *this = *this + ob; 419 return *this; 420 } 421 422 BigIntNums &BigIntNums::operator-=(const BigIntNums &ob) 423 { 424 *this = *this - ob; 425 return *this; 426 } 427 428 BigIntNums &BigIntNums::operator*=(const BigIntNums &ob) 429 { 430 *this = *this * ob; 431 return *this; 432 } 433 434 BigIntNums &BigIntNums::operator/=(const BigIntNums &ob) 435 { 436 *this = *this / ob; 437 return *this; 438 }
标签:
原文地址:http://www.cnblogs.com/Philip-Tell-Truth/p/5738966.html