What's the best way to compare decimal places?

What's the best way to compare decimal places?

lets say I have 2 values, for example 3.45

and 3.44

what's the best way to reliably compare them?

I thought to store all numbers as 345

and 344

, so that I only compare integers and only show user formatted digits with decimal point.

Another solution would be to use custom functions to check the difference, and when the difference is less 0.01

, the numbers should be equal.

What are the other possible solutions (best solutions)?

+3


source to share


3 answers


The most common method is using epsilon (the second one you described). It can be extremely difficult / impossible to make a generic epsilon that works well for all input numbers. If you are dealing with numbers around 0.00001 or numbers around 1,000,000,000, epsilon 0.01 will probably be terrible for you. Read this one for a really in-depth analysis of epsilon techniques.



The first solution you described is very common in time mathematics. Everything is represented by an integer number of ticks. Ticks can be 1 second or 1 millisecond or whatever. Then you can convert them to a decimal digit of another division if you like, or compare them. The only thing you need to choose is the size of the checkmark, and nothing can represent less than a unit.

+3


source


This is also known as "fuzzy comparison", allowing two values ​​to differ slightly (tolerance, also known as "epsilon"). Typically, this epsilon value ranges from 1E-6

to 1E-10

, but you will find applications in which more or less values ​​are more suitable: in your example, epsilon should be at least 1E-2 = 0.01

.

Once you find an epsilon value that suits your needs, you can write the following set of comparison functions such as the following (written in a common subset of C and C ++; they should work for almost every object-oriented / procedural language, minor changes) :

const double fuzzyEpsilon = 1E-6;  // just an example!

bool fuzzyEqual(double a, double b) {
    return (abs(a - b) <= fuzzyEpsilon);
}

bool fuzzyUnqual(double a, double b) {
    return (abs(a - b) > fuzzyEpsilon);
}

int fuzzyCompare(double a, double b) {
    return ((a - b) > fuzzyEpsilon) - ((b - a) > fuzzyEpsilon);
}

      



The third function returns a code -1

, 0

, 1

if a < b

, a == b

, a > b

respectively, with a fuzzy comparison (same as strcmp

). The implementation assumes that the programming language implicitly converts booleans to 0

(false) and 1

(true). If not, use the following:

int fuzzyCompare(double a, double b) {
    return (a - b) > fuzzyEpsilon ? 1 :
          ((b - a) > fuzzyEpsilon ? -1 : 0);
}

      

0


source


The representation of decimal values ​​in binary reality is approximate, resulting in many odd behaviors. Accuracy often degrades with further arithmetic, especially subtraction of nearby values. However, individual values ​​can be cleared for comparison by rounding to the minimum number of digits before comparing them. For example, V = round (V * 1e14) / 1e14 rounds any V value to 14 decimal digits. Two such values ​​can be confidently compared for equality. 64-bit real has a definition precision of 15.65, so rounding to 14 digits (or less) provides some error.

Yes, the sequence of multiplication, rounding () and division is expensive. However, decimal is a human interface, often used for money applications that cannot tolerate "funny" arithmetic. Being wrong is usually much worse than being slow.

0


source







All Articles