Scrungepipes
Scrungepipes

Reputation: 37581

How to increment a 64 bit number when the OS only supports 32?

I have a number stored as a string up to 16 chars (0 to F) in length. This needs to be incremented and the result stored as a string.

Simplest thing would have been to convert the string to an int, increment by one, then convert back to a string. However the OS doesn't support 64 numbers. What's the alternative?

I presume a hand crafted solution using two 32 bit integers is possible, in which case this must be a common scenario, but I couldn't find any boilerplate template code for doing such a thing after a bit of googling.

UPDATE: Sorry - sould have mentioned earlier - This is for Brew MP C++ - their conversion libraries' APIs are limited to 32 bit.

And experimenting with long long seems to have fundamental big time problems in general executing on hardware, making it unusable.

Upvotes: 3

Views: 600

Answers (5)

Jonathan Dickinson
Jonathan Dickinson

Reputation: 9218

This is hand-ported from some C# I wrote (without a C++ compiler) - so you may need to tweak it. This works against a low/high type struct.

struct VirtInt64
{
    unsigned int Low;
    unsigned int High;
};

void Increment(VirtInt64* a)
{
    var newLow = a->Low + 1;
    if (newLow < a->Low)
    {
        a->Low = 0;
        a->High = a->High + 1;
    }
    else
    {
        a->Low = newLow;
    }
}

Upvotes: 0

fredoverflow
fredoverflow

Reputation: 263128

Here is the solution suggested by @Mark in C++:

template<typename Iter>
void increment(Iter begin, Iter end)
{
    for (; begin != end; ++begin)
    {
        ++*begin;
        if (*begin == 'G')
        {
            *begin = '0';
            continue;
        }
        if (*begin == ':')
        {
            *begin = 'A';
        }
        break;
    }
}

Remember to call it with reverse iterators, so the string gets incremented from right to left:

int main()
{
    std::string x = "123456789ABCDEFF";
    increment(x.rbegin(), x.rend());
    std::cout << x << std::endl;
    x = "FFFFFFFFFFFFFFFF";
    increment(x.rbegin(), x.rend());
    std::cout << x << std::endl;
}

Upvotes: 1

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361412

Include <cstdint> and use int64_t or uint64_t. You can use them even on 32-bit machines. All that you need a modern compiler.

Upvotes: 3

Mark Ransom
Mark Ransom

Reputation: 308168

You can increment one digit at a time. If the digit is between '0' and '8', just add one; likewise if it's between 'A' and 'E'. If it's '9', set it to 'A'. If it's 'F', set it to '0' and increment the next digit to the left.

Upvotes: 11

Eric J.
Eric J.

Reputation: 150108

Your compiler doesn't support a 64-bit long?

You can use a variety of libraries to support arbitrary width integers such as http://gmplib.org/

Upvotes: 3

Related Questions