简体   繁体   中英

Comparing floating-point numbers (floats or doubles) for min/max

How to compare two different floats, to a certain degree of accuracy. I know that there are very slight imprecisions while using floats or doubles in any programming language, but which may however, be enough to cause this comparison of floats a < b to return a different value than it actually should.

I was solving a problem from the UVa Online Judge which gave me a Wrong Answer many times. It took few float values as input, albeit, to 2 decimal places. I figured out the makeshift solution, which was by splitting the input and converting it to ints, but I wouldn't prefer to use that always.

So my question is, what's the best way to compare whether a float a is lesser (or greater) than a float b, provided that the inputs of a and b are given correct to n decimal places, in this case, 2?

The language I prefer is C++.

Use std::numeric_limits<T>::epsilon() to check whether two numbers are almost equal. If you want to know whether one is greater/less you should also take into account the relative tolerance.

#include <cmath>
#include <limits>

template < typename T >
bool fuzzy_compare(T a, T b)
{
  return std::abs(a - b) < std::numeric_limits<T>::epsilon();
};

Just use math:

#define PREC 0.01                 //(1/pow(10,n)), n = 2
float c = a-b;
if (abs(c) < PREC) {
    printf("a equals b");
} else if(c < 0){
    printf("b is grater than a");
} else 
    printf("a is grater than b");
}

Use the setprecison() operator. The number you put in between the parentheses will determine how many numbers pass the decimal will be included in the output. Be sure to include the iomanip library.

Comparing floats is alway a tricky Here is a more complicated example, showing why you should use std::numeric_limits<T>::epsilon() .

  • The first line returns true, but the second returns false (on my machine).

     float64_t CalculateEpsilon () { float64_t l_AllowedInaccuray = 1; // 1.1, 0.9 int32_t significantDecimalPlaces = 2; return ( l_AllowedInaccuray * pow ( 0.1, significantDecimalPlaces ) ); } bool IsEqual ( float64_t lhs, float64_t rhs ) { float64_t l_Epsilon = CalculateEpsilon (); float64_t l_Delta = std::abs ( lhs - rhs ); return l_Delta <= l_Epsilon; } int32_t main () { std::cout << IsEqual ( 107.35999999999999, 107.350 ); //returns true std::cout << IsEqual ( 107.359999999999999, 107.350 ); //returns false return 0; } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM