int128_old_ut.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include <library/cpp/testing/unittest/registar.h>
  2. #include <library/cpp/int128/int128.h>
  3. #include "int128_ut_helpers.h"
  4. class TUInt128Test: public TTestBase {
  5. UNIT_TEST_SUITE(TUInt128Test);
  6. UNIT_TEST(Create);
  7. UNIT_TEST(Minus);
  8. UNIT_TEST(Plus);
  9. UNIT_TEST(Shift)
  10. UNIT_TEST(Overflow);
  11. UNIT_TEST(Underflow);
  12. UNIT_TEST(ToStringTest);
  13. UNIT_TEST(FromStringTest);
  14. #if defined(Y_HAVE_INT128)
  15. UNIT_TEST(FromSystemUint128);
  16. #endif
  17. UNIT_TEST_SUITE_END();
  18. private:
  19. void Create();
  20. void Minus();
  21. void Plus();
  22. void Shift();
  23. void Overflow();
  24. void Underflow();
  25. void ToStringTest();
  26. void FromStringTest();
  27. #if defined(Y_HAVE_INT128)
  28. void FromSystemUint128();
  29. #endif
  30. };
  31. UNIT_TEST_SUITE_REGISTRATION(TUInt128Test);
  32. void TUInt128Test::Create() {
  33. const ui128 n1 = 10;
  34. UNIT_ASSERT_EQUAL(n1, 10);
  35. const ui128 n2 = n1;
  36. UNIT_ASSERT_EQUAL(n2, 10);
  37. const ui128 n3(10);
  38. UNIT_ASSERT_EQUAL(n3, 10);
  39. }
  40. void TUInt128Test::Minus() {
  41. const ui128 n2 = 20;
  42. const ui128 n3 = 30;
  43. ui128 n4 = n3 - n2;
  44. UNIT_ASSERT_EQUAL(n4, 10);
  45. n4 = n4 - 2;
  46. UNIT_ASSERT_EQUAL(n4, 8);
  47. n4 -= 2;
  48. UNIT_ASSERT_EQUAL(n4, 6);
  49. n4 = 10 - n4;
  50. UNIT_ASSERT_EQUAL(n4, 4);
  51. }
  52. void TUInt128Test::Plus() {
  53. const ui128 n2 = 20;
  54. const ui128 n3 = 30;
  55. ui128 n4 = n3 + n2;
  56. UNIT_ASSERT_EQUAL(n4, 50);
  57. n4 = n4 + 2;
  58. UNIT_ASSERT_EQUAL(n4, 52);
  59. n4 += 2;
  60. UNIT_ASSERT_EQUAL(n4, 54);
  61. n4 = 10 + n4;
  62. UNIT_ASSERT_EQUAL(n4, 64);
  63. }
  64. void TUInt128Test::Shift() {
  65. ui128 n = 1;
  66. const ui128 n4 = n << 4;
  67. UNIT_ASSERT_EQUAL(n4, ui128(0x0, 0x0000000000000010));
  68. UNIT_ASSERT_EQUAL(n4 >> 4, 1);
  69. const ui128 n8 = n << 8;
  70. UNIT_ASSERT_EQUAL(n8, ui128(0x0, 0x0000000000000100));
  71. UNIT_ASSERT_EQUAL(n8 >> 8, 1);
  72. const ui128 n60 = n << 60;
  73. UNIT_ASSERT_EQUAL(n60, ui128(0x0, 0x1000000000000000));
  74. UNIT_ASSERT_EQUAL(n60 >> 60, 1);
  75. const ui128 n64 = n << 64;
  76. UNIT_ASSERT_EQUAL(n64, ui128(0x1, 0x0000000000000000));
  77. UNIT_ASSERT_EQUAL(n64 >> 64, 1);
  78. const ui128 n124 = n << 124;
  79. UNIT_ASSERT_EQUAL(n124, ui128(0x1000000000000000, 0x0000000000000000));
  80. UNIT_ASSERT_EQUAL(n124 >> 124, 1);
  81. }
  82. void TUInt128Test::Overflow() {
  83. ui128 n = ui128(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF);
  84. const ui128 n2 = n + 2;
  85. UNIT_ASSERT_EQUAL(n2, 1);
  86. }
  87. void TUInt128Test::Underflow() {
  88. ui128 n = 1;
  89. const ui128 n128 = n - 2;
  90. UNIT_ASSERT_EQUAL(n128, ui128(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF));
  91. }
  92. void TUInt128Test::ToStringTest() {
  93. ui128 n(0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF);
  94. TString correct = "340282366920938463463374607431768211455";
  95. UNIT_ASSERT_EQUAL(correct, ::ToString(n));
  96. }
  97. void TUInt128Test::FromStringTest() {
  98. {
  99. const TString originalString = "37778931862957161709568";
  100. const ui128 number = FromString<ui128>(originalString);
  101. UNIT_ASSERT_EQUAL(ToString(number), originalString);
  102. }
  103. {
  104. const TString originalString = "1024";
  105. const ui128 number = FromString<ui128>(originalString);
  106. UNIT_ASSERT_EQUAL(ToString(number), originalString);
  107. UNIT_ASSERT_EQUAL(GetHigh(number), 0);
  108. UNIT_ASSERT_EQUAL(GetLow(number), 1024);
  109. }
  110. {
  111. const TString originalString = "18446744073709551616"; // 2^64, i.e. UINT64_MAX + 1
  112. const ui128 number = FromString<ui128>(originalString);
  113. UNIT_ASSERT_EQUAL(ToString(number), originalString);
  114. UNIT_ASSERT_EQUAL(GetHigh(number), 1);
  115. UNIT_ASSERT_EQUAL(GetLow(number), 0);
  116. }
  117. {
  118. const TString originalString = "340282366920938463463374607431768211455"; // 2^128-1, i.e. UINT128_MAX
  119. const ui128 number = FromString<ui128>(originalString);
  120. UNIT_ASSERT_EQUAL(ToString(number), originalString);
  121. UNIT_ASSERT_EQUAL(GetHigh(number), 0xFFFFFFFFFFFFFFFF);
  122. UNIT_ASSERT_EQUAL(GetLow(number), 0xFFFFFFFFFFFFFFFF);
  123. }
  124. }
  125. #if defined(Y_HAVE_INT128)
  126. void TUInt128Test::FromSystemUint128() {
  127. unsigned __int128 n = 1;
  128. ui128 number{n};
  129. UNIT_ASSERT_EQUAL(GetLow(number), 1);
  130. UNIT_ASSERT_EQUAL(GetHigh(number), 0);
  131. auto byteArray = NInt128Private::GetAsArray(number);
  132. #ifdef _little_endian_
  133. UNIT_ASSERT_EQUAL(byteArray[0], 1);
  134. for (size_t i = 1; i < 16; i++) {
  135. UNIT_ASSERT_EQUAL(byteArray[i], 0);
  136. }
  137. #elif defined(_big_endian_)
  138. UNIT_ASSERT_EQUAL(byteArray[15], 1);
  139. for (size_t i = 0; i < 15; i++) {
  140. UNIT_ASSERT_EQUAL(byteArray[i], 0);
  141. }
  142. #endif
  143. UNIT_ASSERT_EQUAL(std::memcmp((void*)&n, (void*)&number, 16), 0);
  144. UNIT_ASSERT_EQUAL(ToString(n), "1");
  145. UNIT_ASSERT_EQUAL(FromString<unsigned __int128>(ToString(n)), n);
  146. }
  147. #endif