, where max and min are the larger and smaller, respectively, of the absolute values of the two arguments. But the formula breaks down if both arguments are zero or infinite. SampleHypotenuse catches the invalid exception that arises from
or
and performs the simple fix.
#pragma fenv_access on
double SampleHypotenuse(double x, double y) { // May be called with any rounding.
TFPEnvironmentSaveAndUpdate localEnvironment;
double_t min = Min(Abs(x), Abs(y));
double_t max = Max(Abs(x), Abs(y));
try {
TFPExceptionHandler invalidHandler(kFPInvalid);
return max * SquareRoot(1.0 + Square(min / max));
}
catch (const TFPInvalidException& caughtInvalid) {
localEnvironment.ClearFlags(kFPInvalid); // clear spurious exception
return max; // two zeroes or two infinities
}
}
max is much larger than min, or if both are very tiny. There is never a serious error due to underflow.
max is very large. The result is
or the largest normal number, depending on the rounding mode.
SampleHypotenuse(x, y) is no greater than
when rounding toward zero or toward
, and is no less when rounding toward
.