SoFunction
Updated on 2025-04-13

How to compare floating point numbers and double types with 0 values ​​in C++

Preface

In C++, due to floating point numbers (float/double) storage method and accuracy issues are directly related to0Make equality comparison (e.g.==) may lead to unexpected results. The following is a detailed description from three aspects: principle, correct comparison method and code example:

1. The root cause of the problem of comparing floating point numbers with 0

  • The accuracy of floating point numbers

    • Floating point numbers are stored in memory in scientific binary notation (according to IEEE 754 standard), and some decimal decimals cannot be expressed accurately.
    • For example:0.1In binary, it is an infinite loop decimal, and there will be rounding errors when actually storing.
    • The tiny error accumulated during the calculation process may theoretically lead to0The value of   is actually a very small non-zero value (e.g.1e-16)。
  • A trap for direct comparison

    double a = 0.1 + 0.1 + 0.1;  // The theoretical value is 0.3, the actual value may be 0.300000000000000000004if (a == 0.3) { /* May not be true */ }
    

2. Correct comparison method

1. Compare whether the floating point number is 0

Use a very small threshold (epsilon) Determine whether the floating point number is close to 0:

#include <cmath> // Use fabs
bool isZero(double value, double epsilon = 1e-9) {
    return std::fabs(value) &lt; epsilon;
}

// Example usagedouble x = 1e-10;
if (isZero(x)) {
    std::cout &lt;&lt; "x can be regarded as 0" &lt;&lt; std::endl;
}

2. Compare whether two floating point numbers are equal

Compare whether the difference between two floating point numbers is within the allowable range:

bool areEqual(double a, double b, double epsilon = 1e-9) {
    return std::fabs(a - b) &lt; epsilon;
}

// Example usagedouble a = 0.1 + 0.1 + 0.1;
double b = 0.3;
if (areEqual(a, b)) {
    std::cout &lt;&lt; "a and b are equal in the error range" &lt;&lt; std::endl;
}

3. Key points to note

  • Choose a reasonable epsilon

    • epsilonThe value of   needs to be combined with specific scenarios:
      • Normal application:1e-9(For most cases).
      • Scientific calculations: smaller values ​​may be required (e.g.1e-15)。
    • Avoid hard-code: use constants or passstd::numeric_limitsObtain machine accuracy:
      #include <limits>
      const double epsilon = std::numeric_limits<double>::epsilon();
      
  • Avoid the traps in comparison

    • Don't compare floating point numbers directly
      // Wrong practiceif (x == 0.0) { /* Unreliable */ }
      
    • Consider relative error
      For larger values, it may be necessary to compare the relative errors in combination (for example, to determine whether the two values ​​are within the 1% error range).
  • Processing of special values

    • NaN (non-numerical): Neededstd::isnan()Test.
    • Infinity:usestd::isinf()Test.
    double x = std::sqrt(-1.0);  // Generate NaNif (std::isnan(x)) {
        std::cout &lt;&lt; "x is non-numeric" &lt;&lt; std::endl;
    }
    

4. Complete sample code

#include &lt;iostream&gt;
#include &lt;cmath&gt;
#include &lt;limits&gt;

// Determine whether it is 0bool isZero(double value, double epsilon = 1e-9) {
    return std::fabs(value) &lt; epsilon;
}

// Determine whether two floating point numbers are equalbool areEqual(double a, double b, double epsilon = 1e-9) {
    return std::fabs(a - b) &lt; epsilon;
}

int main() {
    double a = 0.1 + 0.1 + 0.1;  // The actual value is about 0.300000000000000000004    double b = 0.3;

    // Direct comparison failed    if (a == b) {
        std::cout &lt;&lt; "Direct comparison: equality" &lt;&lt; std::endl;
    } else {
        std::cout &lt;&lt; "Direct comparison: unequal" &lt;&lt; std::endl;
    }

    //The error range is relatively successful    if (areEqual(a, b)) {
        std::cout &lt;&lt; "Error comparison: equality" &lt;&lt; std::endl;
    }

    // Determine whether it is 0    double x = 1e-10;
    if (isZero(x)) {
        std::cout &lt;&lt; "x can be regarded as 0" &lt;&lt; std::endl;
    }

    return 0;
}

5. Summary

operate The correct way Error Method
Determine whether the floating point number is 0 fabs(val) < epsilon val == 0.0
Determine whether two floating point numbers are equal fabs(a - b) < epsilon a == b
Handle special values ​​(NaN/Inf) std::isnan(val) / std::isinf(val) Direct comparison

Following the above method can avoid logical errors caused by floating point accuracy problems and ensure the robustness of the code.

This is the article about how to compare floating point numbers and double types in C++ with 0 values. For more related contents of comparison of floating point numbers, double and 0 values, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!