forked from OSchip/llvm-project
[libc] Fix bugs with negative and mixed normal/denormal inputs in hypot implementation.
Fix a bug with negative and mixed normal/denormal inputs in hypot implementation. Differential Revision: https://reviews.llvm.org/D114726
This commit is contained in:
parent
d6c0ef7887
commit
dbed678f4b
|
@ -150,7 +150,7 @@ static inline T hypot(T x, T y) {
|
|||
return abs(y);
|
||||
}
|
||||
|
||||
if (x >= y) {
|
||||
if (abs(x) >= abs(y)) {
|
||||
a_exp = x_bits.getUnbiasedExponent();
|
||||
a_mant = x_bits.getMantissa();
|
||||
b_exp = y_bits.getUnbiasedExponent();
|
||||
|
@ -178,10 +178,13 @@ static inline T hypot(T x, T y) {
|
|||
y_mant_width = MantissaWidth<T>::value + 1;
|
||||
} else {
|
||||
leading_one = internal::findLeadingOne(a_mant, y_mant_width);
|
||||
a_exp = 1;
|
||||
}
|
||||
|
||||
if (b_exp != 0) {
|
||||
b_mant |= one;
|
||||
} else {
|
||||
b_exp = 1;
|
||||
}
|
||||
|
||||
a_mant_sq = static_cast<DUIntType>(a_mant) * a_mant;
|
||||
|
|
|
@ -47,28 +47,47 @@ public:
|
|||
|
||||
void testSubnormalRange(Func func) {
|
||||
constexpr UIntType count = 1000001;
|
||||
constexpr UIntType step =
|
||||
(FPBits::maxSubnormal - FPBits::minSubnormal) / count;
|
||||
for (UIntType v = FPBits::minSubnormal, w = FPBits::maxSubnormal;
|
||||
v <= FPBits::maxSubnormal && w >= FPBits::minSubnormal;
|
||||
v += step, w -= step) {
|
||||
T x = T(FPBits(v)), y = T(FPBits(w));
|
||||
T result = func(x, y);
|
||||
mpfr::BinaryInput<T> input{x, y};
|
||||
ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5);
|
||||
for (unsigned scale = 0; scale < 4; ++scale) {
|
||||
UIntType maxValue = FPBits::maxSubnormal << scale;
|
||||
UIntType step = (maxValue - FPBits::minSubnormal) / count;
|
||||
for (int signs = 0; signs < 4; ++signs) {
|
||||
for (UIntType v = FPBits::minSubnormal, w = maxValue;
|
||||
v <= maxValue && w >= FPBits::minSubnormal; v += step, w -= step) {
|
||||
T x = T(FPBits(v)), y = T(FPBits(w));
|
||||
if (signs % 2 == 1) {
|
||||
x = -x;
|
||||
}
|
||||
if (signs >= 2) {
|
||||
y = -y;
|
||||
}
|
||||
|
||||
T result = func(x, y);
|
||||
mpfr::BinaryInput<T> input{x, y};
|
||||
ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void testNormalRange(Func func) {
|
||||
constexpr UIntType count = 1000001;
|
||||
constexpr UIntType step = (FPBits::maxNormal - FPBits::minNormal) / count;
|
||||
for (UIntType v = FPBits::minNormal, w = FPBits::maxNormal;
|
||||
v <= FPBits::maxNormal && w >= FPBits::minNormal;
|
||||
v += step, w -= step) {
|
||||
T x = T(FPBits(v)), y = T(FPBits(w));
|
||||
T result = func(x, y);
|
||||
mpfr::BinaryInput<T> input{x, y};
|
||||
ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5);
|
||||
for (int signs = 0; signs < 4; ++signs) {
|
||||
for (UIntType v = FPBits::minNormal, w = FPBits::maxNormal;
|
||||
v <= FPBits::maxNormal && w >= FPBits::minNormal;
|
||||
v += step, w -= step) {
|
||||
T x = T(FPBits(v)), y = T(FPBits(w));
|
||||
if (signs % 2 == 1) {
|
||||
x = -x;
|
||||
}
|
||||
if (signs >= 2) {
|
||||
y = -y;
|
||||
}
|
||||
|
||||
T result = func(x, y);
|
||||
mpfr::BinaryInput<T> input{x, y};
|
||||
ASSERT_MPFR_MATCH(mpfr::Operation::Hypot, input, result, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue