fp_bits_ut.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include "fp_bits.h"
  2. #include <library/cpp/testing/unittest/registar.h>
  3. #include <util/system/valgrind.h>
  4. namespace NYql {
  5. namespace {
  6. template <typename T>
  7. void CanonizeFpBitsTest() {
  8. enum EValues {
  9. Zero,
  10. MZero,
  11. One,
  12. Half,
  13. Two,
  14. PMin,
  15. PMax,
  16. DNorm,
  17. PInf,
  18. NInf,
  19. QNan,
  20. SNan,
  21. INan,
  22. Max
  23. };
  24. T values[EValues::Max];
  25. T newValues[EValues::Max];
  26. int valuesClass[EValues::Max];
  27. values[Zero] = T(0);
  28. values[MZero] = -values[Zero];
  29. values[One] = T(1);
  30. values[Half] = values[One] / 2;
  31. values[Two] = values[One] * 2;
  32. values[PMin] = std::numeric_limits<T>::min();
  33. values[DNorm] = values[PMin] / 2;
  34. values[PMax] = std::numeric_limits<T>::max();
  35. values[PInf] = std::numeric_limits<T>::infinity();
  36. values[NInf] = -std::numeric_limits<T>::infinity();
  37. values[QNan] = std::numeric_limits<T>::quiet_NaN();
  38. values[SNan] = std::numeric_limits<T>::signaling_NaN();
  39. values[INan] = std::numeric_limits<T>::infinity() / std::numeric_limits<T>::infinity();
  40. for (int v = Zero; v < Max; ++v) {
  41. int cls;
  42. if (v <= MZero) {
  43. cls = FP_ZERO;
  44. } else if (v < DNorm) {
  45. cls = FP_NORMAL;
  46. } else if (v == DNorm) {
  47. cls = FP_SUBNORMAL;
  48. } else if (v < QNan) {
  49. cls = FP_INFINITE;
  50. } else {
  51. cls = FP_NAN;
  52. }
  53. valuesClass[v] = cls;
  54. }
  55. for (int v = Zero; v < Max; ++v) {
  56. UNIT_ASSERT_VALUES_EQUAL(std::fpclassify(values[v]), valuesClass[v]);
  57. }
  58. for (int v = Zero; v < Max; ++v) {
  59. newValues[v] = values[v];
  60. CanonizeFpBits<T>(&newValues[v]);
  61. }
  62. for (int v = Zero; v < Max; ++v) {
  63. UNIT_ASSERT_VALUES_EQUAL(std::fpclassify(newValues[v]), valuesClass[v]);
  64. }
  65. for (int v = Zero; v < Max; ++v) {
  66. int originalV = v;
  67. if (v == MZero) {
  68. originalV = Zero;
  69. } else if (v >= QNan) {
  70. originalV = QNan;
  71. }
  72. UNIT_ASSERT(std::memcmp((const void*)&newValues[v], (const void*)&values[originalV], std::min(size_t(10), sizeof(T))) == 0);
  73. }
  74. }
  75. }
  76. Y_UNIT_TEST_SUITE(TFpBits) {
  77. Y_UNIT_TEST(CanonizeFloat) {
  78. CanonizeFpBitsTest<float>();
  79. }
  80. Y_UNIT_TEST(CanonizeDouble) {
  81. CanonizeFpBitsTest<double>();
  82. }
  83. Y_UNIT_TEST(CanonizeLongDouble) {
  84. if (NValgrind::ValgrindIsOn()) {
  85. return; // TODO KIKIMR-3431
  86. }
  87. CanonizeFpBitsTest<long double>();
  88. }
  89. }
  90. }