COMPFUZZ Function

Performs a fuzzy comparison of two numeric values.

Category: Mathematical

Syntax

COMPFUZZ(value1, value2 <, fuzz <, scale> > )

Required Arguments

value1

specifies the first of two numeric values to be compared.

value2

specifies the second numeric value to be compared.

Optional Arguments

fuzz

is a nonnegative numeric value that specifies the relative threshold for comparisons. Values greater than or equal to one are treated as multiples of the machine precision.

Default 1024

scale

specifies the scale factor.

Default MAX (ABS (value1), ABS (value2))

Details

The COMPFUZZ function returns the following values if you specify all four arguments:
  • -1 if value1 < value2 - threshold
  • 0 if ABS(value1 - value2) ≤ threshold
  • 1 if value1 > value2 + threshold
The following relationships exist:
  • threshold = fuzz * ABS(scale) if 0 ≤ fuzz < 1
  • threshold = fuzz * ABS(scale) * CONSTANT('MACEPS') if 1 ≤ fuzz < 1 / CONSTANT('MACEPS')
COMPFUZZ avoids floating point underflow or overflow.

Comparisons

The COMPFUZZ function compares two floating point numbers and returns a value based on the comparison. The ROUND function rounds an argument to a value that is very close to a multiple of a second argument. The result might not be an exact multiple of the second argument.

Example

In floating point arithmetic, the value of a sum sometimes depends on the order in which the numbers are added. One approximate bound for the floating point error in the computation of a sum of n numbers, x1 through xn is expressed by the following formula:
n * machine_precision * sum (abs(x1) + ... + abs(xn))
To compare sums of n floating point numbers with the COMPFUZZ function, you can therefore use n as the fuzz value and the sum of the absolute values as the scale factor, as shown in the following DATA step:
data _null_;
   x1 = -1/3;
   x2 = 22/7;
   x3 = -1234567891;
   x4 = 1234567890;
      /* Add the numbers in two different orders. */
   sum1 = x1 + x2 + x3 + x4;
   sum2 = x4 + x3 + x2 + x1;
   diff = abs (sum1 - sum2);
   put sum1= / sum2= / diff=;
      /* Using only a fuzz value gives the wrong result. The fuzz value  */
      /* is 8 because there are four numbers in each sum, for a total of */
      /* eight numbers.                                                  */
   compfuzz = compfuzz (sum1, sum2, 8);
   put "fuzz only (wrong):         " compfuzz=;
      /* Using a fuzz factor and a scale value gives the correct result. */
   scale = abs(x1) + abs(x2) + abs(x3) + abs(x4);
   compfuzz = compfuzz (sum1, sum2, 8, scale);
   put "fuzz and scale (correct):  " compfuzz=;
run;
   
SAS writes the following output to the log:
Partial SAS Log for the COMPFUZZ Function
sum1=1.8095238095
sum2=1.8095238095
diff=5.543588E-11
fuzz only (wrong):         compfuzz=-1
fuzz and scale (correct):  compfuzz=0

See Also