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.
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.
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/
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.
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;
}
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;
}
}
精彩评论