Home  >  Q&A  >  body text

c/c++ 比较两个浮点数相等

PHP中文网PHP中文网2715 days ago669

reply all(2)I'll reply

  • PHP中文网

    PHP中文网2017-04-17 15:10:48

    First of all, the two ifs are the same. When comparing floating point numbers with integers, the integers are converted to floating point numbers.
    Then, why is i not equal to 10.0? Because it will only be equal to these values:

    >>> def gen():
    ...   i = 0
    ...   while i < 10:
    ...     i += 0.1
    ...     yield i
    ...
    >>> L = list(gen())
    >>> L
    [0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6, 0.7, 0.7999999999999999, 0.8999999999999999, 0.9999999999999999, 1.0999999999999999, 1.2, 1.3, 1.4000000000000001, 1.5000000000000002, 1.6000000000000003, 1.7000000000000004, 1.8000000000000005, 1.9000000000000006, 2.0000000000000004, 2.1000000000000005, 2.2000000000000006, 2.3000000000000007, 2.400000000000001, 2.500000000000001, 2.600000000000001, 2.700000000000001, 2.800000000000001, 2.9000000000000012, 3.0000000000000013, 3.1000000000000014, 3.2000000000000015, 3.3000000000000016, 3.4000000000000017, 3.5000000000000018, 3.600000000000002, 3.700000000000002, 3.800000000000002, 3.900000000000002, 4.000000000000002, 4.100000000000001, 4.200000000000001, 4.300000000000001, 4.4, 4.5, 4.6, 4.699999999999999, 4.799999999999999, 4.899999999999999, 4.999999999999998, 5.099999999999998, 5.1999999999999975, 5.299999999999997, 5.399999999999997, 5.4999999999999964, 5.599999999999996, 5.699999999999996, 5.799999999999995, 5.899999999999995, 5.999999999999995, 6.099999999999994, 6.199999999999994, 6.299999999999994, 6.399999999999993, 6.499999999999993, 6.5999999999999925, 6.699999999999992, 6.799999999999992, 6.8999999999999915, 6.999999999999991, 7.099999999999991, 7.19999999999999, 7.29999999999999, 7.39999999999999, 7.499999999999989, 7.599999999999989, 7.699999999999989, 7.799999999999988, 7.899999999999988, 7.999999999999988, 8.099999999999987, 8.199999999999987, 8.299999999999986, 8.399999999999986, 8.499999999999986, 8.599999999999985, 8.699999999999985, 8.799999999999985, 8.899999999999984, 8.999999999999984, 9.099999999999984, 9.199999999999983, 9.299999999999983, 9.399999999999983, 9.499999999999982, 9.599999999999982, 9.699999999999982, 9.799999999999981, 9.89999999999998, 9.99999999999998, 10.09999999999998]

    You can see that there is an error in converting floating point from decimal to binary. After 100 error accumulations, i will only be equal to 9.99999999999998. (I'm using Python 3.6, and the decimal representation of floating point numbers uses the shortest equivalent representation. It also uses the same internal representation as the C language.)

    Floating point numbers are represented and operated in binary form in computers (usually using the IEEE 754 standard), and 0.1 cannot be accurately represented in binary (it is a recurring decimal; only decimals whose denominator only contains a factor of 2 are represented in binary It will not cycle until then). There will be errors in this way. As errors accumulate, it will deviate further and further from the decimal system.

    If you need to compare for equality, you can find the difference with the specified number. If the difference is less than a specific value (such as the math.isclose function in Python), it is considered equal.

    If you need precise values ​​(such as doing financial calculations, where not a penny is less), you can use so-called "decimal numbers" to perform operations (decimal, supported by both Python and Ruby. You can also use mpdecimal library), or specify the precision (such as using the mpfr library), or use fixed point numbers.

    reply
    0
  • 高洛峰

    高洛峰2017-04-17 15:10:48

    Regarding the language of 强数据类型, when comparing data with decimal points such as double float, == is generally not used for comparison.

    Instead, it compares the absolute value of the subtraction of the two numbers. If the absolute value is less than a small value, then we consider the two floating point numbers to be equal.

    The following code:

    #include <iostream>
    #include <cmath>
    
    using namespace std;
    
    int main(int argc, char **argv)
    {
        for(double i=0; i!=10; i += 0.1)
        {
            if( fabs( i - 10.0 ) < 0.00000001 ) ///< fabs: 获得double类型的绝对值
            {
                cout << "i equal 10" << '\n';
                break;
            }
    
            cout << i << '\n';
    
            if( i > 20 )
            {
                break;
            }
        }
        return 0;
    }

    The reason why this happens is that the computer itself uses 01 binary to represent data.

    It can basically be understood like this:Because of the storage format of floating-point numbers inside the computer, many floating-point numbers saved in the memory are only saved in a form as close as possible

    If you are interested, you can learn more.

    Blog Garden Articles

    reply
    0
  • Cancelreply