Why do I see a double variable initialized to some value like 21.4 as 21.399999618530273?

前端 未结 14 2030
名媛妹妹
名媛妹妹 2020-11-21 23:41
double r = 11.631;
double theta = 21.4;

In the debugger, these are shown as 11.631000000000000

相关标签:
14条回答
  • 2020-11-21 23:47

    You cant avoid this as you're using floating point numbers with fixed quantity of bytes. There's simply no isomorphism possible between real numbers and its limited notation.

    But most of the time you can simply ignore it. 21.4==21.4 would still be true because it is still the same numbers with the same error. But 21.4f==21.4 may not be true because the error for float and double are different.

    If you need fixed precision, perhaps you should try fixed point numbers. Or even integers. I for example often use int(1000*x) for passing to debug pager.

    0 讨论(0)
  • 2020-11-21 23:50

    I've come across this before (on my blog) - I think the surprise tends to be that the 'irrational' numbers are different.

    By 'irrational' here I'm just referring to the fact that they can't be accurately represented in this format. Real irrational numbers (like π - pi) can't be accurately represented at all.

    Most people are familiar with 1/3 not working in decimal: 0.3333333333333...

    The odd thing is that 1.1 doesn't work in floats. People expect decimal values to work in floating point numbers because of how they think of them:

    1.1 is 11 x 10^-1

    When actually they're in base-2

    1.1 is 154811237190861 x 2^-47

    You can't avoid it, you just have to get used to the fact that some floats are 'irrational', in the same way that 1/3 is.

    0 讨论(0)
  • 2020-11-21 23:50

    According to the javadoc

    "If at least one of the operands to a numerical operator is of type double, then the
    operation is carried out using 64-bit floating-point arithmetic, and the result of the
    numerical operator is a value of type double. If the other operand is not a double, it is
    first widened (§5.1.5) to type double by numeric promotion (§5.6)."

    Here is the Source

    0 讨论(0)
  • 2020-11-21 23:52

    If you are using Java and you need accuracy, use the BigDecimal class for floating point calculations. It is slower but safer.

    0 讨论(0)
  • 2020-11-21 23:53

    These accuracy problems are due to the internal representation of floating point numbers and there's not much you can do to avoid it.

    By the way, printing these values at run-time often still leads to the correct results, at least using modern C++ compilers. For most operations, this isn't much of an issue.

    0 讨论(0)
  • 2020-11-21 23:54

    If you have a value like:

    double theta = 21.4;
    

    And you want to do:

    if (theta == 21.4)
    {
    }
    

    You have to be a bit clever, you will need to check if the value of theta is really close to 21.4, but not necessarily that value.

    if (fabs(theta - 21.4) <= 1e-6)
    {
    }
    
    0 讨论(0)
提交回复
热议问题