Math_test.cc 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #include "catch.hpp"
  2. #include "Math.hh"
  3. TEST_CASE("Math::log2p1")
  4. {
  5. CHECK(Math::log2p1(0) == 0);
  6. CHECK(Math::log2p1(1) == 1);
  7. CHECK(Math::log2p1(2) == 2);
  8. CHECK(Math::log2p1(3) == 2);
  9. CHECK(Math::log2p1(4) == 3);
  10. CHECK(Math::log2p1(5) == 3);
  11. CHECK(Math::log2p1(6) == 3);
  12. CHECK(Math::log2p1(7) == 3);
  13. CHECK(Math::log2p1(8) == 4);
  14. CHECK(Math::log2p1(9) == 4);
  15. CHECK(Math::log2p1(127) == 7);
  16. CHECK(Math::log2p1(128) == 8);
  17. CHECK(Math::log2p1(129) == 8);
  18. CHECK(Math::log2p1(255) == 8);
  19. CHECK(Math::log2p1(256) == 9);
  20. constexpr auto x = Math::log2p1(255); static_assert(x == 8);
  21. }
  22. TEST_CASE("Math::ispow2")
  23. {
  24. CHECK(!Math::ispow2(0));
  25. CHECK( Math::ispow2(1));
  26. CHECK( Math::ispow2(2));
  27. CHECK(!Math::ispow2(3));
  28. CHECK( Math::ispow2(4));
  29. CHECK(!Math::ispow2(5));
  30. CHECK(!Math::ispow2(6));
  31. CHECK(!Math::ispow2(7));
  32. CHECK( Math::ispow2(8));
  33. CHECK(!Math::ispow2(9));
  34. CHECK(!Math::ispow2(15));
  35. CHECK( Math::ispow2(16));
  36. CHECK(!Math::ispow2(17));
  37. CHECK( Math::ispow2(32));
  38. CHECK( Math::ispow2(64));
  39. CHECK(!Math::ispow2(255));
  40. CHECK( Math::ispow2(256));
  41. CHECK( Math::ispow2(512));
  42. CHECK( Math::ispow2(1024));
  43. CHECK( Math::ispow2(2048));
  44. CHECK( Math::ispow2(4096));
  45. CHECK( Math::ispow2(8192));
  46. CHECK(!Math::ispow2(0xffff));
  47. CHECK( Math::ispow2(0x10000));
  48. CHECK( Math::ispow2(0x80000000));
  49. CHECK(!Math::ispow2(0xffffffff));
  50. }
  51. TEST_CASE("Math::ceil2")
  52. {
  53. CHECK(Math::ceil2(0) == 1);
  54. CHECK(Math::ceil2(1) == 1);
  55. CHECK(Math::ceil2(2) == 2);
  56. CHECK(Math::ceil2(3) == 4);
  57. CHECK(Math::ceil2(4) == 4);
  58. CHECK(Math::ceil2(5) == 8);
  59. CHECK(Math::ceil2(6) == 8);
  60. CHECK(Math::ceil2(7) == 8);
  61. CHECK(Math::ceil2(8) == 8);
  62. CHECK(Math::ceil2(9) == 16);
  63. CHECK(Math::ceil2(15) == 16);
  64. CHECK(Math::ceil2(16) == 16);
  65. CHECK(Math::ceil2(17) == 32);
  66. CHECK(Math::ceil2(32) == 32);
  67. CHECK(Math::ceil2(64) == 64);
  68. CHECK(Math::ceil2(255) == 256);
  69. CHECK(Math::ceil2(256) == 256);
  70. CHECK(Math::ceil2(512) == 512);
  71. CHECK(Math::ceil2(1024) == 1024);
  72. CHECK(Math::ceil2(2048) == 2048);
  73. CHECK(Math::ceil2(4096) == 4096);
  74. CHECK(Math::ceil2(8192) == 8192);
  75. CHECK(Math::ceil2(0xffff) == 0x10000);
  76. CHECK(Math::ceil2(0x10000) == 0x10000);
  77. CHECK(Math::ceil2(0x80000000) == 0x80000000);
  78. // values > 0x80000000 don't work,
  79. // result can't be represented in 32bit
  80. }
  81. TEST_CASE("Math::clip")
  82. {
  83. CHECK((Math::clip<10, 20>(-6)) == 10);
  84. CHECK((Math::clip<10, 20>( 0)) == 10);
  85. CHECK((Math::clip<10, 20>( 9)) == 10);
  86. CHECK((Math::clip<10, 20>(10)) == 10);
  87. CHECK((Math::clip<10, 20>(11)) == 11);
  88. CHECK((Math::clip<10, 20>(14)) == 14);
  89. CHECK((Math::clip<10, 20>(19)) == 19);
  90. CHECK((Math::clip<10, 20>(20)) == 20);
  91. CHECK((Math::clip<10, 20>(21)) == 20);
  92. CHECK((Math::clip<10, 20>(99)) == 20);
  93. CHECK((Math::clip<10, 10>( 9)) == 10);
  94. CHECK((Math::clip<10, 10>(10)) == 10);
  95. CHECK((Math::clip<10, 10>(11)) == 10);
  96. CHECK((Math::clip<-10, 10>(-20)) == -10);
  97. CHECK((Math::clip<-10, 10>( -3)) == -3);
  98. CHECK((Math::clip<-10, 10>( 20)) == 10);
  99. CHECK((Math::clip<-100, -10>(-200)) == -100);
  100. CHECK((Math::clip<-100, -10>( -53)) == -53);
  101. CHECK((Math::clip<-100, -10>( 200)) == -10);
  102. // ok, compiler error (invalid range)
  103. //CHECK((Math::clip<6, 3>(1)) == 1);
  104. }
  105. TEST_CASE("Math::clipIntToShort")
  106. {
  107. CHECK(Math::clipIntToShort(-100000) == -32768);
  108. CHECK(Math::clipIntToShort( -32769) == -32768);
  109. CHECK(Math::clipIntToShort( -32768) == -32768);
  110. CHECK(Math::clipIntToShort( -32767) == -32767);
  111. CHECK(Math::clipIntToShort( -10000) == -10000);
  112. CHECK(Math::clipIntToShort( -10) == -10);
  113. CHECK(Math::clipIntToShort( -1) == -1);
  114. CHECK(Math::clipIntToShort( 0) == 0);
  115. CHECK(Math::clipIntToShort( 1) == 1);
  116. CHECK(Math::clipIntToShort( 10) == 10);
  117. CHECK(Math::clipIntToShort( 9876) == 9876);
  118. CHECK(Math::clipIntToShort( 32766) == 32766);
  119. CHECK(Math::clipIntToShort( 32767) == 32767);
  120. CHECK(Math::clipIntToShort( 32768) == 32767);
  121. CHECK(Math::clipIntToShort( 100000) == 32767);
  122. }
  123. TEST_CASE("Math::clipIntToByte")
  124. {
  125. CHECK(Math::clipIntToByte(-100) == 0);
  126. CHECK(Math::clipIntToByte( -27) == 0);
  127. CHECK(Math::clipIntToByte( -1) == 0);
  128. CHECK(Math::clipIntToByte( 0) == 0);
  129. CHECK(Math::clipIntToByte( 1) == 1);
  130. CHECK(Math::clipIntToByte( 10) == 10);
  131. CHECK(Math::clipIntToByte( 127) == 127);
  132. CHECK(Math::clipIntToByte( 128) == 128);
  133. CHECK(Math::clipIntToByte( 222) == 222);
  134. CHECK(Math::clipIntToByte( 255) == 255);
  135. CHECK(Math::clipIntToByte( 256) == 255);
  136. CHECK(Math::clipIntToByte( 257) == 255);
  137. CHECK(Math::clipIntToByte( 327) == 255);
  138. }
  139. static unsigned classic_gcd(unsigned a, unsigned b)
  140. {
  141. while (unsigned t = b % a) { b = a; a = t; }
  142. return a;
  143. }
  144. static void testGcd(unsigned a, unsigned b)
  145. {
  146. unsigned expected = classic_gcd(a, b);
  147. CHECK(Math::gcd(a, b) == expected);
  148. CHECK(Math::gcd(b, a) == expected);
  149. }
  150. TEST_CASE("Math::gcd")
  151. {
  152. testGcd(1, 1);
  153. testGcd(1, 2);
  154. testGcd(1, 1234500);
  155. testGcd(14, 1);
  156. testGcd(14, 2);
  157. testGcd(14, 7);
  158. testGcd(14, 21);
  159. testGcd(14, 291);
  160. testGcd(14, 6398);
  161. testGcd(1464, 6398);
  162. testGcd(1464, 6398);
  163. CHECK(Math::gcd(320, 1280) == 320);
  164. CHECK(Math::gcd(123 * 121972, 123 * 9710797) == 123);
  165. }
  166. static void testReverseNBits(unsigned x, unsigned n, unsigned expected)
  167. {
  168. CHECK(Math::reverseNBits(x, n) == expected);
  169. CHECK(Math::reverseNBits(expected, n) == x);
  170. }
  171. TEST_CASE("Math::reverseNBits")
  172. {
  173. testReverseNBits(0x0, 4, 0x0);
  174. testReverseNBits(0x1, 4, 0x8);
  175. testReverseNBits(0x2, 4, 0x4);
  176. testReverseNBits(0x3, 4, 0xC);
  177. testReverseNBits(0x4, 4, 0x2);
  178. testReverseNBits(0x8, 4, 0x1);
  179. testReverseNBits(0x6, 4, 0x6);
  180. testReverseNBits(0xE, 4, 0x7);
  181. testReverseNBits(0xF, 4, 0xF);
  182. testReverseNBits(0x00012345, 22, 0x0028B120);
  183. testReverseNBits(0x0010000F, 32, 0xF0000800);
  184. }
  185. static void testReverseByte(uint8_t x, uint8_t expected)
  186. {
  187. CHECK(Math::reverseByte (x ) == expected);
  188. CHECK(Math::reverseNBits(x, 8) == expected);
  189. CHECK(Math::reverseByte (expected ) == x);
  190. CHECK(Math::reverseNBits(expected, 8) == x);
  191. }
  192. TEST_CASE("Math::reverseByte")
  193. {
  194. testReverseByte(0x00, 0x00);
  195. testReverseByte(0x01, 0x80);
  196. testReverseByte(0x02, 0x40);
  197. testReverseByte(0x07, 0xE0);
  198. testReverseByte(0x12, 0x48);
  199. testReverseByte(0x73, 0xCE);
  200. testReverseByte(0x7F, 0xFE);
  201. testReverseByte(0x8C, 0x31);
  202. testReverseByte(0xAB, 0xD5);
  203. testReverseByte(0xE4, 0x27);
  204. testReverseByte(0xF0, 0x0F);
  205. }
  206. TEST_CASE("Math::floodRight")
  207. {
  208. CHECK(Math::floodRight(0) == 0);
  209. CHECK(Math::floodRight(1) == 1);
  210. CHECK(Math::floodRight(2) == 3);
  211. CHECK(Math::floodRight(3) == 3);
  212. CHECK(Math::floodRight(4) == 7);
  213. CHECK(Math::floodRight(5) == 7);
  214. CHECK(Math::floodRight(6) == 7);
  215. CHECK(Math::floodRight(7) == 7);
  216. CHECK(Math::floodRight(8) == 15);
  217. CHECK(Math::floodRight(9) == 15);
  218. CHECK(Math::floodRight(15) == 15);
  219. CHECK(Math::floodRight(16) == 31);
  220. CHECK(Math::floodRight(32) == 63);
  221. CHECK(Math::floodRight(64) == 127);
  222. CHECK(Math::floodRight(12345) == 16383);
  223. CHECK(Math::floodRight(0x7F001234) == 0x7FFFFFFF);
  224. CHECK(Math::floodRight(0x80000000) == 0xFFFFFFFF);
  225. CHECK(Math::floodRight(0xF0FEDCBA) == 0xFFFFFFFF);
  226. CHECK(Math::floodRight(0x1234F0FEDCBAULL) == 0x1FFFFFFFFFFFULL);
  227. CHECK(Math::floodRight(uint8_t(0x12)) == uint8_t(0x1F));
  228. CHECK(Math::floodRight(uint16_t(0x2512)) == uint16_t(0x3FFF));
  229. }
  230. TEST_CASE("Math::countLeadingZeros")
  231. {
  232. // undefined for 0
  233. CHECK(Math::countLeadingZeros(0x00000001) == 31);
  234. CHECK(Math::countLeadingZeros(0x00000002) == 30);
  235. CHECK(Math::countLeadingZeros(0x00000003) == 30);
  236. CHECK(Math::countLeadingZeros(0x00000004) == 29);
  237. CHECK(Math::countLeadingZeros(0x00000005) == 29);
  238. CHECK(Math::countLeadingZeros(0x00000007) == 29);
  239. CHECK(Math::countLeadingZeros(0x00000008) == 28);
  240. CHECK(Math::countLeadingZeros(0x00000081) == 24);
  241. CHECK(Math::countLeadingZeros(0x00000134) == 23);
  242. CHECK(Math::countLeadingZeros(0x00000234) == 22);
  243. CHECK(Math::countLeadingZeros(0x00008234) == 16);
  244. CHECK(Math::countLeadingZeros(0x00021234) == 14);
  245. CHECK(Math::countLeadingZeros(0x00421234) == 9);
  246. CHECK(Math::countLeadingZeros(0x01421234) == 7);
  247. CHECK(Math::countLeadingZeros(0x01421234) == 7);
  248. CHECK(Math::countLeadingZeros(0x11421234) == 3);
  249. CHECK(Math::countLeadingZeros(0x31421234) == 2);
  250. CHECK(Math::countLeadingZeros(0x61421234) == 1);
  251. CHECK(Math::countLeadingZeros(0x91421234) == 0);
  252. CHECK(Math::countLeadingZeros(0xF1421234) == 0);
  253. }