th3g3ntl3man
th3g3ntl3man

Reputation: 2106

C++ - Convert vector<uint64> to a single number

There is a method to convert a std::vector<uint64> to a single number?

I have a vector like this:

v[0] = 0;
v[1] = 6796890219657246832;

Or like this:

v[0] = 16377;
v[1] = 2631694347470643681;
v[2] = 11730294873282192384;

The result I like to get is, in the first case 6796890219657246832 and in the second: 16377263169434747064368111730294873282192384. My main problem is choosing the data type for the value as it is possible that the vector size is not always 2 but it could be 5 or higher.

Upvotes: 1

Views: 309

Answers (3)

jignatius
jignatius

Reputation: 6474

The Boost.Multiprecision library can be used for computations with very large numbers. This will do what you want using that library:

#include <boost/multiprecision/cpp_int.hpp>
#include <vector>
#include <cstdint>
#include <iostream>

namespace mp = boost::multiprecision;

mp::cpp_int add_numbers(const std::vector<uint64_t> &numbers)
{
    mp::cpp_int sum = 0;
    size_t digits = 0;
    
    for (std::vector<uint64_t>::const_reverse_iterator it = numbers.crbegin(); it != numbers.crend(); ++it)
    {
        mp::cpp_int num(*it);
        sum += num * mp::pow(mp::cpp_int(10), digits);
        digits += num.str().size();
    }
    
    return sum;
}

int main() {
    std::vector<uint64_t> numbers = {16377U, 2631694347470643681U, 11730294873282192384U};
    mp::cpp_int sum = add_numbers(numbers);
    std::cout << sum << std::endl;
}

Output:

16377263169434747064368111730294873282192384

Live demo

Upvotes: 1

Marshall Clow
Marshall Clow

Reputation: 16670

use std::accumulate and generate a string.

std::string result = std::accumulate (
         v.begin(),
         v.end(),
         std::string(),
         [](const std::string &result, const uint64 &val) {
             return result + std::to_string(val); }
         );

Upvotes: 0

Ghasem Ramezani
Ghasem Ramezani

Reputation: 2888

No C++ provided types will support that many digits. So obviously, you need BIG-INT for that. Ethier implemented by yourself or using a tested library like GMP.

For example, using GMP will be like:

static mpz_class convert_to_i(std::vector<std::size_t> const& vec)
{
        std::string sum;
        for (auto const number : vec) {
                sum += std::to_string(number);
        }
        return mpz_class(sum);
}

Let the vec be:

std::vector<std::size_t> const vec = {
        16377,
        2631694347470643681,
        1173029487328219238
};

Result of convert_to_i(vec) will be:

1637726316943474706436811173029487328219238

If your original numbers are also big-int:

static mpz_class convert_to_i(std::vector<mpz_class> const& vec)
{
        std::string sum;
        for (auto const& number : vec) {
                sum += number.get_str();
        }
        return mpz_class(sum);
}

Let the vec_2 be:

std::vector<mpz_class> const vec_2 = {
        mpz_class("26316943474706436812631694347470643681"),
        mpz_class("263169434747064368126316943474706436812631694347470643681")
};

Result of convert_to_i(vec_2) will be:

26316943474706436812631694347470643681263169434747064368126316943474706436812631694347470643681

Just for copy/paste and test: the code.

Upvotes: 4

Related Questions