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.16666666 is precise to only 8 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?
Verify that the difference between the two values is within an
acceptable tolerance:
using System;
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.
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) that is the smallest positive value, greater
than zero, in which the absolute value of the difference between two
values (numerator/denominator – dblValue) must be less than. In
other words, by taking the absolute value of the difference between
the fraction and the floating-point value and comparing it to a
predetermined value passed to the epsilon argument, we 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 6 digits,
although 7 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 we
require for a good approximation of the fraction 1/7:
bool Approximate = Class1.IsApproximatelyEqualTo(1, 7,
.1428571, .0000001);
// Approximate == true
See the “Double.Epsilon Field” and “Single.Epsilon Field” topics in the
MSDN documentation.