in commons-numbers-core/src/main/java/org/apache/commons/numbers/core/Norm.java [339:398]
private static double euclidean(final double x,
final double y,
final double z) {
final double xabs = Math.abs(x);
final double yabs = Math.abs(y);
final double zabs = Math.abs(z);
final double max = Math.max(Math.max(xabs, yabs), zabs);
// 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 * zabs;
}
// 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;
}
double sum = 0d;
double comp = 0d;
// add scaled x
final double sx = xabs * scale;
final double px = sx * sx;
comp += ExtendedPrecision.squareLowUnscaled(sx, px);
final double sumPx = sum + px;
comp += ExtendedPrecision.twoSumLow(sum, px, sumPx);
sum = sumPx;
// add scaled y
final double sy = yabs * scale;
final double py = sy * sy;
comp += ExtendedPrecision.squareLowUnscaled(sy, py);
final double sumPy = sum + py;
comp += ExtendedPrecision.twoSumLow(sum, py, sumPy);
sum = sumPy;
// add scaled z
final double sz = zabs * scale;
final double pz = sz * sz;
comp += ExtendedPrecision.squareLowUnscaled(sz, pz);
final double sumPz = sum + pz;
comp += ExtendedPrecision.twoSumLow(sum, pz, sumPz);
sum = sumPz;
return Math.sqrt(sum + comp) * rescale;
}