in commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Norm.java [264:319]
private static double euclidean(final double x,
final double y) {
final double xabs = Math.abs(x);
final double yabs = Math.abs(y);
final double max;
final double min;
// the compare method considers NaN greater than other values, meaning that our
// check for if the max is finite later on will detect NaNs correctly
if (Double.compare(xabs, yabs) > 0) {
max = xabs;
min = yabs;
} else {
max = yabs;
min = xabs;
}
// if the max is not finite, then one of the inputs must not have
// been finite
if (!Double.isFinite(max)) {
// let the standard multiply operation determine whether to return NaN or infinite
return xabs * yabs;
} else if (Math.getExponent(max) - Math.getExponent(min) > EXP_DIFF_THRESHOLD_2D) {
// value is completely dominated by max; just return max
return max;
}
// compute the scale and rescale values
final double scale;
final double rescale;
if (max > LARGE_THRESH) {
scale = SCALE_DOWN;
rescale = SCALE_UP;
} else if (max < SAFE_SCALE_UP_THRESH) {
scale = SCALE_UP;
rescale = SCALE_DOWN;
} else {
scale = 1d;
rescale = 1d;
}
// initialise sum and compensation using scaled x
final double sx = xabs * scale;
double sum = sx * sx;
double comp = DD.twoSquareLow(sx, sum);
// add scaled y
final double sy = yabs * scale;
final double py = sy * sy;
comp += DD.twoSquareLow(sy, py);
final double sumPy = sum + py;
comp += DD.twoSumLow(sum, py, sumPy);
sum = sumPy;
return Math.sqrt(sum + comp) * rescale;
}