Well, as you said, there are two options, if you care about readability and need to print doubles then:
Method 1: (readable)
#include <limits>
void double_to_string(double the_double, int offset_to_max)
{
typedef std::numeric_limits<double> doublelimit;
// ready to transfer
std::cout.precision(doublelimit::digits10 + offset_to_max);
std::cout << the_double << std::endl;
}
// Back to double
double cstring_to_double(const char *s)
{
return std::atof(s);
}
int main(int argc, char *argv[]) {
double the_double = 0.10000000000000002;
//double the_double = 0.1;
int offset = 2;
double_to_string(the_double, offset);
}
This way, doubles printed will have aliasing using full precision (17). I recomend using 17 since the default will always try to round. Either way, a full correct print using this method will require a more powerful library.
Method 2: (binary)
Just memcpy the value, using and int64 is fine, double can store 53 bits max:
template<typename T, typename H = int64_t>
H write_data(T x)
{
H i;
// Can we hold the data?
if (sizeof(T) > sizeof(H)) assert(false); // or write some error procesing
// Now take the lower size of the two.
memcpy(&i, &x, sizeof(H) > sizeof(T) ? sizeof(T) : sizeof(H));
return i;
}
// union version
template<typename T, typename H = int64_t>
H write_data_u(T x)
{
// Can we hold the data?
if (sizeof(T) > sizeof(H)) assert(false); // or write some error procesing
union {
T d;
H i;
} n;
n.d = x;
return n.i;
}
int main(int argc, char *argv[])
{
double the_double = 0.10000000000000001;
int64_t double_holder = write_data<double, int64_t>(the_double);
// Binary data as decimal string: ready to transfer the string, remember to convert to big_endian first if you transfer the binary representation.
std::cout << "double_as_int64:" << double_holder << std::endl;
// Back to double (we know int64_t holds a double so we dont care about the remaining bits)
double back_to_double = write_data<int64_t, double>(double_holder);
std::cout.precision(std::numeric_limits<double>::digits10 + 2);
std::cout << "back_to_double:" << back_to_double << std::endl;
}