core_func_integer.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////
  2. // OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
  3. ///////////////////////////////////////////////////////////////////////////////////////////////////
  4. // Created : 2011-05-03
  5. // Updated : 2011-05-03
  6. // Licence : This source is under MIT licence
  7. // File : test/core/func_integer.cpp
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////
  9. #include <glm/integer.hpp>
  10. #include <glm/gtc/vec1.hpp>
  11. #include <iostream>
  12. #include <vector>
  13. #include <ctime>
  14. enum result
  15. {
  16. SUCCESS,
  17. FAIL,
  18. ASSERT,
  19. STATIC_ASSERT
  20. };
  21. namespace bitfieldInsert
  22. {
  23. template <typename genType, typename sizeType>
  24. struct type
  25. {
  26. genType Base;
  27. genType Insert;
  28. sizeType Offset;
  29. sizeType Bits;
  30. genType Return;
  31. };
  32. typedef type<glm::uint, glm::uint> typeU32;
  33. typeU32 const Data32[] =
  34. {
  35. {0xff000000, 0x0000ff00, 8, 8, 0xff00ff00},
  36. {0xffff0000, 0x0000ffff, 16, 16, 0x00000000},
  37. {0x0000ffff, 0xffff0000, 16, 16, 0xffffffff},
  38. {0x00000000, 0xffffffff, 0, 32, 0xffffffff},
  39. {0x00000000, 0xffffffff, 0, 0, 0x00000000}
  40. };
  41. int test()
  42. {
  43. int Error = 0;
  44. glm::uint count = sizeof(Data32) / sizeof(typeU32);
  45. for(glm::uint i = 0; i < count; ++i)
  46. {
  47. glm::uint Return = glm::bitfieldInsert(
  48. Data32[i].Base,
  49. Data32[i].Insert,
  50. Data32[i].Offset,
  51. Data32[i].Bits);
  52. Error += Data32[i].Return == Return ? 0 : 1;
  53. }
  54. return Error;
  55. }
  56. }//bitfieldInsert
  57. namespace bitfieldExtract
  58. {
  59. template <typename genType, typename sizeType>
  60. struct type
  61. {
  62. genType Value;
  63. sizeType Offset;
  64. sizeType Bits;
  65. genType Return;
  66. result Result;
  67. };
  68. typedef type<glm::uint, glm::uint> typeU32;
  69. typeU32 const Data32[] =
  70. {
  71. {0xffffffff, 0,32, 0xffffffff, SUCCESS},
  72. {0xffffffff, 8, 0, 0x00000000, SUCCESS},
  73. {0x00000000, 0,32, 0x00000000, SUCCESS},
  74. {0x0f0f0f0f, 0,32, 0x0f0f0f0f, SUCCESS},
  75. {0x00000000, 8, 0, 0x00000000, SUCCESS},
  76. {0x80000000,31, 1, 0x00000001, SUCCESS},
  77. {0x7fffffff,31, 1, 0x00000000, SUCCESS},
  78. {0x00000300, 8, 8, 0x00000003, SUCCESS},
  79. {0x0000ff00, 8, 8, 0x000000ff, SUCCESS},
  80. {0xfffffff0, 0, 5, 0x00000010, SUCCESS},
  81. {0x000000ff, 1, 3, 0x00000007, SUCCESS},
  82. {0x000000ff, 0, 3, 0x00000007, SUCCESS},
  83. {0x00000000, 0, 2, 0x00000000, SUCCESS},
  84. {0xffffffff, 0, 8, 0x000000ff, SUCCESS},
  85. {0xffff0000,16,16, 0x0000ffff, SUCCESS},
  86. {0xfffffff0, 0, 8, 0x00000000, FAIL},
  87. {0xffffffff,16,16, 0x00000000, FAIL},
  88. //{0xffffffff,32, 1, 0x00000000, ASSERT}, // Throw an assert
  89. //{0xffffffff, 0,33, 0x00000000, ASSERT}, // Throw an assert
  90. //{0xffffffff,16,16, 0x00000000, ASSERT}, // Throw an assert
  91. };
  92. int test()
  93. {
  94. int Error = 0;
  95. glm::uint count = sizeof(Data32) / sizeof(typeU32);
  96. for(glm::uint i = 0; i < count; ++i)
  97. {
  98. glm::uint Return = glm::bitfieldExtract(
  99. Data32[i].Value,
  100. Data32[i].Offset,
  101. Data32[i].Bits);
  102. bool Compare = Data32[i].Return == Return;
  103. if(Data32[i].Result == SUCCESS && Compare)
  104. continue;
  105. else if(Data32[i].Result == FAIL && !Compare)
  106. continue;
  107. Error += 1;
  108. }
  109. return Error;
  110. }
  111. }//extractField
  112. namespace bitfieldReverse
  113. {
  114. template <typename genType>
  115. struct type
  116. {
  117. genType Value;
  118. genType Return;
  119. result Result;
  120. };
  121. typedef type<glm::uint> typeU32;
  122. typeU32 const Data32[] =
  123. {
  124. {0xffffffff, 0xffffffff, SUCCESS},
  125. {0x00000000, 0x00000000, SUCCESS},
  126. {0xf0000000, 0x0000000f, SUCCESS},
  127. };
  128. int test()
  129. {
  130. glm::uint count = sizeof(Data32) / sizeof(typeU32);
  131. for(glm::uint i = 0; i < count; ++i)
  132. {
  133. glm::uint Return = glm::bitfieldReverse(
  134. Data32[i].Value);
  135. bool Compare = Data32[i].Return == Return;
  136. if(Data32[i].Result == SUCCESS && Compare)
  137. continue;
  138. else if(Data32[i].Result == FAIL && !Compare)
  139. continue;
  140. std::cout << "glm::bitfieldReverse test fail on test " << i << std::endl;
  141. return 1;
  142. }
  143. return 0;
  144. }
  145. }//bitRevert
  146. namespace findMSB
  147. {
  148. template <typename genType>
  149. struct type
  150. {
  151. genType Value;
  152. genType Return;
  153. };
  154. type<int> const DataI32[] =
  155. {
  156. {0x00000000, -1},
  157. {0x00000001, 0},
  158. {0x00000002, 1},
  159. {0x00000003, 1},
  160. {0x00000004, 2},
  161. {0x00000005, 2},
  162. {0x00000007, 2},
  163. {0x00000008, 3},
  164. {0x00000010, 4},
  165. {0x00000020, 5},
  166. {0x00000040, 6},
  167. {0x00000080, 7},
  168. {0x00000100, 8},
  169. {0x00000200, 9},
  170. {0x00000400, 10},
  171. {0x00000800, 11},
  172. {0x00001000, 12},
  173. {0x00002000, 13},
  174. {0x00004000, 14},
  175. {0x00008000, 15},
  176. {0x00010000, 16},
  177. {0x00020000, 17},
  178. {0x00040000, 18},
  179. {0x00080000, 19},
  180. {0x00100000, 20},
  181. {0x00200000, 21},
  182. {0x00400000, 22},
  183. {0x00800000, 23},
  184. {0x01000000, 24},
  185. {0x02000000, 25},
  186. {0x04000000, 26},
  187. {0x08000000, 27},
  188. {0x10000000, 28},
  189. {0x20000000, 29},
  190. {0x40000000, 30}
  191. };
  192. int test()
  193. {
  194. int Error(0);
  195. for(std::size_t i = 0; i < sizeof(DataI32) / sizeof(type<int>); ++i)
  196. {
  197. int Result = glm::findMSB(DataI32[i].Value);
  198. Error += DataI32[i].Return == Result ? 0 : 1;
  199. assert(!Error);
  200. }
  201. return Error;
  202. }
  203. }//findMSB
  204. namespace findLSB
  205. {
  206. template <typename genType>
  207. struct type
  208. {
  209. genType Value;
  210. genType Return;
  211. };
  212. type<int> const DataI32[] =
  213. {
  214. {0x00000001, 0},
  215. {0x00000003, 0},
  216. {0x00000002, 1}
  217. };
  218. int test()
  219. {
  220. int Error(0);
  221. for(std::size_t i = 0; i < sizeof(DataI32) / sizeof(type<int>); ++i)
  222. {
  223. int Result = glm::findLSB(DataI32[i].Value);
  224. Error += DataI32[i].Return == Result ? 0 : 1;
  225. assert(!Error);
  226. }
  227. return Error;
  228. }
  229. }//findLSB
  230. namespace uaddCarry
  231. {
  232. int test()
  233. {
  234. int Error(0);
  235. {
  236. glm::uint x = 16;
  237. glm::uint y = 17;
  238. glm::uint Carry = 0;
  239. glm::uint Result = glm::uaddCarry(x, y, Carry);
  240. Error += Carry == 1 ? 0 : 1;
  241. Error += Result == 33 ? 0 : 1;
  242. }
  243. {
  244. glm::uvec1 x(16);
  245. glm::uvec1 y(17);
  246. glm::uvec1 Carry(0);
  247. glm::uvec1 Result(glm::uaddCarry(x, y, Carry));
  248. Error += glm::all(glm::equal(Carry, glm::uvec1(1))) ? 0 : 1;
  249. Error += glm::all(glm::equal(Result, glm::uvec1(33))) ? 0 : 1;
  250. }
  251. {
  252. glm::uvec2 x(16);
  253. glm::uvec2 y(17);
  254. glm::uvec2 Carry(0);
  255. glm::uvec2 Result(glm::uaddCarry(x, y, Carry));
  256. Error += glm::all(glm::equal(Carry, glm::uvec2(1))) ? 0 : 1;
  257. Error += glm::all(glm::equal(Result, glm::uvec2(33))) ? 0 : 1;
  258. }
  259. {
  260. glm::uvec3 x(16);
  261. glm::uvec3 y(17);
  262. glm::uvec3 Carry(0);
  263. glm::uvec3 Result(glm::uaddCarry(x, y, Carry));
  264. Error += glm::all(glm::equal(Carry, glm::uvec3(1))) ? 0 : 1;
  265. Error += glm::all(glm::equal(Result, glm::uvec3(33))) ? 0 : 1;
  266. }
  267. {
  268. glm::uvec4 x(16);
  269. glm::uvec4 y(17);
  270. glm::uvec4 Carry(0);
  271. glm::uvec4 Result(glm::uaddCarry(x, y, Carry));
  272. Error += glm::all(glm::equal(Carry, glm::uvec4(1))) ? 0 : 1;
  273. Error += glm::all(glm::equal(Result, glm::uvec4(33))) ? 0 : 1;
  274. }
  275. return Error;
  276. }
  277. }//namespace uaddCarry
  278. namespace usubBorrow
  279. {
  280. int test()
  281. {
  282. int Error(0);
  283. {
  284. glm::uint x = 16;
  285. glm::uint y = 17;
  286. glm::uint Borrow = 0;
  287. glm::uint Result = glm::usubBorrow(x, y, Borrow);
  288. Error += Borrow == 1 ? 0 : 1;
  289. Error += Result == 1 ? 0 : 1;
  290. }
  291. {
  292. glm::uvec1 x(16);
  293. glm::uvec1 y(17);
  294. glm::uvec1 Borrow(0);
  295. glm::uvec1 Result(glm::usubBorrow(x, y, Borrow));
  296. Error += glm::all(glm::equal(Borrow, glm::uvec1(1))) ? 0 : 1;
  297. Error += glm::all(glm::equal(Result, glm::uvec1(1))) ? 0 : 1;
  298. }
  299. {
  300. glm::uvec2 x(16);
  301. glm::uvec2 y(17);
  302. glm::uvec2 Borrow(0);
  303. glm::uvec2 Result(glm::usubBorrow(x, y, Borrow));
  304. Error += glm::all(glm::equal(Borrow, glm::uvec2(1))) ? 0 : 1;
  305. Error += glm::all(glm::equal(Result, glm::uvec2(1))) ? 0 : 1;
  306. }
  307. {
  308. glm::uvec3 x(16);
  309. glm::uvec3 y(17);
  310. glm::uvec3 Borrow(0);
  311. glm::uvec3 Result(glm::usubBorrow(x, y, Borrow));
  312. Error += glm::all(glm::equal(Borrow, glm::uvec3(1))) ? 0 : 1;
  313. Error += glm::all(glm::equal(Result, glm::uvec3(1))) ? 0 : 1;
  314. }
  315. {
  316. glm::uvec4 x(16);
  317. glm::uvec4 y(17);
  318. glm::uvec4 Borrow(0);
  319. glm::uvec4 Result(glm::usubBorrow(x, y, Borrow));
  320. Error += glm::all(glm::equal(Borrow, glm::uvec4(1))) ? 0 : 1;
  321. Error += glm::all(glm::equal(Result, glm::uvec4(1))) ? 0 : 1;
  322. }
  323. return Error;
  324. }
  325. }//namespace usubBorrow
  326. namespace umulExtended
  327. {
  328. int test()
  329. {
  330. int Error(0);
  331. {
  332. glm::uint x = 2;
  333. glm::uint y = 3;
  334. glm::uint msb = 0;
  335. glm::uint lsb = 0;
  336. glm::umulExtended(x, y, msb, lsb);
  337. Error += msb == 0 ? 0 : 1;
  338. Error += lsb == 6 ? 0 : 1;
  339. }
  340. {
  341. glm::uvec1 x(2);
  342. glm::uvec1 y(3);
  343. glm::uvec1 msb(0);
  344. glm::uvec1 lsb(0);
  345. glm::umulExtended(x, y, msb, lsb);
  346. Error += glm::all(glm::equal(msb, glm::uvec1(0))) ? 0 : 1;
  347. Error += glm::all(glm::equal(lsb, glm::uvec1(6))) ? 0 : 1;
  348. }
  349. {
  350. glm::uvec2 x(2);
  351. glm::uvec2 y(3);
  352. glm::uvec2 msb(0);
  353. glm::uvec2 lsb(0);
  354. glm::umulExtended(x, y, msb, lsb);
  355. Error += glm::all(glm::equal(msb, glm::uvec2(0))) ? 0 : 1;
  356. Error += glm::all(glm::equal(lsb, glm::uvec2(6))) ? 0 : 1;
  357. }
  358. {
  359. glm::uvec3 x(2);
  360. glm::uvec3 y(3);
  361. glm::uvec3 msb(0);
  362. glm::uvec3 lsb(0);
  363. glm::umulExtended(x, y, msb, lsb);
  364. Error += glm::all(glm::equal(msb, glm::uvec3(0))) ? 0 : 1;
  365. Error += glm::all(glm::equal(lsb, glm::uvec3(6))) ? 0 : 1;
  366. }
  367. {
  368. glm::uvec4 x(2);
  369. glm::uvec4 y(3);
  370. glm::uvec4 msb(0);
  371. glm::uvec4 lsb(0);
  372. glm::umulExtended(x, y, msb, lsb);
  373. Error += glm::all(glm::equal(msb, glm::uvec4(0))) ? 0 : 1;
  374. Error += glm::all(glm::equal(lsb, glm::uvec4(6))) ? 0 : 1;
  375. }
  376. return Error;
  377. }
  378. }//namespace umulExtended
  379. namespace imulExtended
  380. {
  381. int test()
  382. {
  383. int Error(0);
  384. {
  385. int x = 2;
  386. int y = 3;
  387. int msb = 0;
  388. int lsb = 0;
  389. glm::imulExtended(x, y, msb, lsb);
  390. Error += msb == 0 ? 0 : 1;
  391. Error += lsb == 6 ? 0 : 1;
  392. }
  393. {
  394. glm::ivec1 x(2);
  395. glm::ivec1 y(3);
  396. glm::ivec1 msb(0);
  397. glm::ivec1 lsb(0);
  398. glm::imulExtended(x, y, msb, lsb);
  399. Error += glm::all(glm::equal(msb, glm::ivec1(0))) ? 0 : 1;
  400. Error += glm::all(glm::equal(lsb, glm::ivec1(6))) ? 0 : 1;
  401. }
  402. {
  403. glm::ivec2 x(2);
  404. glm::ivec2 y(3);
  405. glm::ivec2 msb(0);
  406. glm::ivec2 lsb(0);
  407. glm::imulExtended(x, y, msb, lsb);
  408. Error += glm::all(glm::equal(msb, glm::ivec2(0))) ? 0 : 1;
  409. Error += glm::all(glm::equal(lsb, glm::ivec2(6))) ? 0 : 1;
  410. }
  411. {
  412. glm::ivec3 x(2);
  413. glm::ivec3 y(3);
  414. glm::ivec3 msb(0);
  415. glm::ivec3 lsb(0);
  416. glm::imulExtended(x, y, msb, lsb);
  417. Error += glm::all(glm::equal(msb, glm::ivec3(0))) ? 0 : 1;
  418. Error += glm::all(glm::equal(lsb, glm::ivec3(6))) ? 0 : 1;
  419. }
  420. {
  421. glm::ivec4 x(2);
  422. glm::ivec4 y(3);
  423. glm::ivec4 msb(0);
  424. glm::ivec4 lsb(0);
  425. glm::imulExtended(x, y, msb, lsb);
  426. Error += glm::all(glm::equal(msb, glm::ivec4(0))) ? 0 : 1;
  427. Error += glm::all(glm::equal(lsb, glm::ivec4(6))) ? 0 : 1;
  428. }
  429. return Error;
  430. }
  431. }//namespace imulExtended
  432. namespace bitCount
  433. {
  434. template <typename genType>
  435. struct type
  436. {
  437. genType Value;
  438. genType Return;
  439. };
  440. type<int> const DataI32[] =
  441. {
  442. {0x00000001, 1},
  443. {0x00000003, 2},
  444. {0x00000002, 1},
  445. {0xffffffff, 32},
  446. {0x00000000, 0}
  447. };
  448. template <typename T>
  449. int bitCount_if(T v)
  450. {
  451. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitCount' only accept integer values");
  452. int Count(0);
  453. for(T i = 0, n = static_cast<T>(sizeof(T) * 8); i < n; ++i)
  454. {
  455. if(v & static_cast<T>(1 << i))
  456. ++Count;
  457. }
  458. return Count;
  459. }
  460. template <typename T>
  461. int bitCount_vec(T v)
  462. {
  463. GLM_STATIC_ASSERT(std::numeric_limits<T>::is_integer, "'bitCount' only accept integer values");
  464. int Count(0);
  465. for(T i = 0, n = static_cast<T>(sizeof(T) * 8); i < n; ++i)
  466. {
  467. Count += static_cast<int>((v >> i) & static_cast<T>(1));
  468. }
  469. return Count;
  470. }
  471. int perf()
  472. {
  473. int Error(0);
  474. std::size_t Size = 10000000;
  475. std::clock_t TimestampsA = std::clock();
  476. {
  477. std::vector<int> v;
  478. v.resize(Size);
  479. for(std::size_t i = 0, n = v.size(); i < n; ++i)
  480. v[i] = bitCount_if(i);
  481. }
  482. std::clock_t TimestampsB = std::clock();
  483. {
  484. std::vector<int> v;
  485. v.resize(Size);
  486. for(std::size_t i = 0, n = v.size(); i < n; ++i)
  487. v[i] = bitCount_vec(i);
  488. }
  489. std::clock_t TimestampsC = std::clock();
  490. {
  491. std::vector<int> v;
  492. v.resize(Size);
  493. for(std::size_t i = 0, n = v.size(); i < n; ++i)
  494. v[i] = glm::bitCount(i);
  495. }
  496. std::clock_t TimestampsD = std::clock();
  497. std::clock_t TimeIf = TimestampsB - TimestampsA;
  498. std::clock_t TimeVec = TimestampsC - TimestampsB;
  499. std::clock_t TimeDefault = TimestampsD - TimestampsC;
  500. printf("TimeIf %d\n", TimeIf);
  501. printf("TimeVec %d\n", TimeVec);
  502. printf("TimeDefault %d\n", TimeDefault);
  503. return Error;
  504. }
  505. int test()
  506. {
  507. int Error(0);
  508. for(std::size_t i = 0, n = sizeof(DataI32) / sizeof(type<int>); i < n; ++i)
  509. {
  510. int Result = glm::bitCount(DataI32[i].Value);
  511. Error += DataI32[i].Return == Result ? 0 : 1;
  512. assert(!Error);
  513. }
  514. return Error;
  515. }
  516. }//bitCount
  517. int main()
  518. {
  519. int Error = 0;
  520. std::cout << "sizeof(glm::uint64): " << sizeof(glm::detail::uint64) << std::endl;
  521. Error += ::umulExtended::test();
  522. Error += ::imulExtended::test();
  523. Error += ::uaddCarry::test();
  524. Error += ::usubBorrow::test();
  525. Error += ::bitfieldInsert::test();
  526. Error += ::bitfieldExtract::test();
  527. Error += ::bitfieldReverse::test();
  528. Error += ::bitCount::test();
  529. Error += ::bitCount::perf();
  530. Error += ::findMSB::test();
  531. Error += ::findLSB::test();
  532. return Error;
  533. }