Re: Integer Base Function
"Earl Purple" wrote:
I did. Probably around the same time as you were writing your post.
I also incorporated many of Frederick Gotham's nifty tips.
Yep, that's what I did.
Here's my updated version of my Base<>() function:
// Put this in a header file:
namespace YourNamespaceNa me
{
///////////////////////////////////////////////////////////////////////////
// //
// Base //
// Represent an integer in any base from 2 to 36. //
// //
///////////////////////////////////////////////////////////////////////////
template<typena me 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_li mits<T>::max() - 5;
T const min = std::numeric_li mits<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] = "0123456789ABCD EFGHIJKLMNOPQRS TUVWXYZ";
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 YourNamespaceNa me
--
Cheers,
Robbie Hatley
Tustin, CA, USA
lonewolfintj at pacbell dot net
(put "[usenet]" in subject to bypass spam filter)
"Earl Purple" wrote:
Robbie Hatley wrote:
>
>
so if you like templates so much, and since your code is all inlined
anyway, why not make the function a template on its integral type?
>
But there are certain features of C++ which I love so much that
I rarely use C anymore, except for firmware or tiny utility apps:
namespaces
std containers
std::string
std algorithms
std iterators
parameterized constructors
templates
functors
I rarely use C anymore, except for firmware or tiny utility apps:
namespaces
std containers
std::string
std algorithms
std iterators
parameterized constructors
templates
functors
so if you like templates so much, and since your code is all inlined
anyway, why not make the function a template on its integral type?
I also incorporated many of Frederick Gotham's nifty tips.
You can use numeric_limits to find out some of the information you need
about what type you have.
about what type you have.
Here's my updated version of my Base<>() function:
// Put this in a header file:
namespace YourNamespaceNa me
{
///////////////////////////////////////////////////////////////////////////
// //
// Base //
// Represent an integer in any base from 2 to 36. //
// //
///////////////////////////////////////////////////////////////////////////
template<typena me 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_li mits<T>::max() - 5;
T const min = std::numeric_li mits<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] = "0123456789ABCD EFGHIJKLMNOPQRS TUVWXYZ";
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 YourNamespaceNa me
--
Cheers,
Robbie Hatley
Tustin, CA, USA
lonewolfintj at pacbell dot net
(put "[usenet]" in subject to bypass spam filter)
Comment