Hello,

I have a problem with writing values of type double in pqxx. I've
already created a ticket (#116), but received no feedback. Maybe the
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.precision(41); // ADD THIS LINE
  S << Obj;
  string R;
  S >> R;
  return R;
}

-- 
Denis.
xmpp:[EMAIL PROTECTED]
_______________________________________________
Libpqxx-general mailing list
[email protected]
http://gborg.postgresql.org/mailman/listinfo/libpqxx-general

Reply via email to