You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

236 lines
6.6 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include <cppunit/extensions/HelperMacros.h>
  14. #include <cppunit/TestCaller.h>
  15. #include <cppunit/TestCase.h>
  16. #include <cppunit/TestSuite.h>
  17. #include "core.h"
  18. namespace lol
  19. {
  20. class HalfTest : public CppUnit::TestCase
  21. {
  22. CPPUNIT_TEST_SUITE(HalfTest);
  23. CPPUNIT_TEST(test_half_makebits);
  24. CPPUNIT_TEST(test_half_makeslow);
  25. CPPUNIT_TEST(test_half_makefast);
  26. CPPUNIT_TEST(test_half_isnan);
  27. CPPUNIT_TEST(test_half_isinf);
  28. CPPUNIT_TEST(test_half_isfinite);
  29. CPPUNIT_TEST(test_half_isnormal);
  30. CPPUNIT_TEST(test_half_classify);
  31. CPPUNIT_TEST(test_half_to_float);
  32. CPPUNIT_TEST(test_half_to_int);
  33. CPPUNIT_TEST_SUITE_END();
  34. public:
  35. HalfTest() : CppUnit::TestCase("Matrix Test") {}
  36. void setUp()
  37. {
  38. }
  39. void tearDown() {}
  40. void test_half_makebits()
  41. {
  42. for (unsigned int i = 0; i < 0x10000; i++)
  43. {
  44. half a = half::makebits(i);
  45. uint16_t b = i;
  46. CPPUNIT_ASSERT_EQUAL(a.bits(), b);
  47. }
  48. }
  49. void test_half_makeslow()
  50. {
  51. for (size_t i = 0; i < sizeof(pairs) / sizeof(*pairs); i++)
  52. {
  53. half a = half::makeslow(pairs[i].f);
  54. uint16_t b = pairs[i].x;
  55. CPPUNIT_ASSERT_EQUAL(a.bits(), b);
  56. }
  57. }
  58. void test_half_makefast()
  59. {
  60. for (size_t i = 0; i < sizeof(pairs) / sizeof(*pairs); i++)
  61. {
  62. half a = half::makefast(pairs[i].f);
  63. uint16_t b = pairs[i].x;
  64. CPPUNIT_ASSERT_EQUAL(a.bits(), b);
  65. }
  66. }
  67. void test_half_isnan()
  68. {
  69. CPPUNIT_ASSERT(half::makebits(0x7c01).isnan());
  70. CPPUNIT_ASSERT(half::makebits(0xfc01).isnan());
  71. CPPUNIT_ASSERT(half::makebits(0x7e00).isnan());
  72. CPPUNIT_ASSERT(half::makebits(0xfe00).isnan());
  73. CPPUNIT_ASSERT(!half::makebits(0x7c00).isnan());
  74. CPPUNIT_ASSERT(!half::makebits(0xfc00).isnan());
  75. CPPUNIT_ASSERT(!half(0.0f).isnan());
  76. CPPUNIT_ASSERT(!half(-0.0f).isnan());
  77. CPPUNIT_ASSERT(!half(2.0f).isnan());
  78. CPPUNIT_ASSERT(!half(-2.0f).isnan());
  79. }
  80. void test_half_isinf()
  81. {
  82. CPPUNIT_ASSERT(half(65536.0f).isinf());
  83. CPPUNIT_ASSERT(half(-65536.0f).isinf());
  84. CPPUNIT_ASSERT(!half(0.0f).isinf());
  85. CPPUNIT_ASSERT(!half(-0.0f).isinf());
  86. CPPUNIT_ASSERT(!half(65535.0f).isinf());
  87. CPPUNIT_ASSERT(!half(-65535.0f).isinf());
  88. CPPUNIT_ASSERT(half::makebits(0x7c00).isinf());
  89. CPPUNIT_ASSERT(half::makebits(0xfc00).isinf());
  90. CPPUNIT_ASSERT(!half::makebits(0x7e00).isinf());
  91. CPPUNIT_ASSERT(!half::makebits(0xfe00).isinf());
  92. }
  93. void test_half_isfinite()
  94. {
  95. CPPUNIT_ASSERT(half(0.0f).isfinite());
  96. CPPUNIT_ASSERT(half(-0.0f).isfinite());
  97. CPPUNIT_ASSERT(half(65535.0f).isfinite());
  98. CPPUNIT_ASSERT(half(-65535.0f).isfinite());
  99. CPPUNIT_ASSERT(!half(65536.0f).isfinite());
  100. CPPUNIT_ASSERT(!half(-65536.0f).isfinite());
  101. CPPUNIT_ASSERT(!half::makebits(0x7c00).isfinite());
  102. CPPUNIT_ASSERT(!half::makebits(0xfc00).isfinite());
  103. CPPUNIT_ASSERT(!half::makebits(0x7e00).isfinite());
  104. CPPUNIT_ASSERT(!half::makebits(0xfe00).isfinite());
  105. }
  106. void test_half_isnormal()
  107. {
  108. CPPUNIT_ASSERT(half(0.0f).isnormal());
  109. CPPUNIT_ASSERT(half(-0.0f).isnormal());
  110. CPPUNIT_ASSERT(half(65535.0f).isnormal());
  111. CPPUNIT_ASSERT(half(-65535.0f).isnormal());
  112. CPPUNIT_ASSERT(!half(65536.0f).isnormal());
  113. CPPUNIT_ASSERT(!half(-65536.0f).isnormal());
  114. CPPUNIT_ASSERT(!half::makebits(0x7c00).isnormal());
  115. CPPUNIT_ASSERT(!half::makebits(0xfc00).isnormal());
  116. CPPUNIT_ASSERT(!half::makebits(0x7e00).isnormal());
  117. CPPUNIT_ASSERT(!half::makebits(0xfe00).isnormal());
  118. }
  119. void test_half_classify()
  120. {
  121. for (uint32_t i = 0; i < 0x10000; i++)
  122. {
  123. half h = half::makebits(i);
  124. if (h.isnan())
  125. {
  126. CPPUNIT_ASSERT(!h.isinf());
  127. CPPUNIT_ASSERT(!h.isnormal());
  128. CPPUNIT_ASSERT(!h.isfinite());
  129. }
  130. else if (h.isinf())
  131. {
  132. CPPUNIT_ASSERT(!h.isnormal());
  133. CPPUNIT_ASSERT(!h.isfinite());
  134. }
  135. else
  136. {
  137. CPPUNIT_ASSERT(h.isfinite());
  138. }
  139. }
  140. }
  141. void test_half_to_float()
  142. {
  143. for (size_t i = 0; i < sizeof(pairs) / sizeof(*pairs); i++)
  144. {
  145. float a = (float)half::makebits(pairs[i].x);
  146. float b = pairs[i].f;
  147. CPPUNIT_ASSERT_EQUAL(a, b);
  148. }
  149. for (uint32_t i = 0; i < 0x10000; i++)
  150. {
  151. half h = half::makebits(i);
  152. float f = (float)h;
  153. half g = (half)f;
  154. if (h.isnan())
  155. {
  156. CPPUNIT_ASSERT(isnan(f));
  157. CPPUNIT_ASSERT(g.isnan());
  158. }
  159. else
  160. {
  161. CPPUNIT_ASSERT(!isnan(f));
  162. CPPUNIT_ASSERT_EQUAL(g.bits(), h.bits());
  163. }
  164. }
  165. }
  166. void test_half_to_int()
  167. {
  168. CPPUNIT_ASSERT_EQUAL((int)(half)(0.0f), 0);
  169. CPPUNIT_ASSERT_EQUAL((int)(half)(-0.0f), 0);
  170. CPPUNIT_ASSERT_EQUAL((int)(half)(0.9f), 0);
  171. CPPUNIT_ASSERT_EQUAL((int)(half)(-0.9f), 0);
  172. CPPUNIT_ASSERT_EQUAL((int)(half)(1.0f), 1);
  173. CPPUNIT_ASSERT_EQUAL((int)(half)(-1.0f), -1);
  174. CPPUNIT_ASSERT_EQUAL((int)(half)(1.9f), 1);
  175. CPPUNIT_ASSERT_EQUAL((int)(half)(-1.9f), -1);
  176. CPPUNIT_ASSERT_EQUAL((int)(half)(65504.0f), 65504);
  177. CPPUNIT_ASSERT_EQUAL((int)(half)(-65504.0f), -65504);
  178. }
  179. private:
  180. struct TestPair { float f; uint16_t x; };
  181. static TestPair const pairs[11];
  182. };
  183. HalfTest::TestPair const HalfTest::pairs[] =
  184. {
  185. /* All these values have exact half representations */
  186. { 0.0f, 0x0000 },
  187. { -0.0f, 0x8000 }, /* negative zero */
  188. { 1.0f, 0x3c00 },
  189. { -1.0f, 0xbc00 },
  190. { 2.0f, 0x4000 },
  191. { 0.5f, 0x3800 },
  192. { 0.125f, 0x3000 },
  193. { 15.9375f, 0x4bf8 },
  194. { 0x1.fp-10, 0x17c0 },
  195. { 0x1.fp-14, 0x07c0 }, /* denormal */
  196. { 0x1.fp-15, 0x03e0 }, /* denormal */
  197. };
  198. CPPUNIT_TEST_SUITE_REGISTRATION(HalfTest);
  199. } /* namespace lol */