Why string-to-float conversion may not work? [duplicate] - c++

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Precision of Floating Point
Can you compare floating point values exactly to zero?
floating point issue
In my c++ code I have the string: "0.55".
And I want to convert it to float value "0.55", but all function I used give me the float value "0.55000001".
Why? How can I take the clear value?
Last version of code is:
wstring s = L"0.55";
float f = stof(s);

Floats are not exact. This is because there are infinite number of possible values, but only finite number of bits to represent them!
So because 0.55 cannot be represented, it gives you the value 0.55000001 instead.
More info can be found in: what every programmer should know about floating points arithmetics

0.55 does not have an exact binary representation. There will always be some rounding errors.

There is no float value 0.55 - the format cannot represent that value.
Read the Floating-Point Guide for a detailed explanation.
If you need an exact representation for decimal fractions, use a decimal format, such as provided by the GMP library.

you can use a little algebra and you will get 0.55
wstring s = L"0.55";
float f = stof(s);
use floor function
f = floor(f);

Related

How to convert string to double or float without loosing precision in C++ [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 2 years ago.
I am trying to convert a string to a double or float in C++, but the result is not exact. For example:
double d1 = stod("2.16"); //d1 ends up being 2.1600000000000001
float f1 = stof("2.16"); //f1 ends up being 2.16000009
Is it possible to convert "2.16" to the actual value 2.16 ( 2.16000000 float or 2.1600000000000000 double) using C++ libraries?
I need the exact values for some calculations so I don't need it to be printed as 2.16, I need the exact number.
How to convert string to double or float without loosing precision in C++
By only converting values that can be represented precisely in the target type.
Is it possible to convert "2.16" to the actual value 2.16 (float or double)
No, because the actual value 2.16 doesn't exist in those types (assuming binary IEEE-754 representation). The best that can be achieved is to convert to a representable value that is closest to 2.16.
I need the exact values for some calculations
If this is true, then you need to not use floating point numbers. Floating point can only be used when errors in accuracy are acceptable.
can I at least get conversion which is not smaller than the original nubmer
You indeed can, if you set the rounding mode accordingly:
std::fesetround(FE_UPWARD);

How do I round double value to 2 decimal places in C++? [duplicate]

This question already has answers here:
Rounding to 2 decimal points [duplicate]
(3 answers)
Closed 4 years ago.
Let's say I have some calculations as below:
double a = 99.44, result;
result = 99.44 / 100 * 99.5;
The value stored in result will be 98.9428. How do I round the value into 98.94 and store into "result" ?
The setprecision method only can round the value during cout, but I want the value stored to be rounded for further calculations.
You can use the following algorithm:
multiply with 100
round to nearest integer
divide by 100
This algorithm has problems with big values that are very close to maximum representable as the multiplication may overflow.
Another approach is to use the stream manipulators as you would with std::cout but stream into a string, and then convert that string back into a floating point number. This is much slower, but has no caveat mentioned above.
You can't. Floating-point variables don't have decimal places: they have binary places, which are incommensurable with decimal places.
If you want decimal places, you have to use a decimal radix, e.g. when formatting for output.

exponential value restriction in Float variable in C++

I want my answer in some precision form but not for input output purposes.
float a = cos ( 90*(PI/180)) gives 1.794897E-09
where as I want up to 8 decimal places answer in my variable which will give
0.00000000
setprecision or other methods are not helping to store the value in a variable. How can it be stored? basically it may not even be 8 or 9 digits .. all i want is restriction of an exponentiol form in my answer
You are limited by the type you are using. A single precision float can only represent between 6 and 9 significant decimal digits.
https://en.wikipedia.org/wiki/Single-precision_floating-point_format
Remember, a float is not a decimal value. So what you're seeing is the decimal representation. If you want more digits in the decimal representation, use a double.
https://en.wikipedia.org/wiki/Double-precision_floating-point_format
Double precision floats can represent values to 15-17 digits of decimal precision. This should guarantee the minimum of 8 that you require.
The precision and encoding of floating point values is concretely defined by IEEE 754. Without defining your own implementation of of floating points should be stored in memory, you can't really change the internal precision for how it's encoded and stored in memory.
If you want better precision you can use doubles. All the math functions work well with doubles.

Dividing two floats doesn't give exact result [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 9 years ago.
I had divided 9501/100.0f expecting to get result of 95.01f, but for some deviant reason the result was 95.01000000002f.
I am aware of rounding errors and also that dividing two bigger floats can give improper result, but these two numbers are relative small, and they should not give bad answer.
I have changed floats to doubles, only to see the same result.
So my answer is, why am I seeing this false output?
And eventually workaround without copying number to string and back.
Floating point numbers are not precise, and dealing with them has lots of idiosyncrasies.
What Every Computer Scientist Should Know About Floating-Point Arithmetic
I also enjoy Bruce Dawson's blog entries on floating point values.
Floating point numbers are numbers represented in binary with limited precision.
The error between expected result and actual result is caused by the fact, that the number 95.01 is infinitely periodical in binary representation.
Double has only 51 binary digits, thus there has to be some rounding before the number is stored in the double precision. Single precision has only 23 digits.
It is not possible to represent 95.01 in finite precision floatin point number without any error.
However, you may trust the first 6-9 decimal digits, thus you should format the number with some meaningfull format.
Ahh good, another one of us has become a man in the church of programming :)
Floating points are not exact, the precision will vary from machine to machine. 1.0f != 1.00000000000000000000000000000000000 and so on, it's more like 1.0000001002003400011 and so on (I just picked arbitrary numbers here).

