-1

When converting strings to long double I lose precision in QNX. Do you know how to fix this problem?

I am using c++. I have tried double and float and there were no problems.

#include <iostream>
#include <string>
#include <limits>
#include <sstream>

int main(){
    long double originalNumber = std::numeric_limits<long double>::max() / 2;
    long double convertedNumber;

    // From long double to string
    std::ostringstream ostr;
    ostr << originalNumber;
    std::string tmp_str = ostr.str();

    //From string to long double
    std::istringstream istr(tmp_str);
    istr >> convertedNumber;

    // Check if they are similar
    if (originalNumber == convertedNumber)
        std::cout<< "The same\n";
    else
        std::cout<< "Not the same\n";

    return 0;
}

The result is always Not the same

I. Hamad
  • 307
  • 2
  • 14
  • 1
    You'll need to [use `std::setprecision`](https://en.cppreference.com/w/cpp/io/manip/setprecision) to actually output enough precision to have a hope of exactly reproducible values. That said, near the bounds of representable `double`s, I wouldn't be surprised if there was still some loss. – ShadowRanger Dec 28 '18 at 12:26

1 Answers1

3

This is due to the fact that ostr << originalNumber; use the default format for floating point numbers, which is the scientific notaiton for numbers that big.

#include <iostream>
#include <limits>

int main()
{
    long double const originalNumber = std::numeric_limits<long double>::max() / 2;
    std::cout << originalNumber << '\n'; // 5.94866e+4931
}

Live demo

When you parse that representation back into a floating point number, all the following digits are lost. In fact, if you look at the orders of magnitude:

  • originalNumber is about 1e4931;
  • originalNumber - convertedNumber is about 1e4925.

This means only the first 6 (4931-4925) digits of originalNumber are right; which makes sense if you use the scientific notation.

The solution is std::fixed as stated in the SO question "How do I print a double value with full precision using cout?":

ostr << std::fixed << originalNumber;
// ...
if (originalNumber == convertedNumber) // true
    std::cout<< "The same\n";
else
    std::cout<< "Not the same\n";

Live demo

Beware though, floatting-point mathematic can appear to be broken and comparing two floatting-point numbers with == is often not a good choice.

YSC
  • 38,212
  • 9
  • 96
  • 149