Makka
Makka

Reputation: 264

C++ converting string to float/double without loss of data

I'm looking to convert a string to a float with out loss of data; for example if I use istringstream or ::atof(x.c_str()) I loose data due to rounding I guess.

Normally this isn't a issue for me but I'm using data that has to be the same as its read. Here's a example of a number and what it's converted to.

-8.000001 -> -8
-0.6257381 -> -0.625738
12.0 -> 12 (drops the .0) 

If anyone could help me out I'd be very grateful

Thanks Matt

Upvotes: 0

Views: 6413

Answers (3)

Ben Voigt
Ben Voigt

Reputation: 283901

You're going to need a different data type.

A floating-point decimal type will allow you to store the number exactly the way you want. In such a type, numbers are stored as a pair ( mantissa, exponent ) just like scientific notation and much like IEEE binary floating point.

Your examples would be stored as

(-8000001, -6)
(-6257381, -7)
(120, -1)

For example, the ISO 11073 standard for medical device communications uses such a format.

The downside is that arithmetic will be quite slow, since all the floating-point arithmetic hardware is designed to work with number using an exponent with base-2.

Upvotes: 1

Eric Postpischil
Eric Postpischil

Reputation: 224451

There are three potential issues in your question:

  1. The amount of precision displayed. To control the precision used, include #include <iomanip> and use std::cout << std::setprecision(17); to set the number of digits to use.

  2. Formatting. In the case of wanting “12.0” for “12.0”, you should be aware that “.0” is not stored in a float or double. The double just contains the value 12; it does not contain any information about the original precision or an error interval. It is exactly 12 and nothing else. If you want it formatted in a particular way, you must either use the format flags for the I/O stream or write your own code to do the formatting.

  3. Accuracy. The common float and double types cannot exactly represent 8.000001 or 0.6257381. They use binary to represent floating-point values, and there will be slight errors when decimal numerals are converted to binary. If you have very simple uses of floating-point and are working with significantly fewer digits than the limits of float and double, then you might be able to ignore this and simply format numbers with your limited numbers of digits. If you exceed simple cases, you would need to do error analysis, which can be quite complicated.

Upvotes: 5

Bathsheba
Bathsheba

Reputation: 234875

As a rule of thumb, a float is only precise to 6 significant figures. So if your string has more digits in that you'll hit the precision limit.

A double will give you, not surprisingly, about double this precision; i.e. 12 significant figures.

See Number of significant digits for a floating point type for further remarks.

Upvotes: 0

Related Questions