Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions roofit/roofitcore/test/testNaNPacker.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,59 @@ TEST(RooNaNPacker, PackedNaNPreservedAfterArithmetic)
EXPECT_TRUE(rnp2.isNaNWithPayload());
// nothing can harm the PackedNaN
EXPECT_EQ(rnp.getPayload(), rnp2.getPayload());

// multiply packed NaN by 0
rnp2._payload = 0. * rnp.getNaNWithPayload();
EXPECT_TRUE(rnp2.isNaNWithPayload());
// PackedNaN pays no mind
EXPECT_EQ(rnp.getPayload(), rnp2.getPayload());

// the following tests have compiler dependent behavior
// (note that this behavior was tested for msvc as well, even though this
// whole test is currently disabled in msvc)
#if defined(__clang__) || defined(_MSC_VER)
// add packed NaN to regular NaN
rnp2._payload = std::numeric_limits<double>::quiet_NaN() + rnp.getNaNWithPayload();
// first NaN wins, though! now the payload is gone
EXPECT_FALSE(rnp2.isNaNWithPayload());
// a quiet NaN has a "payload" of zero
EXPECT_EQ(0, rnp2.getPayload());

// ... other way around
rnp2._payload = rnp.getNaNWithPayload() + std::numeric_limits<double>::quiet_NaN();
EXPECT_TRUE(rnp2.isNaNWithPayload());
// if it comes first, the PackedNaN does survive
EXPECT_EQ(rnp.getPayload(), rnp2.getPayload());

// multiply regular NaN with packed NaN
rnp2._payload = rnp.getNaNWithPayload() * std::numeric_limits<double>::quiet_NaN();
EXPECT_TRUE(rnp2.isNaNWithPayload());
// if it comes first, the PackedNaN does survive
EXPECT_EQ(rnp.getPayload(), rnp2.getPayload());

// ... other way around
rnp2._payload = std::numeric_limits<double>::quiet_NaN() * rnp.getNaNWithPayload();
// same as with addition: the first NaN wins
EXPECT_FALSE(rnp2.isNaNWithPayload());
// a quiet NaN has a "payload" of zero
EXPECT_EQ(0, rnp2.getPayload());
#endif // defined(__clang__) || defined(_MSC_VER)
#if defined(__GNUC__) && !defined(__clang__)
// on gcc, a different NaN is preserved than in clang and msvc!

// add packed NaN to regular NaN
rnp2._payload = rnp.getNaNWithPayload() + std::numeric_limits<double>::quiet_NaN();
// on gcc, the second NaN wins! now the payload is gone
EXPECT_FALSE(rnp2.isNaNWithPayload());
// a quiet NaN has a "payload" of zero
EXPECT_EQ(0, rnp2.getPayload());

// ... other way around
rnp2._payload = std::numeric_limits<double>::quiet_NaN() + rnp.getNaNWithPayload();
EXPECT_TRUE(rnp2.isNaNWithPayload());
// if it comes second, the PackedNaN does survive
EXPECT_EQ(rnp.getPayload(), rnp2.getPayload());
#endif // __GNUC__
}

#endif // !defined(_MSC_VER) || defined(R__ENABLE_BROKEN_WIN_TESTS)
Expand Down
Loading