views:

174

answers:

3

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?

+3  A: 

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.

Ralph Rickenbach
A: 

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.

Marc Gravell
A: 

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
Dewfy