Problem in double.Parse in Managed C++
-
11-09-2019 - |
Question
I am getting a weird problem while parsing a double value in managed C++. It may be that I am doing something wrong. When I do:
double value = 0.006;
result = Math::Parse( value)
The output of result is 0.006000000000001
. Why it is appending a 1?
Also when I go an round the value to 5 decimal places, it fails. I am doing:
result2 = Math::Round(result, 5)
But result2
is always 0.006000000000001
. What am I doing wrong?
Solution
It is normal. This problem caused by IEEE format of double - in real 0.006 is represented as approximation of infinite binary fraction. So you have 3 ways -
- use corresponding string formating to output
- use Decimal type
- don't use == to compare numbers, instead use < or > with constant error,e.g: (X -0.06) < Error
OTHER TIPS
This is due to precision. I gave this answer here:
Floats and doubles are number representations with a certain precision. Not every value can be represented in this format. See here as well.
You can easily think of why this would be the case: there is an unlimited number of number just in the intervall (1..1), but a float only has a limited number of bits to represent all numbers in (-MAXFLOAT..MAXFLOAT).
More aptly put: in a 32bit integer representation there is a countable number of integers to be represented, But there is an infinite innumerable number of real values that cannot be fully represented in a limited representation of 32 or 64bit. Therefore there not only is a limit to the highest and lowest representable real value, but also to the accuracy.
So why is a number that has little digits after the floating point affected? Because the representation is based on a binary system instead of a decimal, making other numbers easily represented then the decimal ones.
double precision numbers are essentially approximations, and frequently have tails that you cannot get rid of - i.e. there is no way of expressing the number more accurately.
You might get results more like you expect if you use decimal
- which is still an approximation, but it uses base-10, so tends to behave more like people expect. But because it doesn't map to a CPU type, it is slower.