Truncated Char in C++

I'm working with a float value like: -44.397217  and trying to process it with cout.  My float seems to get truncate to -44.3972 somewhere along the way.

Here is the code:

float y=-44.397217;
    std::ostringstream ss;
     ss << y;
  std::string str = ss.str();
    cout << str << endl;

  char digits[10];
  std::strcpy( digits, str.c_str() );
  std::cout << digits << std::endl;

Open in new window

Do you see the issue?

Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

float is likely 64 bits on your platform. Change to double to get more bits. IIRC, float can only hold about 6-1/2 decimal digits.
christamccAuthor Commented:
I think the float is fine, when it is traced we can see that it gets lost at the str.

I found this info:
"It is impossible to accurately represent a base 10 decimal number using base 2 values, except for a very small number of values (such as 0.25). To get what you need, you have to switch from the float/double built-in types to some kind of decimal number package."

Does that sound like the issue? Any idea on a decimal number package?

You have 8 decimal digits. You need to set the precision. This works:
     float y=-44.397217;  
    std::ostringstream ss;
    ss << (double)y;
    std::string str = ss.str();  
    std::cout << str << std::endl;

See ios_base::precision:

>> decimal number package
This is only needed if you cannot afford any rounding of your decimal digits. Most applications such as graphics and scientific algorithms can handle some small roundoff or truncation errors.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Exploring SharePoint 2016

Explore SharePoint 2016, the web-based, collaborative platform that integrates with Microsoft Office to provide intranets, secure document management, and collaboration so you can develop your online and offline capabilities.

>> ss << (double)y;
Change that to:
   ss << y;
Now consider:
   float y=-44.397217448;  
   std::ostringstream ss;

In this case, you do not get the desired result because float does not have enough bits to handle these 11 decimal digits. But if you change the float to a double, then you will get the correct result.
a 64-bit floating point type would have a precision of about 15 decimals. so the float is only 32 bit what is 6 to 7 decimals of precision. if your trace shows 8 digits then the last digit is random and the one before not precise. you could verify that by myultiplying or dividing by 10 and look at the trace again.

so you should use double as phoffric told you.

for outputting you could include <iomanip> and do like

std::cout << std::fixed  <<  std::setprecision(6) << dbl;

Open in new window

note, when using fixed or scientific, the argument to setprecision defines the number of digits after the decimalpoint. when you neither specify fixed or scientific the argument specifies the maximum digits of both sides of the decimal point.

see for more information.



In my first post, I meant to say double, not float, as in:

double is likely 64 bits on your platform. Change to double to get more bits. IIRC, float can only hold about 6-1/2 decimal digits.

I was surprised to see that for your specific example using
    float y=-44.397217;    // 8 decimal digits
that the results were good despite having more than 7 digits. You could try other 8 digit numbers to see if they all work using float.

But, as you have seen, in my example of:
    float y=-44.397217448;   // 11 decimal digits
you do lose the precision using float, and here, using double is necessary to retain all the decimal digits.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.