aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/packetmath.cpp
diff options
context:
space:
mode:
authorGravatar Antonio Sanchez <cantonios@google.com>2020-10-12 12:24:08 +0100
committerGravatar Rasmus Munk Larsen <rmlarsen@google.com>2021-02-10 22:45:41 +0000
commit4cb563a01e0619ea1798c7927f1909755ead2dd8 (patch)
treef1a1c213a13ad6320fa86ebb144af777568eeeea /test/packetmath.cpp
parent7eb07da538ecc1b8937bfb5dac0d071067728397 (diff)
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.
Diffstat (limited to 'test/packetmath.cpp')
-rw-r--r--test/packetmath.cpp35
1 files changed, 33 insertions, 2 deletions
diff --git a/test/packetmath.cpp b/test/packetmath.cpp
index b7562e6a1..c388f3a31 100644
--- a/test/packetmath.cpp
+++ b/test/packetmath.cpp
@@ -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)));