Вам понадобится поддержка из большой целочисленной библиотеки. Но только крошечная его часть. Такая маленькая часть, что мы можем реализовать ее вместе.
Во-первых, давайте немного изменим ваш код, чтобы сделать его управляемым:
#include <iostream>
#include <cstdlib>
#include <vector>
std::vector<short> genArr(int bits)
{
std::vector<short> numArr(bits);
srand(time(0));
int i;
for (i = 0; i<bits; i++)
{
numArr[i] = rand() % 2;
}
return numArr;
}
void formatNum(std::vector<short> arr)
{
int i;
for (i = 0; i<arr.size(); ++i)
{
std::cout<<arr[i];
}
std::cout<<"\n";
}
Практически то же самое, что и раньше, только используя векторы . Затем вы можете просто реализовать очень высокоуровневый logi c, предполагая, что у вас есть большая библиотека int:
void formatNumDec(std::vector<short> arr)
{
LargeNum n;
for(int i = 0; i < arr.size(); i++)
{
n = n * 2;
if (arr[i])
{
++n;
}
}
std::cout << n << std::endl;
}
Все, что мы сделали: для каждого di git умножаем текущее значение на 2 , затем добавьте ноль или единицу, в зависимости от следующего бита.
Мы полагались на:
- оператор присваивания
- оператор увеличения
- оператор звездочки (для умножения)
Давайте использовать это:
class LargeNum
{
public:
int base;
std::vector<int> digits;
мы получаем оператор присваивания по умолчанию. Давайте добавим конструктор:
LargeNum():base(10) {}
Давайте реализуем инкремент, добавив единицу к последнему di git и перенеся его. Это работает только для небольшого значения, но 1
- это небольшое значение.
LargeNum& operator++()
{
int pos = 0;
bool carry = false;
do
{
carry = false;
if (pos >= digits.size())
{
digits.push_back(0);
}
digits[pos]++;
if (digits[pos] == base)
{
digits[pos] = 0;
carry = true;
}
}
while(carry);
return *this;
}
И последний бит, который нам нужен, это умножение на 2. Давайте реализуем умножение на любое маленькое значение (скажем, от 1 до 10) на умножение каждого di git и перенос:
LargeNum& operator*(int mult)
{
int carry = 0;
for(int pos = 0; pos < digits.size(); pos++)
{
digits[pos] = digits[pos] * mult + carry;
carry = digits[pos] / 10;
digits[pos] %= 10;
}
if (carry)
{
digits.push_back(carry);
}
return *this;
}
};
Это дает нам решение с использованием большой целочисленной библиотеки, которая работает в очень ограниченных случаях. Но достаточно для вашего случая использования. Если протестировать:
int main()
{
auto num = genArr(13);
formatNum(num);
formatNumDec(num);
}
, мы получим:
1100011100011
6371(10)
или, с большими значениями:
1101110010011010101101000111001011011010010001110000101101011000011111001011010101011111001010111011111001110100110110111101000101001111000000110000000111111000010110101100110100111001101101101111010011001100111011001101110000100010110010010101111100101110000101000110111101000101001100001110001010111110101001111101111100010110011111111111010100010110000010001000001001000010111010101100111000001000000100101010111111110100110101001111101100000100001000010011111011011100111101011011111000001111001001011011010111101101000101000101100111001000111100010001001010101110101001110001110000011101000001010010001110011110100000011111100011001010111111101010100011010000011100100110001001111110010011110001011111101111001010000000101000010100010000110101000111100001001111011110111111000100100010000011111000001111110001111011011000100101111101111111100011111001101100001011100111111011011010111111001100001110011100101001101011111011101000110001110010000010010111110101001111111111100010000110011111010010011
73868569780955456124228707899822160955495544892638015310179220061186136753214543146234756723216826639708631800432713243173835264416984333326210886331495933792989604726456910722925688428304932474264611559781633323648147423739204040611247483503242836728251464923462071095422092950093094774327508960755347(10)
Я не беспокоился, в каком направлении (из наименьший или наибольший di git, который вы обрабатывали в своем двоичном файле. Отрегулируйте его соответствующим образом).