10 Aug 2007 14:38

## problem with writing large floating point values to postgres

```Hello,

I have a problem with writing values of type double in pqxx. I've
ticket was unclear, so I'll try to explain my problem.

The problem is that when writing large double values to iostream, it
is displayed in exponential form, omitting last digits. So, when this
number in exponental form converted back to double, it gets rounded
and significant digits is lost.

For example, if I do this:

std::cout << 12345678;

I'll get '1.23457e+007' on screen, and as you see - last two digits
were omitted and in fact, the number is rounded to '12345700'.
This can be fixed by specifying the precision to iostream library:

std::cout.precision(41);
std::cout << 12345678;

And this time, I'll get on screen the number I expected '12345678'.

Since pqxx::to_string/from_string uses std::stringstream for
converting double values, we face the problem that when I try to write
large 'double' to postgres, the number that is actually written is the
rounded one.

Here is the test application that uses pqxx::to_string/from_string

#include <iostream>
#include <string>
#include <pqxx/pqxx>

int main(int, char**)
{
std::stringstream ss;

const double orig_value = 12345678;
double value;

// converting double to string and vice versa
std::string str_value = pqxx::to_string(orig_value);
pqxx::from_string(str_value, value);

// using C-function
printf("printf:\n \torig = %f \n\tnew  = %f\n", orig_value, value);

// using iostream with default params
std::cout << std::endl << "cout: " << std::endl
<< "\torig = " << orig_value << std::endl
<< "\tnew  = " << value << std::endl;

// using iostream and manually specifying the floating value precision
std::cout.precision(41);
std::cout << std::endl << "cout with precision: " << std::endl
<< "\torig = " << orig_value << std::endl
<< "\tnew  = " << value << std::endl;
return 0;
}

And its output:

printf:
orig = 12345678.000000
new  = 12345700.000000

cout:
orig = 1.23457e+007
new  = 1.23457e+007

cout with precision:
orig = 12345678
new  = 12345700

As you can see, after using to_string/from_string the number becomes incorrect.

This problem can be fixed by adding the following line to function
'to_string_fallback' in util.cxx

template<typename T> inline string to_string_fallback(T Obj)
{
stringstream S;
#ifdef PQXX_HAVE_IMBUE
S.imbue(locale("C"));
#endif
S << Obj;
string R;
S >> R;
return R;
}

--

--
Denis.