Logic: Move (huge,tiny) test up, supersedes testing for 0.0

This commit is contained in:
Inkrementator 2025-03-18 00:13:55 +01:00
parent da127b18b8
commit 006b1ca936

View file

@ -310,7 +310,6 @@ if (isFloatingPoint!T)
// If both are tiny, avoid underflow by scaling by 2^^N.
import core.math : fabs, sqrt;
import std.math.traits : floatTraits, RealFormat, isNaN;
import std.algorithm.comparison : max;
alias F = floatTraits!T;
@ -327,12 +326,6 @@ if (isFloatingPoint!T)
}
assert(!(u.isNaN || v.isNaN), "Comparison to NaN always fails, thus is is always handled in the branch above");
const maxabs = max(u,v);
if (v == 0.0)
{
return u;
}
static if (F.realFormat == RealFormat.ieeeSingle)
{
enum SQRTMIN = 0x1p-60f;
@ -360,6 +353,13 @@ if (isFloatingPoint!T)
else
assert(0, "hypot not implemented");
if (u * T.epsilon > v)
{
// hypot (huge, tiny) = huge
// also: hypot(x, 0) = x
return u;
}
// Now u >= v, or else one is NaN.
T ratio = 1.0;
if (v >= SQRTMAX)
@ -379,12 +379,6 @@ if (isFloatingPoint!T)
v *= SCALE_UNDERFLOW;
}
if (u * T.epsilon > v)
{
// hypot (huge, tiny) = huge
return u;
}
// both are in the normal range
return ratio * sqrt(u^^2 + v^^2);
}
@ -427,6 +421,7 @@ if (isFloatingPoint!T)
enum small = 5.016556e-20f;
assert(hypot(small, 0).isClose(small));
assert(hypot(small, float.min_normal).isClose(small));
}
@safe unittest