2

std::istringstream loses precision when converting a string to long double. Can I use something similar to std::fixed or std::setprecision()?

I am using c++ 11 and targeting QNX platform.

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>

int main(){
    long double convertedNumber;
    std::string numberString ("5.94865747678615882510631e+4931");

    //From string to long double
    std::istringstream iss(numberString);
    iss >> convertedNumber;

    std::cout<< std::setprecision(30) << numberString << "\n";
    std::cout<< std::setprecision(30) << convertedNumber << "\n";

    return 0;
}

The output is

5.94865747678615882510631e+4931
5.9486574767861588254e+4931
I. Hamad
  • 307
  • 2
  • 14

2 Answers2

6

The issue you're having has nothing to do with your use of setprecision or streams.

An 80-bit double (long double) is not large enough to store the number you're trying to store with the precision you want. 80-bit doubles have a mantissa of 64 bits, meaning the precision of numbers it can represent is the same as a 64-bit integer, which itself is limited to 19 [decimal] digits of value. The value you're trying to store is (5.9486_57476_78615_88251_0631) 24 decimal digits of value, meaning it's simply too precise to be accurately represented by your program.

If you want to store this value in your program, you need to keep it in its string representation or find an arbitrary precision library for representing/manipulating these numbers. My recommendation is to use the boost.multiprecision library, though it does depend on your organization/task permitting use of the C++ Boost Libraries.

Xirema
  • 19,889
  • 4
  • 32
  • 68
  • Is there a flag to set when compiling to prevent the OS from using this type of registers @Xirema?. – I. Hamad Jan 02 '19 at 09:14
  • @H.Ilyas I'm not sure what you mean by that. `long double` normally falls back to a 64-bit floating point value if the Environment doesn't support 80-bit floats. So even if that kind of flag exists (which it probably does, for binary compatibility), it wouldn't solve your issue. – Xirema Jan 02 '19 at 14:59
  • I'm looking for something like `-ffloat-store`. But as you said, they don't change anything. I have tried other flags also. – I. Hamad Jan 02 '19 at 16:07
0

Yes it will work, these are functions which are used for any stream. a stream is a construct for receiving and sending of bytes A stream uses the

<< Insertion operator

And the >> extraction operator

The std::setprecision function is a stream manipulator which can be applied for any stream EDIT if your question is why its not at a precision of 30, its because you lost precision when doing

iss >> convertedNumber;

And the iss stream is the most precise number according to your input. Stick to the answer of Xirema for a more technical explanation and solution

Mikdore
  • 699
  • 5
  • 16
  • 2
    This answer is correct. However, this is a link-only answer. Could you please elaborate a little more so that the answer is self-contained and the link is only optional additional information ? – Christophe Dec 28 '18 at 15:29
  • 1
    @LightnessRacesinOrbit It is not clear what 'should work fine' means. OP is having an issue, where it doesn't work for them. If the problem can't be reproduced, question should be closed, otherwise, answer should explain how to achieve desired result, rather than stating that it should work. – SergeyA Dec 28 '18 at 15:35
  • @Christophe I do not agree that this answer is correct. – SergeyA Dec 28 '18 at 15:35
  • @SergeyA You're right, I missed that the code in the question _is_ the attempt. I thought they were asking whether they could use setprecision in some other code not relating to cout. It's a bit muddled IMO. – Lightness Races in Orbit Dec 28 '18 at 15:38
  • @SergeyA the answer is right in that it is perfectly valid to use setprecision() on an istream. It states nothing about guarantees the standard makes (i.e. the input is not truncated to the precision), but the OP is not very clear about the expecations from setprecision() on input. – Christophe Dec 28 '18 at 15:49
  • I think it should be fixed now, any other improvements? – Mikdore Dec 28 '18 at 15:49