Rounding problem with double type [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why don't operations on double-precision values give expected results?
I am experiencing a peculiar problem in C++. I created a variable of type Double. Then I did some calculations with some values assigned to other variables and assigned the result to the double variable I declared. It gave me a result with a long decimal part. I want it to round to only 2 decimal places. and store it into the variable. But even after several attempt rounding, I couldnt round it to 2 decimal places.
Then I tried another way to check what the real problem is. I created a Double variable and assigned it the value 1.11. But when I debugged it by putting a break point and added a watch for that variable, I could find that the value now stored in the variable is 1.109999999999.
My question is, why is it showing like that? Isnt there any way in which we can round the variable into two decimal places? Why is it showing a long decimal part even if we assign a number with just two decimal places?
Please suggest a way to store numbers - whether it is calculated or directly assigned - as it is, in a double variable rather than a number with a long decimal part.
In the set of double values, there is no such thing as the number 1.11 because internally, double uses a binary representation (as opposed to humans who are used to a decimal representation). Most finite decimal numbers (such as 1.11) have an infinite representation in binary, but since memory is limited, you lose some precision because of rounding.
The closest you can get to 1.11 with the double data type is 1.1100000000000000976996261670137755572795867919921875, which is internally represented as 0x3ff1c28f5c28f5c3.
Your requirement of two decimal places sounds like you are working with money. A simple solution is to store the cents in an integer (as opposed to the dollars in a double):
int cents = 111;
This way, you don't lose any precision. Another solution is to use a dedicated decimal data type.
the floating-point types like float and double are not 100% precise. They may store 14.3 as 14.299999... and there is nothing wrong about that. That is why you should NEVER compare two floats or doubles with == operator, instread you should check if the absolute value of their difference is smaller than a certain epsilon, like 0.000000001
Now, if you want to output the number in a pleasant way, you can use setprecision from <iomanip>
E.g.
#include <iostream>
#include <iomanip>
int main()
{
double d = 1.389040598345;
std::cout << setprecision(2) << d; //outputs 1.39
}
If you want to obtain the value of d rounded 2 decimal places after the point, then you can use this formula
d = floor((d*100)+0.5)/100.0; //d is now 1.39
Not every decimal number has an exact, finite, binary floating-point representation. You've already found one example, but another one is 0.1 (decimal) = 0.0001100110011... (binary).
You either need to live with that, or use a decimal floating-point library (which will be less efficient).
My recommendation would be to store numbers to full precision, and only round when you need to display them to humans.