Recipe1.1.Determining Approximate Equality Between a Fraction and Floating-Point Value


Recipe 1.1. Determining Approximate Equality Between a Fraction and Floating-Point Value

Problem

You need to compare a fraction with a value of type double or float to determine whether they are within a close approximation to each other. Take, for example, the result of comparing the expression 1/6 and the value 0.16666667. These seem to be equivalent, except that 0.16666667 is precise to only eight places to the right of the decimal point, and 1/6 is precise to the maximum number of digits to the right of the decimal point that the data type will hold.

Solution

To compare the approximate equality between a fraction and a floating-point value, verify that the difference between the two values is within an acceptable tolerance:

 using System; // Override that uses the System.Double.Epsilon value public static bool IsApproximatelyEqualTo(double numerator,                                           double denominator,                                           double dblValue) {     return IsApproximatelyEqualTo(numerator,          denominator, dblValue, double.Epsilon); } // Override that allows for specification of an epsilon value // other than System.Double.Epsilon public static bool IsApproximatelyEqualTo(double numerator,                                           double denominator,                                            double dblValue,                                            double epsilon) {     double difference = (numerator/denominator) - dblValue;     if (Math.Abs(difference) < epsilon)     {         // This is a good approximation.         return true;     }     else     {         // This is NOT a good approximation.         return false;     } } 

Replacing the type double with float allows you to determine whether a fraction and a float value are approximately equal.

Discussion

Fractions can be expressed as a numerator over a denominator; however, storing them as a floating-point value might be necessary. Storing fractions as floating-point values introduces rounding errors that make it difficult to perform comparisons. Expressing the value as a fraction (e.g., 1/6) allows the maximum precision. Expressing the value as a floating-point value (e.g., 0.16667) can limit the precision of the value. In this case, the precision depends on the number of digits that the developer decides to use to the right of the decimal point.

You might need a way to determine whether two values are approximately equal to each other. This comparison is achieved by defining a value (epsilon), representing the smallest positive value by which two numbers can differ and still be considered equal. In other words, by taking the absolute value of the difference between the fraction (numerator/denominator) and the floating-point value (dblValue) and comparing it to a predetermined value passed to the epsilon argument, you can determine whether the floating-point value is a good approximation of the fraction.

Consider a comparison between the fraction 1/7 and its floating-point value, 0.14285714285714285. The following call to the IsApproximatelyEqualTo method indicates that there are not enough digits to the right of the decimal point in the floating-point value to be a good approximation of the fraction (there are six digits, although seven are required):

 bool Approximate = Class1.IsApproximatelyEqualTo(1, 7, .142857, .0000001); // Approximate == false 

Adding another digit of precision to the third parameter of this method now indicates that this more precise number is what you require for a good approximation of the fraction 1/7:

 bool Approximate = Class1.IsApproximatelyEqualTo(1, 7, .1428571, .0000001); // Approximate == true 

See Also

See the "Double.Epsilon Field" and "Single.Epsilon Field" topics in the MSDN documentation.



C# Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2004
Pages: 424

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net