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.

преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  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://www.wtfpl.net/ for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include <cmath>
  14. #include <lol/main.h>
  15. #include "lol/unit.h"
  16. namespace lol
  17. {
  18. LOLUNIT_FIXTURE(RealTest)
  19. {
  20. LOLUNIT_TEST(Constants)
  21. {
  22. double a0 = real::R_0();
  23. double a1 = real::R_1();
  24. double a2 = real::R_2();
  25. double a10 = real::R_10();
  26. LOLUNIT_ASSERT_EQUAL(a0, 0.0);
  27. LOLUNIT_ASSERT_EQUAL(a1, 1.0);
  28. LOLUNIT_ASSERT_EQUAL(a2, 2.0);
  29. LOLUNIT_ASSERT_EQUAL(a10, 10.0);
  30. double b1 = log(real::R_E());
  31. double b2 = log2(real::R_2());
  32. LOLUNIT_ASSERT_EQUAL(b1, 1.0);
  33. LOLUNIT_ASSERT_EQUAL(b2, 1.0);
  34. double c1 = exp(re(real::R_LOG2E()));
  35. double c2 = log(exp2(real::R_LOG2E()));
  36. LOLUNIT_ASSERT_EQUAL(c1, 2.0);
  37. LOLUNIT_ASSERT_EQUAL(c2, 1.0);
  38. double d1 = exp(re(real::R_LOG10E()));
  39. LOLUNIT_ASSERT_EQUAL(d1, 10.0);
  40. double e1 = exp(real::R_LN2());
  41. LOLUNIT_ASSERT_EQUAL(e1, 2.0);
  42. double f1 = exp(real::R_LN10());
  43. LOLUNIT_ASSERT_EQUAL(f1, 10.0);
  44. double g1 = sin(real::R_PI());
  45. double g2 = cos(real::R_PI());
  46. LOLUNIT_ASSERT_DOUBLES_EQUAL(g1, 0.0, 1e-100);
  47. LOLUNIT_ASSERT_EQUAL(g2, -1.0);
  48. double h1 = sin(real::R_PI_2());
  49. double h2 = cos(real::R_PI_2());
  50. LOLUNIT_ASSERT_EQUAL(h1, 1.0);
  51. LOLUNIT_ASSERT_DOUBLES_EQUAL(h2, 0.0, 1e-100);
  52. double i1 = sin(real::R_PI_4()) * sin(real::R_PI_4());
  53. double i2 = cos(real::R_PI_4()) * cos(real::R_PI_4());
  54. LOLUNIT_ASSERT_EQUAL(i1, 0.5);
  55. LOLUNIT_ASSERT_EQUAL(i2, 0.5);
  56. }
  57. LOLUNIT_TEST(FloatToReal)
  58. {
  59. float a1 = real(0.0f);
  60. float a2 = real(-0.0f);
  61. float a3 = real(1.0f);
  62. float a4 = real(-1.0f);
  63. float a5 = real(1.5f);
  64. float a6 = real(12345678.0f);
  65. LOLUNIT_ASSERT_EQUAL(a1, 0.0f);
  66. LOLUNIT_ASSERT_EQUAL(a2, -0.0f);
  67. LOLUNIT_ASSERT_EQUAL(a3, 1.0f);
  68. LOLUNIT_ASSERT_EQUAL(a4, -1.0f);
  69. LOLUNIT_ASSERT_EQUAL(a5, 1.5f);
  70. LOLUNIT_ASSERT_EQUAL(a6, 12345678.0f);
  71. }
  72. LOLUNIT_TEST(DoubleToReal)
  73. {
  74. double a1 = real(0.0);
  75. double a2 = real(-0.0);
  76. double a3 = real(1.0);
  77. double a4 = real(-1.0);
  78. double a5 = real(1.5);
  79. double a6 = real(1234567876543210.0);
  80. LOLUNIT_ASSERT_DOUBLES_EQUAL(a1, 0.0, 0.0);
  81. LOLUNIT_ASSERT_DOUBLES_EQUAL(a2, -0.0, 0.0);
  82. LOLUNIT_ASSERT_DOUBLES_EQUAL(a3, 1.0, 0.0);
  83. LOLUNIT_ASSERT_DOUBLES_EQUAL(a4, -1.0, 0.0);
  84. LOLUNIT_ASSERT_DOUBLES_EQUAL(a5, 1.5, 0.0);
  85. LOLUNIT_ASSERT_DOUBLES_EQUAL(a6, 1234567876543210.0, 0.0);
  86. }
  87. LOLUNIT_TEST(Init)
  88. {
  89. real r;
  90. float f1 = (float)r;
  91. LOLUNIT_ASSERT_EQUAL(f1, 0.0f);
  92. rcmplx q;
  93. float f2 = (float)q.x;
  94. float f3 = (float)q.y;
  95. LOLUNIT_ASSERT_EQUAL(f2, 0.0f);
  96. LOLUNIT_ASSERT_EQUAL(f3, 0.0f);
  97. }
  98. LOLUNIT_TEST(StringToReal)
  99. {
  100. float a1 = real("0");
  101. float a2 = real("1");
  102. float a3 = real("-1");
  103. /* 2^-128 * 2^128 */
  104. float a4 = real("0.0000000000000000000000000000000000000029387358770"
  105. "557187699218413430556141945466638919302188037718792"
  106. "6569604314863681793212890625")
  107. * real("340282366920938463463374607431768211456");
  108. LOLUNIT_ASSERT_EQUAL(a1, 0.0f);
  109. LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
  110. LOLUNIT_ASSERT_EQUAL(a3, -1.0f);
  111. LOLUNIT_ASSERT_EQUAL(a4, 1.0f);
  112. }
  113. LOLUNIT_TEST(UnaryMinus)
  114. {
  115. float a1 = - real(1.0f);
  116. float a2 = - real(-1.0f);
  117. float a3 = - real(0.0f);
  118. float a4 = - real(-0.0f);
  119. LOLUNIT_ASSERT_EQUAL(a1, -1.0f);
  120. LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
  121. LOLUNIT_ASSERT_EQUAL(a3, -0.0f);
  122. LOLUNIT_ASSERT_EQUAL(a4, 0.0f);
  123. }
  124. LOLUNIT_TEST(Comparison)
  125. {
  126. LOLUNIT_ASSERT(real(1.0f) > real(0.5f));
  127. LOLUNIT_ASSERT(real(1.0f) >= real(0.5f));
  128. LOLUNIT_ASSERT(real(1.0f) >= real(1.0f));
  129. LOLUNIT_ASSERT(real(-1.0f) < real(-0.5f));
  130. LOLUNIT_ASSERT(real(-1.0f) <= real(-0.5f));
  131. LOLUNIT_ASSERT(real(-1.0f) <= real(-1.0f));
  132. LOLUNIT_ASSERT(real(-1.0f) < real(0.5f));
  133. LOLUNIT_ASSERT(real(-0.5f) < real(1.0f));
  134. LOLUNIT_ASSERT(real(-1.0f) <= real(0.5f));
  135. LOLUNIT_ASSERT(real(-0.5f) <= real(1.0f));
  136. LOLUNIT_ASSERT(real(1.0f) > real(-0.5f));
  137. LOLUNIT_ASSERT(real(0.5f) > real(-1.0f));
  138. LOLUNIT_ASSERT(real(1.0f) >= real(-0.5f));
  139. LOLUNIT_ASSERT(real(0.5f) >= real(-1.0f));
  140. }
  141. LOLUNIT_TEST(Addition)
  142. {
  143. float a1 = real(1.0f) + real(0.0f);
  144. float a2 = real(0.0f) + real(1.0f);
  145. float a3 = real(1.0f) + real(1.0f);
  146. float a4 = real(-1.0f) + real(-1.0f);
  147. float a5 = real(1.0f) + real(0.125f);
  148. double a6 = real(3.13609818956293918)
  149. + real(0.00005972154828114);
  150. float a7 = real(1.0f) + real(-0.125f);
  151. double a8 = real(0.10000000002) + real(-2.0e-11);
  152. LOLUNIT_ASSERT_EQUAL(a1, 1.0f);
  153. LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
  154. LOLUNIT_ASSERT_EQUAL(a3, 2.0f);
  155. LOLUNIT_ASSERT_EQUAL(a4, -2.0f);
  156. LOLUNIT_ASSERT_EQUAL(a5, 1.125f);
  157. LOLUNIT_ASSERT_DOUBLES_EQUAL(a6, 3.1361579, 0.000001);
  158. LOLUNIT_ASSERT_EQUAL(a7, 0.875f);
  159. LOLUNIT_ASSERT_DOUBLES_EQUAL(a8, 0.1, 1.0e-13);
  160. }
  161. LOLUNIT_TEST(Subtraction)
  162. {
  163. float a1 = real(1.0f) + real(1e20f) - real(1e20f);
  164. LOLUNIT_ASSERT_EQUAL(a1, 1.0f);
  165. }
  166. LOLUNIT_TEST(Multiplication)
  167. {
  168. real x(1.25f);
  169. real y(1.5f);
  170. real z(1.99999f);
  171. real w(-1.5f);
  172. float m1 = x * x;
  173. float m2 = y * y;
  174. float m3 = z * z;
  175. float m4 = w * w;
  176. LOLUNIT_ASSERT_EQUAL(m1, 1.25f * 1.25f);
  177. LOLUNIT_ASSERT_EQUAL(m2, 1.5f * 1.5f);
  178. LOLUNIT_ASSERT_EQUAL(m3, 1.99999f * 1.99999f);
  179. LOLUNIT_ASSERT_EQUAL(m4, -1.5f * -1.5f);
  180. }
  181. LOLUNIT_TEST(ExactDivision)
  182. {
  183. float m1 = real::R_1() / real::R_1();
  184. float m2 = real::R_2() / real::R_1();
  185. float m3 = real::R_1() / real::R_2();
  186. float m4 = real::R_2() / real::R_2();
  187. float m5 = real::R_1() / -real::R_2();
  188. LOLUNIT_ASSERT_EQUAL(m1, 1.0f);
  189. LOLUNIT_ASSERT_EQUAL(m2, 2.0f);
  190. LOLUNIT_ASSERT_EQUAL(m3, 0.5f);
  191. LOLUNIT_ASSERT_EQUAL(m4, 1.0f);
  192. LOLUNIT_ASSERT_EQUAL(m5, -0.5f);
  193. }
  194. LOLUNIT_TEST(InexactDivision)
  195. {
  196. /* 1 / 3 * 3 should be close to 1... check that it does not differ
  197. * by more than 2^-k where k is the number of bits in the mantissa. */
  198. real a = real::R_1() / real::R_3() * real::R_3();
  199. real b = ldexp(real::R_1() - a, real::BIGITS * real::BIGIT_BITS);
  200. LOLUNIT_ASSERT_LEQUAL((double)fabs(b), 1.0);
  201. }
  202. LOLUNIT_TEST(LoadExp)
  203. {
  204. real a1(1.5);
  205. real a2(-1.5);
  206. real a3(0.0);
  207. LOLUNIT_ASSERT_EQUAL((double)ldexp(a1, 7), 192.0);
  208. LOLUNIT_ASSERT_EQUAL((double)ldexp(a1, -7), 0.01171875);
  209. LOLUNIT_ASSERT_EQUAL((double)ldexp(a2, 7), -192.0);
  210. LOLUNIT_ASSERT_EQUAL((double)ldexp(a2, -7), -0.01171875);
  211. LOLUNIT_ASSERT_EQUAL((double)ldexp(a3, 7), 0.0);
  212. LOLUNIT_ASSERT_EQUAL((double)ldexp(a3, -7), 0.0);
  213. }
  214. LOLUNIT_TEST(Ulp)
  215. {
  216. real a1 = real::R_PI();
  217. LOLUNIT_ASSERT_NOT_EQUAL((double)(a1 + ulp(a1) - a1), 0.0);
  218. LOLUNIT_ASSERT_EQUAL((double)(a1 + ulp(a1) / 2 - a1), 0.0);
  219. }
  220. LOLUNIT_TEST(Bool)
  221. {
  222. real a = 0.0;
  223. LOLUNIT_ASSERT(!a);
  224. a = -0.0;
  225. LOLUNIT_ASSERT(!a);
  226. a = 1234.0;
  227. LOLUNIT_ASSERT(a);
  228. LOLUNIT_ASSERT(!!a);
  229. a = -1234.0;
  230. LOLUNIT_ASSERT(a);
  231. LOLUNIT_ASSERT(!!a);
  232. }
  233. LOLUNIT_TEST(AsinAcos)
  234. {
  235. double tests[] =
  236. {
  237. -1024.0, -1023.0, -513.0, -512.0, -511.0, -1.0, -0.0,
  238. 0.0, 1.0, 511.0, 512.0, 513.0, 1023.0, 1024.0
  239. };
  240. for (double test : tests)
  241. {
  242. double a = test / 1024;
  243. double b = sin(asin((real)a));
  244. double c = cos(acos((real)a));
  245. LOLUNIT_SET_CONTEXT(a);
  246. LOLUNIT_ASSERT_DOUBLES_EQUAL(b, a, 1e-100);
  247. LOLUNIT_ASSERT_DOUBLES_EQUAL(c, a, 1e-100);
  248. }
  249. }
  250. LOLUNIT_TEST(FloorCeilEtc)
  251. {
  252. double tests[] =
  253. {
  254. -2.0, -2.0, -2.0, -2.0,
  255. -1.5, -2.0, -1.0, -2.0,
  256. -1.0, -1.0, -1.0, -1.0,
  257. -0.0, -0.0, -0.0, -0.0,
  258. 0.0, 0.0, 0.0, 0.0,
  259. 0.25, 0.0, 1.0, 0.0,
  260. 0.375, 0.0, 1.0, 0.0,
  261. 0.5, 0.0, 1.0, 1.0,
  262. 1.0, 1.0, 1.0, 1.0,
  263. 1.5, 1.0, 2.0, 2.0,
  264. 2.0, 2.0, 2.0, 2.0,
  265. 2.5, 2.0, 3.0, 3.0,
  266. 3.0, 3.0, 3.0, 3.0,
  267. 8192.0, 8192.0, 8192.0, 8192.0,
  268. 8192.03125, 8192.0, 8193.0, 8192.0,
  269. 8192.5, 8192.0, 8193.0, 8193.0,
  270. 8193.0, 8193.0, 8193.0, 8193.0,
  271. 549755813888.0, 549755813888.0, 549755813888.0, 549755813888.0,
  272. 549755813888.03125, 549755813888.0, 549755813889.0, 549755813888.0,
  273. 549755813888.5, 549755813888.0, 549755813889.0, 549755813889.0,
  274. 549755813889.0, 549755813889.0, 549755813889.0, 549755813889.0,
  275. };
  276. for (unsigned int n = 0; n < sizeof(tests) / sizeof(*tests); n += 4)
  277. {
  278. double a0 = floor((real)tests[n]);
  279. double b0 = tests[n + 1];
  280. double a1 = ceil((real)tests[n]);
  281. double b1 = tests[n + 2];
  282. double a2 = round((real)tests[n]);
  283. double b2 = tests[n + 3];
  284. LOLUNIT_ASSERT_EQUAL(b0, a0);
  285. LOLUNIT_ASSERT_EQUAL(b1, a1);
  286. LOLUNIT_ASSERT_EQUAL(b2, a2);
  287. }
  288. }
  289. LOLUNIT_TEST(Pow)
  290. {
  291. double a1 = pow(-real::R_2(), real::R_2());
  292. double b1 = 4.0;
  293. LOLUNIT_ASSERT_DOUBLES_EQUAL(a1, b1, 1.0e-13);
  294. double a2 = pow(-real::R_2(), real::R_3());
  295. double b2 = -8.0;
  296. LOLUNIT_ASSERT_DOUBLES_EQUAL(a2, b2, 1.0e-13);
  297. }
  298. };
  299. } /* namespace lol */