Performs a fuzzy comparison of two numeric values.

Category: Mathematical


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

Required Arguments


specifies the first of two numeric values to be compared.


specifies the second numeric value to be compared.

Optional Arguments


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


specifies the scale factor.

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


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.


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.


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=;
SAS writes the following output to the log:
Partial SAS Log for the COMPFUZZ Function
fuzz only (wrong):         compfuzz=-1
fuzz and scale (correct):  compfuzz=0

See Also