mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Fix ldexp implementations.
The previous implementations produced garbage values if the exponent did not fit within the exponent bits. See #2131 for a complete discussion, and !375 for other possible implementations. Here we implement the 4-factor version. See `pldexp_impl` in `GenericPacketMathFunctions.h` for a full description. The SSE `pcmp*` methods were moved down since `pcmp_le<Packet4i>` requires `por`. Left as a "TODO" is to delegate to a faster version if we know the exponent does fit within the exponent bits. Fixes #2131.
This commit is contained in:
committed by
Rasmus Munk Larsen
parent
7eb07da538
commit
4cb563a01e
@@ -573,10 +573,41 @@ void packetmath_real() {
|
||||
data2[i] = Scalar(internal::random<double>(-1, 1));
|
||||
}
|
||||
for (int i = 0; i < PacketSize; ++i) {
|
||||
data1[i+PacketSize] = Scalar(internal::random<int>(0, 4));
|
||||
data2[i+PacketSize] = Scalar(internal::random<double>(0, 4));
|
||||
data1[i+PacketSize] = Scalar(internal::random<int>(-4, 4));
|
||||
data2[i+PacketSize] = Scalar(internal::random<double>(-4, 4));
|
||||
}
|
||||
CHECK_CWISE2_IF(PacketTraits::HasExp, REF_LDEXP, internal::pldexp);
|
||||
if (PacketTraits::HasExp) {
|
||||
data1[0] = Scalar(-1);
|
||||
// underflow to zero
|
||||
data1[PacketSize] = Scalar(std::numeric_limits<Scalar>::min_exponent-10);
|
||||
CHECK_CWISE2_IF(PacketTraits::HasExp, REF_LDEXP, internal::pldexp);
|
||||
// overflow to inf
|
||||
data1[PacketSize] = Scalar(std::numeric_limits<Scalar>::max_exponent+10);
|
||||
CHECK_CWISE2_IF(PacketTraits::HasExp, REF_LDEXP, internal::pldexp);
|
||||
// NaN stays NaN
|
||||
data1[0] = NumTraits<Scalar>::quiet_NaN();
|
||||
CHECK_CWISE2_IF(PacketTraits::HasExp, REF_LDEXP, internal::pldexp);
|
||||
VERIFY((numext::isnan)(data2[0]));
|
||||
// inf stays inf
|
||||
data1[0] = NumTraits<Scalar>::infinity();
|
||||
data1[PacketSize] = Scalar(std::numeric_limits<Scalar>::min_exponent-10);
|
||||
CHECK_CWISE2_IF(PacketTraits::HasExp, REF_LDEXP, internal::pldexp);
|
||||
// zero stays zero
|
||||
data1[0] = Scalar(0);
|
||||
data1[PacketSize] = Scalar(std::numeric_limits<Scalar>::max_exponent+10);
|
||||
CHECK_CWISE2_IF(PacketTraits::HasExp, REF_LDEXP, internal::pldexp);
|
||||
// Small number big exponent.
|
||||
data1[0] = Scalar(std::ldexp(Scalar(1.0), std::numeric_limits<Scalar>::min_exponent-1));
|
||||
data1[PacketSize] = Scalar(-std::numeric_limits<Scalar>::min_exponent
|
||||
+std::numeric_limits<Scalar>::max_exponent);
|
||||
CHECK_CWISE2_IF(PacketTraits::HasExp, REF_LDEXP, internal::pldexp);
|
||||
// Big number small exponent.
|
||||
data1[0] = Scalar(std::ldexp(Scalar(1.0), std::numeric_limits<Scalar>::max_exponent-1));
|
||||
data1[PacketSize] = Scalar(+std::numeric_limits<Scalar>::min_exponent
|
||||
-std::numeric_limits<Scalar>::max_exponent);
|
||||
CHECK_CWISE2_IF(PacketTraits::HasExp, REF_LDEXP, internal::pldexp);
|
||||
}
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
data1[i] = Scalar(internal::random<double>(-1, 1) * std::pow(10., internal::random<double>(-6, 6)));
|
||||
|
||||
Reference in New Issue
Block a user