638 行
15 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 <cstring>
  14. #include <cstdio>
  15. #include "core.h"
  16. using namespace std;
  17. namespace lol
  18. {
  19. real::real(float f) { *this = (double)f; }
  20. real::real(int i) { *this = (double)i; }
  21. real::real(unsigned int i) { *this = (double)i; }
  22. real::real(double d)
  23. {
  24. union { double d; uint64_t x; } u = { d };
  25. uint32_t sign = (u.x >> 63) << 31;
  26. uint32_t exponent = (u.x << 1) >> 53;
  27. switch (exponent)
  28. {
  29. case 0x00:
  30. m_signexp = sign;
  31. break;
  32. case 0x7ff:
  33. m_signexp = sign | 0x7fffffffu;
  34. break;
  35. default:
  36. m_signexp = sign | (exponent + (1 << 30) - (1 << 10));
  37. break;
  38. }
  39. m_mantissa[0] = u.x >> 36;
  40. m_mantissa[1] = u.x >> 20;
  41. m_mantissa[2] = u.x >> 4;
  42. m_mantissa[3] = u.x << 12;
  43. memset(m_mantissa + 4, 0, sizeof(m_mantissa) - 4 * sizeof(m_mantissa[0]));
  44. }
  45. real::operator float() const { return (float)(double)(*this); }
  46. real::operator int() const { return (int)(double)(*this); }
  47. real::operator unsigned int() const { return (unsigned int)(double)(*this); }
  48. real::operator double() const
  49. {
  50. union { double d; uint64_t x; } u;
  51. /* Get sign */
  52. u.x = m_signexp >> 31;
  53. u.x <<= 11;
  54. /* Compute new exponent */
  55. uint32_t exponent = (m_signexp << 1) >> 1;
  56. int e = (int)exponent - (1 << 30) + (1 << 10);
  57. if (e < 0)
  58. u.x <<= 52;
  59. else if (e >= 0x7ff)
  60. {
  61. u.x |= 0x7ff;
  62. u.x <<= 52;
  63. }
  64. else
  65. {
  66. u.x |= e;
  67. /* Store mantissa if necessary */
  68. u.x <<= 16;
  69. u.x |= m_mantissa[0];
  70. u.x <<= 16;
  71. u.x |= m_mantissa[1];
  72. u.x <<= 16;
  73. u.x |= m_mantissa[2];
  74. u.x <<= 4;
  75. u.x |= m_mantissa[3] >> 12;
  76. /* Rounding */
  77. u.x += (m_mantissa[3] >> 11) & 1;
  78. }
  79. return u.d;
  80. }
  81. real real::operator -() const
  82. {
  83. real ret = *this;
  84. ret.m_signexp ^= 0x80000000u;
  85. return ret;
  86. }
  87. real real::operator +(real const &x) const
  88. {
  89. if (x.m_signexp << 1 == 0)
  90. return *this;
  91. /* Ensure both arguments are positive. Otherwise, switch signs,
  92. * or replace + with -. */
  93. if (m_signexp >> 31)
  94. return -(-*this + -x);
  95. if (x.m_signexp >> 31)
  96. return *this - (-x);
  97. /* Ensure *this is the larger exponent (no need to be strictly larger,
  98. * as in subtraction). Otherwise, switch. */
  99. if ((m_signexp << 1) < (x.m_signexp << 1))
  100. return x + *this;
  101. real ret;
  102. int e1 = m_signexp - (1 << 30) + 1;
  103. int e2 = x.m_signexp - (1 << 30) + 1;
  104. int bigoff = (e1 - e2) / (sizeof(uint16_t) * 8);
  105. int off = e1 - e2 - bigoff * (sizeof(uint16_t) * 8);
  106. if (bigoff > BIGITS)
  107. return *this;
  108. ret.m_signexp = m_signexp;
  109. uint32_t carry = 0;
  110. for (int i = BIGITS; i--; )
  111. {
  112. carry += m_mantissa[i];
  113. if (i - bigoff >= 0)
  114. carry += x.m_mantissa[i - bigoff] >> off;
  115. if (i - bigoff > 0)
  116. carry += (x.m_mantissa[i - bigoff - 1] << (16 - off)) & 0xffffu;
  117. else if (i - bigoff == 0)
  118. carry += 0x0001u << (16 - off);
  119. ret.m_mantissa[i] = carry;
  120. carry >>= 16;
  121. }
  122. /* Renormalise in case we overflowed the mantissa */
  123. if (carry)
  124. {
  125. carry--;
  126. for (int i = 0; i < BIGITS; i++)
  127. {
  128. uint16_t tmp = ret.m_mantissa[i];
  129. ret.m_mantissa[i] = (carry << 15) | (tmp >> 1);
  130. carry = tmp & 0x0001u;
  131. }
  132. ret.m_signexp++;
  133. }
  134. return ret;
  135. }
  136. real real::operator -(real const &x) const
  137. {
  138. if (x.m_signexp << 1 == 0)
  139. return *this;
  140. /* Ensure both arguments are positive. Otherwise, switch signs,
  141. * or replace - with +. */
  142. if (m_signexp >> 31)
  143. return -(-*this + x);
  144. if (x.m_signexp >> 31)
  145. return (*this) + (-x);
  146. /* Ensure *this is larger than x */
  147. if (*this < x)
  148. return -(x - *this);
  149. real ret;
  150. int e1 = m_signexp - (1 << 30) + 1;
  151. int e2 = x.m_signexp - (1 << 30) + 1;
  152. int bigoff = (e1 - e2) / (sizeof(uint16_t) * 8);
  153. int off = e1 - e2 - bigoff * (sizeof(uint16_t) * 8);
  154. if (bigoff > BIGITS)
  155. return *this;
  156. ret.m_signexp = m_signexp;
  157. int32_t carry = 0;
  158. for (int i = 0; i < bigoff; i++)
  159. {
  160. carry -= x.m_mantissa[BIGITS - i];
  161. carry = (carry & 0xffff0000u) | (carry >> 16);
  162. }
  163. carry -= x.m_mantissa[BIGITS - 1 - bigoff] & ((1 << off) - 1);
  164. carry /= (1 << off);
  165. for (int i = BIGITS; i--; )
  166. {
  167. carry += m_mantissa[i];
  168. if (i - bigoff >= 0)
  169. carry -= x.m_mantissa[i - bigoff] >> off;
  170. if (i - bigoff > 0)
  171. carry -= (x.m_mantissa[i - bigoff - 1] << (16 - off)) & 0xffffu;
  172. else if (i - bigoff == 0)
  173. carry -= 0x0001u << (16 - off);
  174. ret.m_mantissa[i] = carry;
  175. carry = (carry & 0xffff0000u) | (carry >> 16);
  176. }
  177. carry += 1;
  178. /* Renormalise if we underflowed the mantissa */
  179. if (carry == 0)
  180. {
  181. /* How much do we need to shift the mantissa? FIXME: this could
  182. * be computed above */
  183. off = 0;
  184. for (int i = 0; i < BIGITS; i++)
  185. {
  186. if (!ret.m_mantissa[i])
  187. {
  188. off += sizeof(uint16_t) * 8;
  189. continue;
  190. }
  191. for (uint16_t tmp = ret.m_mantissa[i]; tmp < 0x8000u; tmp <<= 1)
  192. off++;
  193. break;
  194. }
  195. if (off == BIGITS * sizeof(uint16_t) * 8)
  196. ret.m_signexp &= 0x80000000u;
  197. else
  198. {
  199. off++; /* Shift one more to get rid of the leading one */
  200. ret.m_signexp -= off;
  201. bigoff = off / (sizeof(uint16_t) * 8);
  202. off -= bigoff * sizeof(uint16_t) * 8;
  203. for (int i = 0; i < BIGITS; i++)
  204. {
  205. uint16_t tmp = 0;
  206. if (i + bigoff < BIGITS)
  207. tmp |= ret.m_mantissa[i + bigoff] << off;
  208. if (i + bigoff + 1 < BIGITS)
  209. tmp |= ret.m_mantissa[i + bigoff + 1] >> (16 - off);
  210. ret.m_mantissa[i] = tmp;
  211. }
  212. }
  213. }
  214. return ret;
  215. }
  216. real real::operator *(real const &x) const
  217. {
  218. real ret;
  219. if (m_signexp << 1 == 0 || x.m_signexp << 1 == 0)
  220. {
  221. ret = (m_signexp << 1 == 0) ? *this : x;
  222. ret.m_signexp ^= x.m_signexp & 0x80000000u;
  223. return ret;
  224. }
  225. ret.m_signexp = (m_signexp ^ x.m_signexp) & 0x80000000u;
  226. int e = (m_signexp & 0x7fffffffu) - (1 << 30) + 1
  227. + (x.m_signexp & 0x7fffffffu) - (1 << 30) + 1;
  228. /* Accumulate low order product; no need to store it, we just
  229. * want the carry value */
  230. uint64_t carry = 0;
  231. for (int i = 0; i < BIGITS; i++)
  232. {
  233. for (int j = 0; j < i + 1; j++)
  234. carry += (uint32_t)m_mantissa[BIGITS - 1 - j]
  235. * (uint32_t)x.m_mantissa[BIGITS - 1 + j - i];
  236. carry >>= 16;
  237. }
  238. for (int i = 0; i < BIGITS; i++)
  239. {
  240. for (int j = i + 1; j < BIGITS; j++)
  241. carry += (uint32_t)m_mantissa[BIGITS - 1 - j]
  242. * (uint32_t)x.m_mantissa[j - 1 - i];
  243. carry += m_mantissa[BIGITS - 1 - i];
  244. carry += x.m_mantissa[BIGITS - 1 - i];
  245. ret.m_mantissa[BIGITS - 1 - i] = carry & 0xffffu;
  246. carry >>= 16;
  247. }
  248. /* Renormalise in case we overflowed the mantissa */
  249. if (carry)
  250. {
  251. carry--;
  252. for (int i = 0; i < BIGITS; i++)
  253. {
  254. uint16_t tmp = ret.m_mantissa[i];
  255. ret.m_mantissa[i] = (carry << 15) | (tmp >> 1);
  256. carry = tmp & 0x0001u;
  257. }
  258. e++;
  259. }
  260. ret.m_signexp |= e + (1 << 30) - 1;
  261. return ret;
  262. }
  263. real real::operator /(real const &x) const
  264. {
  265. return *this * fres(x);
  266. }
  267. real &real::operator +=(real const &x)
  268. {
  269. real tmp = *this;
  270. return *this = tmp + x;
  271. }
  272. real &real::operator -=(real const &x)
  273. {
  274. real tmp = *this;
  275. return *this = tmp - x;
  276. }
  277. real &real::operator *=(real const &x)
  278. {
  279. real tmp = *this;
  280. return *this = tmp * x;
  281. }
  282. real &real::operator /=(real const &x)
  283. {
  284. real tmp = *this;
  285. return *this = tmp / x;
  286. }
  287. bool real::operator ==(real const &x) const
  288. {
  289. if ((m_signexp << 1) == 0 && (x.m_signexp << 1) == 0)
  290. return true;
  291. if (m_signexp != x.m_signexp)
  292. return false;
  293. return memcmp(m_mantissa, x.m_mantissa, sizeof(m_mantissa)) == 0;
  294. }
  295. bool real::operator !=(real const &x) const
  296. {
  297. return !(*this == x);
  298. }
  299. bool real::operator <(real const &x) const
  300. {
  301. /* Ensure both numbers are positive */
  302. if (m_signexp >> 31)
  303. return (x.m_signexp >> 31) ? -*this > -x : true;
  304. if (x.m_signexp >> 31)
  305. return false;
  306. /* Compare all relevant bits */
  307. if (m_signexp != x.m_signexp)
  308. return m_signexp < x.m_signexp;
  309. for (int i = 0; i < BIGITS; i++)
  310. if (m_mantissa[i] != x.m_mantissa[i])
  311. return m_mantissa[i] < x.m_mantissa[i];
  312. return false;
  313. }
  314. bool real::operator <=(real const &x) const
  315. {
  316. return !(*this > x);
  317. }
  318. bool real::operator >(real const &x) const
  319. {
  320. /* Ensure both numbers are positive */
  321. if (m_signexp >> 31)
  322. return (x.m_signexp >> 31) ? -*this < -x : false;
  323. if (x.m_signexp >> 31)
  324. return true;
  325. /* Compare all relevant bits */
  326. if (m_signexp != x.m_signexp)
  327. return m_signexp > x.m_signexp;
  328. for (int i = 0; i < BIGITS; i++)
  329. if (m_mantissa[i] != x.m_mantissa[i])
  330. return m_mantissa[i] > x.m_mantissa[i];
  331. return false;
  332. }
  333. bool real::operator >=(real const &x) const
  334. {
  335. return !(*this < x);
  336. }
  337. real fres(real const &x)
  338. {
  339. if (!(x.m_signexp << 1))
  340. {
  341. real ret = x;
  342. ret.m_signexp = x.m_signexp | 0x7fffffffu;
  343. ret.m_mantissa[0] = 0;
  344. return ret;
  345. }
  346. /* Use the system's float inversion to approximate 1/x */
  347. union { float f; uint32_t x; } u = { 1.0f }, v = { 1.0f };
  348. v.x |= (uint32_t)x.m_mantissa[0] << 7;
  349. v.x |= (uint32_t)x.m_mantissa[1] >> 9;
  350. v.f = 1.0 / v.f;
  351. real ret;
  352. ret.m_mantissa[0] = (v.x >> 7) & 0xffffu;
  353. ret.m_mantissa[1] = (v.x << 9) & 0xffffu;
  354. uint32_t sign = x.m_signexp & 0x80000000u;
  355. ret.m_signexp = sign;
  356. int exponent = (x.m_signexp & 0x7fffffffu) + 1;
  357. exponent = -exponent + (v.x >> 23) - (u.x >> 23);
  358. ret.m_signexp |= (exponent - 1) & 0x7fffffffu;
  359. /* Five steps of Newton-Raphson seems enough for 32-bigit reals. */
  360. real two = 2;
  361. ret = ret * (two - ret * x);
  362. ret = ret * (two - ret * x);
  363. ret = ret * (two - ret * x);
  364. ret = ret * (two - ret * x);
  365. ret = ret * (two - ret * x);
  366. return ret;
  367. }
  368. real sqrt(real const &x)
  369. {
  370. /* if zero, return x */
  371. if (!(x.m_signexp << 1))
  372. return x;
  373. /* if negative, return NaN */
  374. if (x.m_signexp >> 31)
  375. {
  376. real ret;
  377. ret.m_signexp = 0x7fffffffu;
  378. ret.m_mantissa[0] = 0xffffu;
  379. return ret;
  380. }
  381. /* Use the system's float inversion to approximate 1/sqrt(x). First
  382. * we construct a float in the [1..4[ range that has roughly the same
  383. * mantissa as our real. Its exponent is 0 or 1, depending on the
  384. * partity of x. The final exponent is 0, -1 or -2. We use the final
  385. * exponent and final mantissa to pre-fill the result. */
  386. union { float f; uint32_t x; } u = { 1.0f }, v = { 2.0f };
  387. v.x -= ((x.m_signexp & 1) << 23);
  388. v.x |= (uint32_t)x.m_mantissa[0] << 7;
  389. v.x |= (uint32_t)x.m_mantissa[1] >> 9;
  390. v.f = 1.0 / sqrtf(v.f);
  391. real ret;
  392. ret.m_mantissa[0] = (v.x >> 7) & 0xffffu;
  393. ret.m_mantissa[1] = (v.x << 9) & 0xffffu;
  394. uint32_t sign = x.m_signexp & 0x80000000u;
  395. ret.m_signexp = sign;
  396. int exponent = (x.m_signexp & 0x7fffffffu) - ((1 << 30) - 1);
  397. exponent = - (exponent / 2) + (v.x >> 23) - (u.x >> 23);
  398. ret.m_signexp |= (exponent + ((1 << 30) - 1)) & 0x7fffffffu;
  399. /* Five steps of Newton-Raphson seems enough for 32-bigit reals. */
  400. real three = 3;
  401. ret = ret * (three - ret * ret * x);
  402. ret.m_signexp--;
  403. ret = ret * (three - ret * ret * x);
  404. ret.m_signexp--;
  405. ret = ret * (three - ret * ret * x);
  406. ret.m_signexp--;
  407. ret = ret * (three - ret * ret * x);
  408. ret.m_signexp--;
  409. ret = ret * (three - ret * ret * x);
  410. ret.m_signexp--;
  411. return ret * x;
  412. }
  413. real fabs(real const &x)
  414. {
  415. real ret = x;
  416. ret.m_signexp &= 0x7fffffffu;
  417. return ret;
  418. }
  419. real exp(real const &x)
  420. {
  421. int square = 0;
  422. /* FIXME: this is slow. Find a better way to approximate exp(x) for
  423. * large values. */
  424. real tmp = x, one = 1.0;
  425. while (tmp > one)
  426. {
  427. tmp.m_signexp--;
  428. square++;
  429. }
  430. real ret = 1.0, fact = 1.0, xn = tmp;
  431. for (int i = 1; i < 100; i++)
  432. {
  433. fact *= (real)i;
  434. ret += xn / fact;
  435. xn *= tmp;
  436. }
  437. for (int i = 0; i < square; i++)
  438. ret = ret * ret;
  439. return ret;
  440. }
  441. real sin(real const &x)
  442. {
  443. real ret = 0.0, fact = 1.0, xn = x, x2 = x * x;
  444. for (int i = 1; ; i += 2)
  445. {
  446. real newret = ret + xn / fact;
  447. if (ret == newret)
  448. break;
  449. ret = newret;
  450. xn *= x2;
  451. fact *= (real)(-(i + 1) * (i + 2));
  452. }
  453. return ret;
  454. }
  455. real cos(real const &x)
  456. {
  457. real ret = 0.0, fact = 1.0, xn = 1.0, x2 = x * x;
  458. for (int i = 1; ; i += 2)
  459. {
  460. real newret = ret + xn / fact;
  461. if (ret == newret)
  462. break;
  463. ret = newret;
  464. xn *= x2;
  465. fact *= (real)(-i * (i + 1));
  466. }
  467. return ret;
  468. }
  469. void real::print(int ndigits) const
  470. {
  471. real const r1 = 1, r10 = 10;
  472. real x = *this;
  473. if (x.m_signexp >> 31)
  474. {
  475. printf("-");
  476. x = -x;
  477. }
  478. /* Normalise x so that mantissa is in [1..9.999] */
  479. int exponent = 0;
  480. if (x.m_signexp)
  481. {
  482. for (real div = r1, newdiv; true; div = newdiv)
  483. {
  484. newdiv = div * r10;
  485. if (x < newdiv)
  486. {
  487. x /= div;
  488. break;
  489. }
  490. exponent++;
  491. }
  492. for (real mul = 1, newx; true; mul *= r10)
  493. {
  494. newx = x * mul;
  495. if (newx >= r1)
  496. {
  497. x = newx;
  498. break;
  499. }
  500. exponent--;
  501. }
  502. }
  503. /* Print digits */
  504. for (int i = 0; i < ndigits; i++)
  505. {
  506. int digit = (int)x;
  507. printf("%i", digit);
  508. if (i == 0)
  509. printf(".");
  510. x -= real(digit);
  511. x *= r10;
  512. }
  513. /* Print exponent information */
  514. if (exponent < 0)
  515. printf("e-%i", -exponent);
  516. else if (exponent > 0)
  517. printf("e+%i", exponent);
  518. printf("\n");
  519. }
  520. } /* namespace lol */