Problema em double.Parse em C ++ gerida
-
11-09-2019 - |
Pergunta
Estou recebendo um problema estranho ao analisar um valor double em C ++ gerenciado. Pode ser que eu estou fazendo algo errado. Quando eu faço:
double value = 0.006;
result = Math::Parse( value)
A saída do resultado é 0.006000000000001
. Por que ele está acrescentando um 1?
Além disso, quando eu for um arredondar o valor para 5 casas decimais, ele falhar. Eu estou fazendo:
result2 = Math::Round(result, 5)
Mas result2
é sempre 0.006000000000001
. O que estou fazendo de errado?
Solução
É normal. Este problema causado pelo formato IEEE da dupla - em tempo real 0,006 é representado como aproximação das fração binária infinita. Então você tem 3 modos -
- uso formatação cadeia correspondente ao output
- uso tipo Decimal
- não usar == para comparar números, em vez usar
com o erro constante, por exemplo: (X -0.06)
Outras dicas
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.