Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

291 rader
8.3 KiB

  1. //
  2. // Lol Engine — Unit tests
  3. //
  4. // Copyright © 2010—2014 Sam Hocevar <sam@hocevar.net>
  5. //
  6. // Lol Engine is free software. It comes without any warranty, to
  7. // the extent permitted by applicable law. You can redistribute it
  8. // and/or modify it under the terms of the Do What the Fuck You Want
  9. // to Public License, Version 2, as published by the WTFPL Task Force.
  10. // See http://www.wtfpl.net/ for more details.
  11. //
  12. #include <lol/engine-internal.h>
  13. #include <cmath>
  14. #include <lolunit.h>
  15. namespace lol
  16. {
  17. lolunit_declare_fixture(HalfTest)
  18. {
  19. lolunit_declare_test(FloatToHalf)
  20. {
  21. for (size_t i = 0; i < sizeof(pairs) / sizeof(*pairs); i++)
  22. {
  23. half a = (half)pairs[i].f;
  24. uint16_t b = pairs[i].x;
  25. lolunit_set_context(i);
  26. lolunit_assert_equal(a.bits, b);
  27. }
  28. }
  29. lolunit_declare_test(FloatToHalfAccurate)
  30. {
  31. for (size_t i = 0; i < sizeof(pairs) / sizeof(*pairs); i++)
  32. {
  33. half a = half::makeaccurate(pairs[i].f);
  34. uint16_t b = pairs[i].x;
  35. lolunit_set_context(i);
  36. lolunit_assert_equal(a.bits, b);
  37. }
  38. }
  39. lolunit_declare_test(BitsToHalf)
  40. {
  41. for (unsigned int i = 0; i < 0x10000; i++)
  42. {
  43. half a = half::makebits(i);
  44. uint16_t b = i;
  45. lolunit_set_context(i);
  46. lolunit_assert_equal(a.bits, b);
  47. }
  48. }
  49. lolunit_declare_test(HalfIsNaN)
  50. {
  51. lolunit_assert(half::makebits(0x7c01).is_nan());
  52. lolunit_assert(half::makebits(0xfc01).is_nan());
  53. lolunit_assert(half::makebits(0x7e00).is_nan());
  54. lolunit_assert(half::makebits(0xfe00).is_nan());
  55. lolunit_assert(!half::makebits(0x7c00).is_nan());
  56. lolunit_assert(!half::makebits(0xfc00).is_nan());
  57. lolunit_assert(!half(0.0f).is_nan());
  58. lolunit_assert(!half(-0.0f).is_nan());
  59. lolunit_assert(!half(2.0f).is_nan());
  60. lolunit_assert(!half(-2.0f).is_nan());
  61. }
  62. lolunit_declare_test(HalfIsInf)
  63. {
  64. lolunit_assert(half(65536.0f).is_inf());
  65. lolunit_assert(half(-65536.0f).is_inf());
  66. lolunit_assert(!half(0.0f).is_inf());
  67. lolunit_assert(!half(-0.0f).is_inf());
  68. lolunit_assert(!half(65535.0f).is_inf());
  69. lolunit_assert(!half(-65535.0f).is_inf());
  70. lolunit_assert(half::makebits(0x7c00).is_inf());
  71. lolunit_assert(half::makebits(0xfc00).is_inf());
  72. lolunit_assert(!half::makebits(0x7e00).is_inf());
  73. lolunit_assert(!half::makebits(0xfe00).is_inf());
  74. }
  75. lolunit_declare_test(HalfIsFinite)
  76. {
  77. lolunit_assert(half(0.0f).is_finite());
  78. lolunit_assert(half(-0.0f).is_finite());
  79. lolunit_assert(half(65535.0f).is_finite());
  80. lolunit_assert(half(-65535.0f).is_finite());
  81. lolunit_assert(!half(65536.0f).is_finite());
  82. lolunit_assert(!half(-65536.0f).is_finite());
  83. lolunit_assert(!half::makebits(0x7c00).is_finite());
  84. lolunit_assert(!half::makebits(0xfc00).is_finite());
  85. lolunit_assert(!half::makebits(0x7e00).is_finite());
  86. lolunit_assert(!half::makebits(0xfe00).is_finite());
  87. }
  88. lolunit_declare_test(HalfIsNormal)
  89. {
  90. lolunit_assert(half(0.0f).is_normal());
  91. lolunit_assert(half(-0.0f).is_normal());
  92. lolunit_assert(half(65535.0f).is_normal());
  93. lolunit_assert(half(-65535.0f).is_normal());
  94. lolunit_assert(!half(65536.0f).is_normal());
  95. lolunit_assert(!half(-65536.0f).is_normal());
  96. lolunit_assert(!half::makebits(0x7c00).is_normal());
  97. lolunit_assert(!half::makebits(0xfc00).is_normal());
  98. lolunit_assert(!half::makebits(0x7e00).is_normal());
  99. lolunit_assert(!half::makebits(0xfe00).is_normal());
  100. }
  101. lolunit_declare_test(HalfClassify)
  102. {
  103. for (uint32_t i = 0; i < 0x10000; i++)
  104. {
  105. lolunit_set_context(i);
  106. half h = half::makebits(i);
  107. if (h.is_nan())
  108. {
  109. lolunit_assert(!h.is_inf());
  110. lolunit_assert(!h.is_normal());
  111. lolunit_assert(!h.is_finite());
  112. }
  113. else if (h.is_inf())
  114. {
  115. lolunit_assert(!h.is_normal());
  116. lolunit_assert(!h.is_finite());
  117. }
  118. else
  119. {
  120. lolunit_assert(h.is_finite());
  121. }
  122. }
  123. }
  124. lolunit_declare_test(HalfToFloat)
  125. {
  126. for (size_t i = 0; i < sizeof(pairs) / sizeof(*pairs); i++)
  127. {
  128. float a = (float)half::makebits(pairs[i].x);
  129. float b = pairs[i].f;
  130. lolunit_set_context(i);
  131. lolunit_assert_equal(a, b);
  132. }
  133. for (uint32_t i = 0; i < 0x10000; i++)
  134. {
  135. half h = half::makebits(i);
  136. if (h.is_nan())
  137. continue;
  138. float f = (float)h;
  139. half g = (half)f;
  140. lolunit_set_context(i);
  141. lolunit_assert_equal(g.bits, h.bits);
  142. }
  143. }
  144. lolunit_declare_test(HalfToInt)
  145. {
  146. lolunit_assert_equal((int)(half)(0.0f), 0);
  147. lolunit_assert_equal((int)(half)(-0.0f), 0);
  148. lolunit_assert_equal((int)(half)(0.9f), 0);
  149. lolunit_assert_equal((int)(half)(-0.9f), 0);
  150. lolunit_assert_equal((int)(half)(1.0f), 1);
  151. lolunit_assert_equal((int)(half)(-1.0f), -1);
  152. lolunit_assert_equal((int)(half)(1.9f), 1);
  153. lolunit_assert_equal((int)(half)(-1.9f), -1);
  154. lolunit_assert_equal((int)(half)(65504.0f), 65504);
  155. lolunit_assert_equal((int)(half)(-65504.0f), -65504);
  156. }
  157. lolunit_declare_test(FloatOpHalf)
  158. {
  159. half zero = 0;
  160. half one = 1;
  161. half two = 2;
  162. float a = zero + one;
  163. lolunit_assert_equal(1.0f, a);
  164. a += zero;
  165. lolunit_assert_equal(1.0f, a);
  166. a -= zero;
  167. lolunit_assert_equal(1.0f, a);
  168. a *= one;
  169. lolunit_assert_equal(1.0f, a);
  170. a /= one;
  171. lolunit_assert_equal(1.0f, a);
  172. float b = one + zero;
  173. lolunit_assert_equal(1.0f, b);
  174. b += one;
  175. lolunit_assert_equal(2.0f, b);
  176. b *= two;
  177. lolunit_assert_equal(4.0f, b);
  178. b -= two;
  179. lolunit_assert_equal(2.0f, b);
  180. b /= two;
  181. lolunit_assert_equal(1.0f, b);
  182. float c = one - zero;
  183. lolunit_assert_equal(1.0f, c);
  184. float d = two - one;
  185. lolunit_assert_equal(1.0f, d);
  186. float e = two + (-one);
  187. lolunit_assert_equal(1.0f, e);
  188. float f = (two * two) / (one + one);
  189. lolunit_assert_equal(2.0f, f);
  190. }
  191. lolunit_declare_test(HalfOpFloat)
  192. {
  193. half zero = 0;
  194. half one = 1;
  195. half two = 2;
  196. half four = 4;
  197. half a = one + 0.0f;
  198. lolunit_assert_equal(one.bits, a.bits);
  199. a += 0.0f;
  200. lolunit_assert_equal(one.bits, a.bits);
  201. a -= 0.0f;
  202. lolunit_assert_equal(one.bits, a.bits);
  203. a *= 1.0f;
  204. lolunit_assert_equal(one.bits, a.bits);
  205. a /= 1.0f;
  206. lolunit_assert_equal(one.bits, a.bits);
  207. half b = one + 0.0f;
  208. lolunit_assert_equal(one.bits, b.bits);
  209. b += 1.0f;
  210. lolunit_assert_equal(two.bits, b.bits);
  211. b *= 2.0f;
  212. lolunit_assert_equal(four.bits, b.bits);
  213. b -= 2.0f;
  214. lolunit_assert_equal(two.bits, b.bits);
  215. b /= 2.0f;
  216. lolunit_assert_equal(one.bits, b.bits);
  217. half c = 1.0f - zero;
  218. lolunit_assert_equal(one.bits, c.bits);
  219. half d = 2.0f - one;
  220. lolunit_assert_equal(one.bits, d.bits);
  221. half e = 2.0f + (-one);
  222. lolunit_assert_equal(one.bits, e.bits);
  223. half f = (2.0f * two) / (1.0f + one);
  224. lolunit_assert_equal(two.bits, f.bits);
  225. }
  226. struct TestPair { float f; uint16_t x; };
  227. static TestPair const pairs[11];
  228. };
  229. HalfTest::TestPair const HalfTest::pairs[] =
  230. {
  231. /* All these values have exact half representations */
  232. { 0.0f, 0x0000 },
  233. { -0.0f, 0x8000 }, /* negative zero */
  234. { 1.0f, 0x3c00 },
  235. { -1.0f, 0xbc00 },
  236. { 2.0f, 0x4000 },
  237. { 0.5f, 0x3800 },
  238. { 0.125f, 0x3000 },
  239. { 15.9375f, 0x4bf8 },
  240. { 31.0f / (1 << 14), 0x17c0 }, /* 0x1.fp-10 */
  241. { 31.0f / (1 << 18), 0x07c0 }, /* 0x1.fp-14, normal float, denormal half */
  242. { 31.0f / (1 << 19), 0x03e0 }, /* 0x1.fp-15, normal float, denormal half */
  243. };
  244. } /* namespace lol */