-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
convert to std::string #152
Comments
That is a good question. C++ does not make it particularly easy to convert user-defined integral types to hexadecimal string representation. But it can be done. In a first step, consider simply printing a #include <iomanip>
#include <iostream>
#include <math/wide_integer/uintwide_t.h>
int main()
{
using math::wide_integer::uint256_t;
uint256_t u = 0x12345677U;
u *= u;
u *= u;
u *= u;
std::cout << std::hex << std::uppercase << std::showbase << u << std::endl;
std::cout << std::hex << std::uppercase << std::showbase << (std::numeric_limits<uint256_t>::max)() << std::endl;
} As a second step, some developers use string-streaming to convert to string. But you also mention that you'd like a hexadecimal representation. As a second step, consider string-streaming. Look at the convenience template function #include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <math/wide_integer/uintwide_t.h>
template<typename T>
std::string hexlexical_cast(const T& u)
{
static_assert((std::numeric_limits<T>::is_specialized == true) && (std::numeric_limits<T>::is_signed == false),
"Error: This convenience template function is intended for unsigned types.");
std::stringstream strm;
strm << std::hex << std::uppercase << std::showbase << u;
return strm.str();
}
int main()
{
using math::wide_integer::uint256_t;
uint256_t u = 0x12345677U;
u *= u;
u *= u;
u *= u;
std::cout << hexlexical_cast(u) << std::endl;
std::cout << hexlexical_cast((std::numeric_limits<uint256_t>::max)()) << std::endl;
} Other variations are possible with different streaming flags, etc. There is also There is also a facility called The former idea is something that could potentially interest me. But for now, string-streaming might be a way to go... |
Thank you very much for the time and help! The examples is great. will investigate it.. |
Before leaving this example, there is another thing I occasionally do when converting big integers. On embedded platforms the weight of string-streaming can be too heavy. Although using raw pointers can be a bit, let's say, dangerous, I also occasionally use a self-written facility such as An example thereof is shown below. It extracts digits in a given base one digit at a time until the input integer is reduced via division to zero. It's conceptually a little bit like An implementation of #include <cstddef>
#include <cstdint>
#include <iomanip>
#include <iterator>
#include <iostream>
#include <sstream>
#include <string>
#include <math/wide_integer/uintwide_t.h>
namespace util {
template<typename UnsignedIntegerType,
typename OutputIterator,
const std::uint_fast8_t BaseRepresentation = 10U,
const bool UpperCase = true>
OutputIterator baselexical_cast(const UnsignedIntegerType& u, OutputIterator OutFirst)
{
using unsigned_integer_type = UnsignedIntegerType;
using output_value_type = typename std::iterator_traits<OutputIterator>::value_type;
unsigned_integer_type x(u);
std::ptrdiff_t index = 0;
do
{
for(std::ptrdiff_t j = index; j >= 0; --j)
{
*(OutFirst + (j + 1)) = *(OutFirst + j);
}
++index;
output_value_type c = (output_value_type) (x % (unsigned_integer_type) BaseRepresentation);
x = unsigned_integer_type(x / (unsigned_integer_type) BaseRepresentation);
if(c <= (output_value_type) 9)
{
c = (output_value_type) (c + (output_value_type) '0');
}
else if((c >= (output_value_type) 0xA) && (c <= (output_value_type) 0xF))
{
c = (output_value_type) ( (output_value_type) (UpperCase ? (output_value_type) 'A' : (output_value_type) 'a')
+ (output_value_type) (c - (output_value_type) 0xA));
}
*OutFirst = c;
}
while(x != 0U);
return (OutputIterator) (OutFirst + index);
}
} // namespace util
int main()
{
using math::wide_integer::uint256_t;
{
uint256_t u = 0x12345677U;
u *= u;
u *= u;
u *= u;
char pcr[128U] = { '\0' };
util::baselexical_cast<uint256_t, char*, 16U>(u, pcr);
std::cout << pcr << std::endl;
}
{
char pcr[128U] = { '\0' };
util::baselexical_cast<uint256_t, char*, 16U>((std::numeric_limits<uint256_t>::max)(), pcr);
std::cout << pcr << std::endl;
}
} |
While it might not be easy to extract, this |
Thank you John. Sorry I had not previously noticed your particular implementation. Do you also handle base(s) other than 10 such as the popular base-16? |
It doesn't but that should be pretty easy to implement. Might manage it over the holidays... |
Follow-up in #153 |
It wasn't nearly so easy as I thought but take a look back for a |
Greetings! Is it possible to convert uint to hex std::string ? I found the wr_string method, but how do I get a string from char*?
The text was updated successfully, but these errors were encountered: