Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:04:44

0001 #include <cppunit/extensions/HelperMacros.h>
0002 #include <iostream>
0003 #include <iomanip>
0004 #include <limits>
0005 
0006 #include "DataFormats/Math/interface/liblogintpack.h"
0007 
0008 class testlogintpack : public CppUnit::TestFixture {
0009   CPPUNIT_TEST_SUITE(testlogintpack);
0010 
0011   CPPUNIT_TEST(test16base11);
0012   CPPUNIT_TEST(test8);
0013 
0014   CPPUNIT_TEST_SUITE_END();
0015 
0016 public:
0017   void setUp() {}
0018   void tearDown() {}
0019 
0020   void test16base11();
0021   void test8();
0022 
0023 private:
0024 };
0025 
0026 namespace {
0027   int16_t pack16base11(double x) { return logintpack::pack16log(x, -15, 0, 1 << 11); }
0028   int16_t pack16base11ceil(double x) { return logintpack::pack16logCeil(x, -15, 0, 1 << 11); }
0029   int16_t pack16base11closed(double x) { return logintpack::pack16logClosed(x, -15, 0, 1 << 11); }
0030   double unpack16base11(int16_t x) { return logintpack::unpack16log(x, -15, 0, 1 << 11); }
0031   double unpack16base11closed(int16_t x) { return logintpack::unpack16logClosed(x, -15, 0, 1 << 11); }
0032 
0033   int8_t pack(double x) { return logintpack::pack8log(x, -15, 0); }
0034   int8_t packceil(double x) { return logintpack::pack8logCeil(x, -15, 0); }
0035   int8_t packclosed(double x) { return logintpack::pack8log(x, -15, 0); }
0036   double unpack(int8_t x) { return logintpack::unpack8log(x, -15, 0); }
0037   double unpackclosed(int8_t x) { return logintpack::unpack8logClosed(x, -15, 0); }
0038 }  // namespace
0039 
0040 void testlogintpack::test16base11() {
0041   constexpr uint16_t base = 1 << 11;  // 2^11 = 2048
0042 
0043   constexpr int16_t smallestPositive = 0;
0044   constexpr int16_t smallestNegative = -1;
0045   constexpr int16_t largestPositive = base - 1;
0046   constexpr int16_t largestNegative = -largestPositive;
0047 
0048   union {
0049     float flt;
0050     uint32_t i32;
0051   } conv32;
0052   union {
0053     double flt;
0054     uint64_t i64;
0055   } conv64;
0056 
0057   const double smallestValuePos = std::exp(-15.);
0058   const double smallestValueNeg = -std::exp(-15. + 1. / base * 15.);
0059   const double smallestValueNegForClosed = -std::exp(-15. + 1. / (base - 1) * 15.);
0060   CPPUNIT_ASSERT(pack16base11(smallestValuePos) == smallestPositive);
0061   CPPUNIT_ASSERT(pack16base11ceil(smallestValuePos) == smallestPositive);
0062   CPPUNIT_ASSERT(pack16base11closed(smallestValuePos) == smallestPositive);
0063   CPPUNIT_ASSERT(unpack16base11(smallestPositive) == smallestValuePos);
0064   CPPUNIT_ASSERT(unpack16base11closed(smallestPositive) == smallestValuePos);
0065 
0066   CPPUNIT_ASSERT(pack16base11(smallestValueNeg) == smallestNegative);
0067   CPPUNIT_ASSERT(pack16base11ceil(smallestValueNeg) == smallestNegative);
0068   CPPUNIT_ASSERT(unpack16base11(smallestNegative) == smallestValueNeg);
0069   CPPUNIT_ASSERT(unpack16base11(pack16base11(smallestValueNeg)) == smallestValueNeg);
0070   CPPUNIT_ASSERT(unpack16base11(pack16base11ceil(smallestValueNeg)) == smallestValueNeg);
0071   CPPUNIT_ASSERT(unpack16base11closed(pack16base11closed(smallestValueNegForClosed)) == smallestValueNegForClosed);
0072 
0073   CPPUNIT_ASSERT(pack16base11(smallestValuePos - std::exp(-16.)) == smallestPositive);
0074   CPPUNIT_ASSERT(pack16base11ceil(smallestValuePos - std::exp(-16.)) == smallestPositive);
0075   CPPUNIT_ASSERT(pack16base11closed(smallestValuePos - std::exp(-16.)) == smallestPositive);
0076   conv64.flt = smallestValuePos;
0077   conv64.i64 -= 1;
0078   const double smallestValuePosMinus1Ulp64 = conv64.flt;
0079   CPPUNIT_ASSERT(pack16base11(smallestValuePosMinus1Ulp64) == smallestPositive);
0080   CPPUNIT_ASSERT(pack16base11ceil(smallestValuePosMinus1Ulp64) == smallestPositive);
0081   CPPUNIT_ASSERT(pack16base11closed(smallestValuePosMinus1Ulp64) == smallestPositive);
0082 
0083   CPPUNIT_ASSERT(pack16base11(smallestValueNeg + std::exp(-16.)) == smallestNegative);
0084   CPPUNIT_ASSERT(pack16base11ceil(smallestValueNeg + std::exp(-16.)) == smallestNegative);
0085   CPPUNIT_ASSERT(unpack16base11(pack16base11(smallestValueNeg + std::exp(-16.))) == smallestValueNeg);
0086   CPPUNIT_ASSERT(unpack16base11(pack16base11ceil(smallestValueNeg + std::exp(-16.))) == smallestValueNeg);
0087   CPPUNIT_ASSERT(unpack16base11closed(pack16base11closed(smallestValueNegForClosed + std::exp(-16.))) ==
0088                  smallestValueNegForClosed);
0089   conv64.flt = smallestValueNeg;
0090   conv64.i64 += 1;
0091   const double smallestValueNegPlusUlp64 = conv64.flt;
0092   CPPUNIT_ASSERT(pack16base11(smallestValueNegPlusUlp64) == smallestNegative);
0093   CPPUNIT_ASSERT(pack16base11ceil(smallestValueNegPlusUlp64) == smallestNegative);
0094   CPPUNIT_ASSERT(unpack16base11(pack16base11(smallestValueNegPlusUlp64)) == smallestValueNeg);
0095   CPPUNIT_ASSERT(unpack16base11(pack16base11ceil(smallestValueNegPlusUlp64)) == smallestValueNeg);
0096   CPPUNIT_ASSERT(unpack16base11closed(pack16base11closed(smallestValueNegPlusUlp64)) == smallestValueNegForClosed);
0097 
0098   const double largestValuePos = std::exp(-15. + double(base - 1) / base * 15.);
0099   const double largestValueNeg = -largestValuePos;
0100   CPPUNIT_ASSERT(pack16base11(largestValuePos) == largestPositive);
0101   CPPUNIT_ASSERT(pack16base11ceil(largestValuePos) == largestPositive);
0102   CPPUNIT_ASSERT(unpack16base11(largestPositive) == largestValuePos);
0103 
0104   CPPUNIT_ASSERT(pack16base11(largestValueNeg) == largestNegative);
0105   CPPUNIT_ASSERT(pack16base11ceil(largestValueNeg) == largestNegative);
0106   CPPUNIT_ASSERT(unpack16base11(largestNegative) == largestValueNeg);
0107 
0108   CPPUNIT_ASSERT(pack16base11(largestValuePos + 0.1) == largestPositive);
0109   CPPUNIT_ASSERT(pack16base11ceil(largestValuePos + 0.1) == largestPositive);
0110 
0111   CPPUNIT_ASSERT(pack16base11(largestValueNeg - 0.1) == largestNegative);
0112   CPPUNIT_ASSERT(pack16base11ceil(largestValueNeg - 0.1) == largestNegative);
0113 
0114   const double largestValueClosedPos = std::exp(0.);
0115   const double largestValueClosedNeg = -largestValueClosedPos;
0116   CPPUNIT_ASSERT(pack16base11closed(largestValueClosedPos) == largestPositive);
0117   CPPUNIT_ASSERT(unpack16base11closed(largestPositive) == largestValueClosedPos);
0118   CPPUNIT_ASSERT(pack16base11closed(largestValueClosedNeg) == largestNegative);
0119   CPPUNIT_ASSERT(unpack16base11closed(largestNegative) == largestValueClosedNeg);
0120 
0121   CPPUNIT_ASSERT(pack16base11closed(largestValueClosedPos + 0.1) == largestPositive);
0122   CPPUNIT_ASSERT(pack16base11closed(largestValueClosedNeg - 0.1) == largestNegative);
0123 
0124   const double someValue = std::exp(-15. + 1. / base * 15.);
0125   const float someValueFloat = std::exp(-15.f + 1.f / float(base) * 15.f);
0126   CPPUNIT_ASSERT(unpack16base11(pack16base11ceil(someValue)) == someValue);
0127   CPPUNIT_ASSERT(static_cast<float>(unpack16base11(pack16base11ceil(someValue))) == someValueFloat);
0128 
0129   conv32.flt = someValueFloat;
0130   conv32.i32 += 1;
0131   const float someValuePlus1Ulp32 = conv32.flt;
0132   CPPUNIT_ASSERT(static_cast<float>(unpack16base11(pack16base11ceil(someValuePlus1Ulp32))) >= someValuePlus1Ulp32);
0133 
0134   conv64.flt = someValue;
0135   conv64.i64 += 1;
0136   const float someValuePlus1Ulp64 = conv64.flt;
0137   CPPUNIT_ASSERT(unpack16base11(pack16base11ceil(someValuePlus1Ulp64)) >= someValuePlus1Ulp64);
0138 }
0139 
0140 void testlogintpack::test8() {
0141   using logintpack::smallestNegative;
0142   using logintpack::smallestPositive;
0143   constexpr int8_t largestPositive = 127;
0144   constexpr int8_t largestNegative = -127;
0145 
0146   const double smallestValuePos = std::exp(-15.);
0147   const double smallestValueNeg = -std::exp(-15. + 1. / 128. * 15.);
0148   const double smallestValueNegForClosed = -std::exp(-15. + 1. / 127. * 15.);
0149   CPPUNIT_ASSERT(pack(smallestValuePos) == smallestPositive);
0150   CPPUNIT_ASSERT(packceil(smallestValuePos) == smallestPositive);
0151   CPPUNIT_ASSERT(packclosed(smallestValuePos) == smallestPositive);
0152   CPPUNIT_ASSERT(unpack(smallestPositive) == smallestValuePos);
0153   CPPUNIT_ASSERT(unpackclosed(smallestPositive) == smallestValuePos);
0154 
0155   CPPUNIT_ASSERT(pack(smallestValueNeg) == smallestNegative);
0156   CPPUNIT_ASSERT(packceil(smallestValueNeg) == smallestNegative);
0157   CPPUNIT_ASSERT(unpack(smallestNegative) == smallestValueNeg);
0158   CPPUNIT_ASSERT(unpack(pack(smallestValueNeg)) == smallestValueNeg);
0159   CPPUNIT_ASSERT(unpack(packceil(smallestValueNeg)) == smallestValueNeg);
0160   CPPUNIT_ASSERT(unpackclosed(packclosed(smallestValueNegForClosed)) == smallestValueNegForClosed);
0161 
0162   const double largestValuePos = std::exp(-15. + 127. / 128. * 15.);
0163   const double largestValueNeg = -largestValuePos;
0164   CPPUNIT_ASSERT(pack(largestValuePos) == largestPositive);
0165   CPPUNIT_ASSERT(packceil(largestValuePos) == largestPositive);
0166   CPPUNIT_ASSERT(unpack(largestPositive) == largestValuePos);
0167 
0168   CPPUNIT_ASSERT(pack(largestValueNeg) == largestNegative);
0169   CPPUNIT_ASSERT(packceil(largestValueNeg) == largestNegative);
0170   CPPUNIT_ASSERT(unpack(largestNegative) == largestValueNeg);
0171 
0172   const double largestValueClosedPos = std::exp(0.);
0173   const double largestValueClosedNeg = -largestValueClosedPos;
0174   CPPUNIT_ASSERT(packclosed(largestValueClosedPos) == largestPositive);
0175   CPPUNIT_ASSERT(unpackclosed(largestPositive) == largestValueClosedPos);
0176   CPPUNIT_ASSERT(packclosed(largestValueClosedNeg) == largestNegative);
0177   CPPUNIT_ASSERT(unpackclosed(largestNegative) == largestValueClosedNeg);
0178 
0179   const double someValue = std::exp(-15. + 1 / 128. * 15.);
0180   const float someValueFloat = std::exp(-15.f + 1 / 128.f * 15.f);
0181   CPPUNIT_ASSERT(unpack(packceil(someValue)) == someValue);
0182   CPPUNIT_ASSERT(static_cast<float>(unpack(packceil(someValue))) == someValueFloat);
0183   {
0184     union {
0185       float flt;
0186       uint32_t i32;
0187     } conv;
0188     conv.flt = someValueFloat;
0189     conv.i32 += 1;
0190     const float someValuePlus1Ulp32 = conv.flt;
0191     CPPUNIT_ASSERT(static_cast<float>(unpack(packceil(someValuePlus1Ulp32))) >= someValuePlus1Ulp32);
0192   }
0193   {
0194     union {
0195       double flt;
0196       uint64_t i64;
0197     } conv;
0198     conv.flt = someValue;
0199     conv.i64 += 1;
0200     const float someValuePlus1Ulp64 = conv.flt;
0201     CPPUNIT_ASSERT(unpack(packceil(someValuePlus1Ulp64)) >= someValuePlus1Ulp64);
0202   }
0203 }
0204 
0205 CPPUNIT_TEST_SUITE_REGISTRATION(testlogintpack);