Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // BigNum.h
- #pragma once
- #include <iostream>
- #include <string>
- #include <vector>
- #include <fstream>
- #include <sstream>
- #include <iterator>
- #include <bitset>
- #include <algorithm>
- #include <cstdint>
- class BigNum
- {
- public:
- BigNum() = default;
- BigNum(uint64_t input_base, std::string input_number);
- BigNum(uint64_t input_base, uint64_t input_number);
- uint64_t base = 0;
- std::vector<uint64_t> number{};
- protected:
- friend std::ostream& operator<<(std::ostream& output, const BigNum& bignum);
- private:
- };
- BigNum setup_number(std::string filename);
- BigNum add_numbers(BigNum& num1, BigNum& num2);
- std::string load_binary_number(std::string filename);
- BigNum multiply_numbers(BigNum& num1, BigNum& num2);
- BigNum to_decimal(BigNum& num);
- // BigNum.cpp
- BigNum::BigNum(uint64_t input_base, std::string input_number)
- {
- if (input_base > 1)
- {
- base = input_base;
- for (auto digit : input_number)
- {
- if (digit >= 48 && digit <= 57)
- {
- number.push_back(digit - static_cast<uint64_t>('0'));
- }
- else if (digit >= 65 && digit <= 70)
- {
- number.push_back(digit - static_cast<uint64_t>('A') + 10);
- }
- else if (digit >= 97 && digit <= 122)
- {
- number.push_back(digit - static_cast<uint64_t>('a') + 10);
- }
- else
- {
- std::cout << "error: BigNum constructor: invalid digit";
- exit(0);
- }
- }
- }
- }
- BigNum::BigNum(uint64_t input_base, uint64_t input_number) :
- BigNum(input_base, std::to_string(input_number))
- {
- }
- std::ostream& operator<<(std::ostream& output, const BigNum& bignum)
- {
- int A = 10, Z = 35, a = 36, z = 61;
- for (auto digit : bignum.number)
- {
- if (digit >= A && digit <= Z)
- {
- output << (static_cast<char>(digit - 10 + 'A'));
- }
- else if (digit >= a && digit <= z)
- {
- output << (static_cast<char>(digit - 36 + 'a'));
- }
- else
- {
- output << digit;
- }
- }
- return output;
- }
- BigNum setup_number(std::string filename)
- {
- std::ifstream input_file;
- input_file.open(filename, std::ios::binary);
- if (!input_file)
- {
- std::cout << "Failed to open file" << std::endl;
- exit(0);
- }
- std::stringstream binary_string;
- std::istreambuf_iterator<char> in(input_file), in_end;
- std::ostream_iterator<std::bitset<8>> out(binary_string, "");
- std::copy(in, in_end, out);
- BigNum number{ 2 , binary_string.str() };
- return number;
- }
- std::string load_binary_number(std::string filename)
- {
- std::ifstream input_file;
- input_file.open(filename, std::ios::binary);
- if (!input_file)
- {
- std::cout << "Failed to open file" << std::endl;
- exit(0);
- }
- std::stringstream binary_string;
- std::istreambuf_iterator<char> in(input_file), in_end;
- std::ostream_iterator<std::bitset<8>> out(binary_string, "");
- std::copy(in, in_end, out);
- return binary_string.str();
- }
- BigNum add_numbers(BigNum& num1, BigNum& num2)
- {
- BigNum result{};
- if (num1.base == num2.base)
- {
- result.base = num1.base;
- }
- else
- {
- return result;
- }
- auto it1 = num1.number.rbegin();
- auto it2 = num2.number.rbegin();
- uint64_t carry = 0;
- while (it1 != num1.number.rend() || it2 != num2.number.rend())
- {
- uint64_t n1 = (it1 != num1.number.rend()) ? *it1++ : 0;
- uint64_t n2 = (it2 != num2.number.rend()) ? *it2++ : 0;
- uint64_t temp = n1 + n2 + carry;
- carry = 0;
- if (temp > num1.base - 1)
- {
- temp = temp % num1.base;
- carry = 1;
- }
- result.number.push_back(temp);
- }
- if (carry == 1)
- {
- result.number.push_back(1);
- }
- std::reverse(result.number.begin(), result.number.end());
- return result;
- }
- BigNum multiply_numbers(BigNum& num1, BigNum& num2)
- {
- BigNum result{};
- if (num1.base == num2.base)
- {
- result.base = num1.base;
- }
- else
- {
- return result;
- }
- auto it1 = num1.number.rbegin();
- uint64_t add_zeroes = 0;
- while (it1 != num1.number.rend())
- {
- auto it2 = num2.number.rbegin();
- BigNum number{};
- number.base = num1.base;
- uint64_t base = num1.base;
- uint64_t digit = 0;
- uint64_t carry = 0;
- while (it2 != num2.number.rend())
- {
- auto tmp = *it1 * *it2 + carry;
- digit = tmp % base;
- carry = tmp / base;
- number.number.push_back(digit);
- it2++;
- }
- if (carry != 0)
- {
- number.number.push_back(carry);
- }
- std::reverse(number.number.begin(), number.number.end());
- for (uint64_t i = 0; i < add_zeroes; i++)
- {
- number.number.push_back(0);
- }
- add_zeroes++;
- result = add_numbers(result, number);
- it1++;
- }
- return result;
- }
- BigNum to_decimal(BigNum& num)
- {
- BigNum result;
- result.base = 10;
- BigNum power{ 10, 1 };
- BigNum base{ 10, num.base };
- auto it = num.number.rbegin();
- while (it != num.number.rend())
- {
- BigNum tmp{ 10, *it };
- BigNum temp = multiply_numbers(power, tmp);
- result = add_numbers(result, temp);
- power = multiply_numbers(power, base);
- it++;
- }
- return result;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement