Alex Buell said:
Is there an elegant way of converting strings containing digits
between different number bases in C++?
Below I present excerpts from some earlier posts of mine in this group around
July 2 to July 5 of this year, in which I give a function which prints any
integer up to nine quintillion in any base from 2 to 30.
That's not exactly what you asked for, but it's close. If you can
write the part that converts from any base to a basic 2's-compliment
C++ integer variable, then you can use my function to print the
representation of that integer in the base of your choice.
//============= BEGIN EXCERPTS FROM EARLIER POSTS =====================
// July 2-5:
....For your enjoyment, a function that expresses any integer with
absolute value less-than-or-equal-to nine quintillion in any
base from 2 to 36...
.... if you don't like the non-std type "long long" you can always
change it to "long"; but then it could only handle numbers up to
about 2 billion, instead of 9 quintillion...
// Put this in a header file:
namespace YourNamespaceName
{
///////////////////////////////////////////////////////////////////////////
// //
// Base //
// Represent an integer in any base from 2 to 36. //
// //
///////////////////////////////////////////////////////////////////////////
template<typename T>
std::string
Base
(
int base, // must be >= 2 and <= 36
int precision, // must be >= 1 and <= 63
T number, // must be >= min+5 and <= max-5 for type
bool leading_zeros = false // does user want leading zeros?
)
{
T const max = std::numeric_limits<T>::max() - 5;
T const min = std::numeric_limits<T>::min() + 5;
double largest = pow(base, precision) - 1;
if
(
base < 2 || base > 36 // If base is out-of-range
|| precision < 1 || precision > 63 // or precision is out-of-range
|| number < min || number > max // or number is out-of-range
|| largest > max // or base/precision combo is out-of-range
|| largest < number // or base/precision combo can't express number
)
{
return std::string("***ERROR***"); // then return "***ERROR***".
}
std::string repre = std::string("");
if (number < 0)
{
number = -number;
repre += '-';
}
T place = 1;
for (int i = 1; i <= precision - 1; ++i)
{
place *= base;
}
T value = 0;
const char digits[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
bool first_non_zero = false;
for ( ; place > 0; place /= base)
{
value = number / place;
if (value > 0) first_non_zero = true;
if (leading_zeros || first_non_zero) repre += digits[value];
number -= value * place;
}
return repre;
} // end Base()
} // end namespace YourNamespaceName
//============= END EXCERPTS FROM EARLIER POSTS =====================
--
Cheers,
Robbie Hatley
Tustin, CA, USA
lone wolf intj at pac bell dot net
(put "[usenet]" in subject to bypass spam filter)
home dot pac bell dot net slant earnur slant