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.

преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 13 години
преди 7 години
преди 7 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 13 години
преди 13 години
преди 7 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 13 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 7 години
преди 5 години
преди 7 години
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693
  1. //
  2. // Lol Engine
  3. //
  4. // Copyright © 2010—2019 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 <new>
  13. #include <string>
  14. #include <sstream>
  15. #include <iomanip>
  16. #include <cstring>
  17. #include <cstdlib>
  18. #include <cmath>
  19. namespace lol
  20. {
  21. /*
  22. * Initialisation order is not important because everything is
  23. * done on demand, but here is the dependency list anyway:
  24. * - fast_log() requires R_1
  25. * - log() requires R_LN2
  26. * - inverse() require R_2
  27. * - exp() requires R_0, R_1, R_LN2
  28. * - sqrt() requires R_3
  29. */
  30. static real fast_log(real const &x);
  31. static real load_min();
  32. static real load_max();
  33. static real load_pi();
  34. /* These getters do not need caching, their return values are small */
  35. template<> inline real const real::R_0() { return real(); }
  36. template<> inline real const real::R_INF() { real ret; ret.m_inf = true; return ret; }
  37. template<> inline real const real::R_NAN() { real ret; ret.m_nan = true; return ret; }
  38. #define LOL_CONSTANT_GETTER(name, value) \
  39. template<> inline real const& real::name() \
  40. { \
  41. static real ret; \
  42. static int prev_bigit_count = -1; \
  43. /* If the default bigit count has changed, we must recompute
  44. * the value with the desired precision. */ \
  45. if (prev_bigit_count != global_bigit_count()) \
  46. { \
  47. ret = (value); \
  48. prev_bigit_count = global_bigit_count(); \
  49. } \
  50. return ret; \
  51. }
  52. LOL_CONSTANT_GETTER(R_1, real(1.0));
  53. LOL_CONSTANT_GETTER(R_2, real(2.0));
  54. LOL_CONSTANT_GETTER(R_3, real(3.0));
  55. LOL_CONSTANT_GETTER(R_10, real(10.0));
  56. LOL_CONSTANT_GETTER(R_MIN, load_min());
  57. LOL_CONSTANT_GETTER(R_MAX, load_max());
  58. LOL_CONSTANT_GETTER(R_LN2, fast_log(R_2()));
  59. LOL_CONSTANT_GETTER(R_LN10, log(R_10()));
  60. LOL_CONSTANT_GETTER(R_LOG2E, inverse(R_LN2()));
  61. LOL_CONSTANT_GETTER(R_LOG10E, inverse(R_LN10()));
  62. LOL_CONSTANT_GETTER(R_E, exp(R_1()));
  63. LOL_CONSTANT_GETTER(R_PI, load_pi());
  64. LOL_CONSTANT_GETTER(R_PI_2, R_PI() / 2);
  65. LOL_CONSTANT_GETTER(R_PI_3, R_PI() / R_3());
  66. LOL_CONSTANT_GETTER(R_PI_4, R_PI() / 4);
  67. LOL_CONSTANT_GETTER(R_TAU, R_PI() + R_PI());
  68. LOL_CONSTANT_GETTER(R_1_PI, inverse(R_PI()));
  69. LOL_CONSTANT_GETTER(R_2_PI, R_1_PI() * 2);
  70. LOL_CONSTANT_GETTER(R_2_SQRTPI, inverse(sqrt(R_PI())) * 2);
  71. LOL_CONSTANT_GETTER(R_SQRT2, sqrt(R_2()));
  72. LOL_CONSTANT_GETTER(R_SQRT3, sqrt(R_3()));
  73. LOL_CONSTANT_GETTER(R_SQRT1_2, R_SQRT2() / 2);
  74. #undef LOL_CONSTANT_GETTER
  75. /*
  76. * Now carry on with the rest of the Real class.
  77. */
  78. template<> inline real::Real(int32_t i) { new(this) real((double)i); }
  79. template<> inline real::Real(uint32_t i) { new(this) real((double)i); }
  80. template<> inline real::Real(float f) { new(this) real((double)f); }
  81. template<> inline real::Real(int64_t i)
  82. {
  83. new(this) real((uint64_t)std::abs(i));
  84. m_sign = i < 0;
  85. }
  86. template<> inline real::Real(uint64_t i)
  87. {
  88. new(this) real();
  89. if (i)
  90. {
  91. /* Only works with 32-bit bigits for now */
  92. static_assert(sizeof(bigit_t) == 4, "bigit_t must be 32-bit");
  93. int delta = 1;
  94. while ((i >> 63) == 0)
  95. {
  96. i <<= 1;
  97. ++delta;
  98. }
  99. i <<= 1; /* Remove implicit one */
  100. m_exponent = 64 - delta;
  101. m_mantissa.resize(DEFAULT_BIGIT_COUNT);
  102. m_mantissa[0] = (bigit_t)(i >> 32);
  103. if (bigit_count() > 1)
  104. m_mantissa[1] = (bigit_t)i;
  105. }
  106. }
  107. template<> inline real::Real(double d)
  108. {
  109. union { double d; uint64_t x; } u = { d };
  110. m_sign = bool(u.x >> 63);
  111. exponent_t exponent = (u.x << 1) >> 53;
  112. switch (exponent)
  113. {
  114. case 0x00: /* +0 / -0 */
  115. break;
  116. case 0x7ff: /* Inf/NaN (FIXME: handle NaN!) */
  117. m_inf = true;
  118. break;
  119. default:
  120. /* Only works with 32-bit bigits for now */
  121. static_assert(sizeof(bigit_t) == 4, "bigit_t must be 32-bit");
  122. m_exponent = exponent - ((1 << 10) - 1);
  123. m_mantissa.resize(DEFAULT_BIGIT_COUNT);
  124. m_mantissa[0] = (bigit_t)(u.x >> 20);
  125. if (bigit_count() > 1)
  126. m_mantissa[1] = (bigit_t)(u.x << 12);
  127. break;
  128. }
  129. }
  130. template<> inline real::Real(long double f)
  131. {
  132. /* We don’t know the long double layout, so we get rid of the
  133. * exponent, then load it into a real in two steps. */
  134. int exponent;
  135. f = frexpl(f, &exponent);
  136. new(this) real(double(f));
  137. *this += double(f - (long double)*this);
  138. m_exponent += exponent;
  139. }
  140. template<> inline real::operator float() const { return (float)(double)*this; }
  141. template<> inline real::operator int32_t() const { return (int32_t)(double)floor(*this); }
  142. template<> inline real::operator uint32_t() const { return (uint32_t)(double)floor(*this); }
  143. template<> inline real::operator uint64_t() const
  144. {
  145. uint32_t msb = (uint32_t)ldexp(*this, -32);
  146. uint64_t ret = ((uint64_t)msb << 32)
  147. | (uint32_t)(*this - ldexp((real)msb, 32));
  148. return ret;
  149. }
  150. template<> inline real::operator int64_t() const
  151. {
  152. /* If number is positive, convert it to uint64_t first. If it is
  153. * negative, switch its sign first. */
  154. return is_negative() ? -(int64_t)-*this : (int64_t)(uint64_t)*this;
  155. }
  156. template<> inline real::operator double() const
  157. {
  158. union { double d; uint64_t x; } u;
  159. /* Get sign */
  160. u.x = (is_negative() ? 1 : 0) << 11;
  161. /* Compute new exponent (FIXME: handle Inf/NaN) */
  162. int64_t e = m_exponent + ((1 << 10) - 1);
  163. if (is_zero())
  164. u.x <<= 52;
  165. else if (e < 0) /* if exponent underflows, set to zero */
  166. u.x <<= 52;
  167. else if (e >= 0x7ff)
  168. {
  169. u.x |= 0x7ff;
  170. u.x <<= 52;
  171. }
  172. else
  173. {
  174. u.x |= e;
  175. /* Store mantissa if necessary */
  176. u.x <<= 32;
  177. if (bigit_count() > 0)
  178. u.x |= m_mantissa[0];
  179. u.x <<= 20;
  180. if (bigit_count() > 1)
  181. {
  182. u.x |= m_mantissa[1] >> 12;
  183. /* Rounding */
  184. u.x += (m_mantissa[1] >> 11) & 1;
  185. }
  186. }
  187. return u.d;
  188. }
  189. template<> inline real::operator long double() const
  190. {
  191. double hi = double(*this);
  192. double lo = double(*this - hi);
  193. return (long double)(hi) + (long double)(lo);
  194. }
  195. /*
  196. * Create a real number from an ASCII representation
  197. */
  198. template<> inline real::Real(char const *str)
  199. {
  200. real ret = 0;
  201. exponent_t exponent = 0;
  202. bool hex = false, comma = false, nonzero = false, negative = false, finished = false;
  203. for (char const *p = str; *p && !finished; p++)
  204. {
  205. switch (*p)
  206. {
  207. case '-':
  208. case '+':
  209. if (p != str)
  210. break;
  211. negative = (*p == '-');
  212. break;
  213. case '.':
  214. if (comma)
  215. finished = true;
  216. comma = true;
  217. break;
  218. case 'x':
  219. case 'X':
  220. /* This character is only valid for 0x... and 0X... numbers */
  221. if (p != str + 1 || str[0] != '0')
  222. finished = true;
  223. hex = true;
  224. break;
  225. case 'p':
  226. case 'P':
  227. if (hex)
  228. exponent += atoi(p + 1);
  229. finished = true;
  230. break;
  231. case 'e':
  232. case 'E':
  233. if (!hex)
  234. {
  235. exponent += atoi(p + 1);
  236. finished = true;
  237. break;
  238. }
  239. LOL_ATTR_FALLTHROUGH
  240. case 'a': case 'b': case 'c': case 'd': case 'f':
  241. case 'A': case 'B': case 'C': case 'D': case 'F':
  242. case '0': case '1': case '2': case '3': case '4':
  243. case '5': case '6': case '7': case '8': case '9':
  244. if (nonzero)
  245. {
  246. /* Multiply ret by 10 or 16 depending the base. */
  247. if (!hex)
  248. {
  249. real x = ret + ret;
  250. ret = x + x + ret;
  251. }
  252. ret.m_exponent += hex ? 4 : 1;
  253. }
  254. if (*p != '0')
  255. {
  256. ret += (*p >= 'a' && *p <= 'f') ? (int)(*p - 'a' + 10)
  257. : (*p >= 'A' && *p <= 'F') ? (int)(*p - 'A' + 10)
  258. : (int)(*p - '0');
  259. nonzero = true;
  260. }
  261. if (comma)
  262. exponent -= hex ? 4 : 1;
  263. break;
  264. default:
  265. finished = true;
  266. break;
  267. }
  268. }
  269. if (hex)
  270. ret.m_exponent += exponent;
  271. else if (exponent)
  272. ret *= pow(R_10(), (real)exponent);
  273. if (negative)
  274. ret = -ret;
  275. *this = ret;
  276. }
  277. template<> inline real real::operator +() const
  278. {
  279. return *this;
  280. }
  281. template<> inline real real::operator -() const
  282. {
  283. real ret = *this;
  284. ret.m_sign ^= true;
  285. return ret;
  286. }
  287. template<> inline real real::operator +(real const &x) const
  288. {
  289. if (x.is_zero())
  290. return *this;
  291. if (is_zero())
  292. return x;
  293. /* Ensure both arguments are positive. Otherwise, switch signs,
  294. * or replace + with -. */
  295. if (is_negative())
  296. return -(-*this + -x);
  297. if (x.is_negative())
  298. return *this - (-x);
  299. /* Ensure *this has the larger exponent (no need for the mantissa to
  300. * be larger, as in subtraction). Otherwise, switch. */
  301. if (m_exponent < x.m_exponent)
  302. return x + *this;
  303. int64_t e1 = m_exponent;
  304. int64_t e2 = x.m_exponent;
  305. int64_t bigoff = (e1 - e2) / bigit_bits();
  306. int64_t off = e1 - e2 - bigoff * bigit_bits();
  307. /* FIXME: ensure we have the same number of bigits */
  308. if (bigoff > bigit_count())
  309. return *this;
  310. real ret;
  311. ret.m_mantissa.resize(bigit_count());
  312. ret.m_exponent = m_exponent;
  313. uint64_t carry = 0;
  314. for (int i = bigit_count(); i--; )
  315. {
  316. carry += m_mantissa[i];
  317. if (i - bigoff >= 0)
  318. carry += x.m_mantissa[i - bigoff] >> off;
  319. if (off && i - bigoff > 0)
  320. carry += (x.m_mantissa[i - bigoff - 1] << (bigit_bits() - off)) & 0xffffffffu;
  321. else if (i - bigoff == 0)
  322. carry += (uint64_t)1 << (bigit_bits() - off);
  323. ret.m_mantissa[i] = (uint32_t)carry;
  324. carry >>= bigit_bits();
  325. }
  326. /* Renormalise in case we overflowed the mantissa */
  327. if (carry)
  328. {
  329. carry--;
  330. for (int i = 0; i < bigit_count(); ++i)
  331. {
  332. uint32_t tmp = ret.m_mantissa[i];
  333. ret.m_mantissa[i] = ((uint32_t)carry << (bigit_bits() - 1))
  334. | (tmp >> 1);
  335. carry = tmp & 1u;
  336. }
  337. ret.m_exponent++;
  338. }
  339. return ret;
  340. }
  341. template<> inline real real::operator -(real const &x) const
  342. {
  343. if (x.is_zero())
  344. return *this;
  345. if (is_zero())
  346. return -x;
  347. /* Ensure both arguments are positive. Otherwise, switch signs,
  348. * or replace - with +. */
  349. if (is_negative())
  350. return -(-*this + x);
  351. if (x.is_negative())
  352. return (*this) + (-x);
  353. /* Ensure *this is larger than x */
  354. if (*this < x)
  355. return -(x - *this);
  356. exponent_t e1 = m_exponent;
  357. exponent_t e2 = x.m_exponent;
  358. exponent_t bigoff = (e1 - e2) / bigit_bits();
  359. exponent_t off = e1 - e2 - bigoff * bigit_bits();
  360. /* FIXME: ensure we have the same number of bigits */
  361. if (bigoff > bigit_count())
  362. return *this;
  363. real ret;
  364. ret.m_mantissa.resize(bigit_count());
  365. ret.m_exponent = m_exponent;
  366. /* int64_t instead of uint64_t to preserve sign through shifts */
  367. exponent_t carry = 0;
  368. for (int i = 0; i < bigoff; ++i)
  369. {
  370. carry -= x.m_mantissa[bigit_count() - 1 - i];
  371. /* Emulates a signed shift */
  372. carry >>= bigit_bits();
  373. carry |= carry << bigit_bits();
  374. }
  375. if (bigoff < bigit_count())
  376. carry -= x.m_mantissa[bigit_count() - 1 - bigoff] & (((exponent_t)1 << off) - 1);
  377. carry /= (exponent_t)1 << off;
  378. for (int i = bigit_count(); i--; )
  379. {
  380. carry += m_mantissa[i];
  381. if (i - bigoff >= 0)
  382. carry -= x.m_mantissa[i - bigoff] >> off;
  383. if (off && i - bigoff > 0)
  384. carry -= (x.m_mantissa[i - bigoff - 1] << (bigit_bits() - off)) & 0xffffffffu;
  385. else if (i - bigoff == 0)
  386. carry -= (uint64_t)1 << (bigit_bits() - off);
  387. ret.m_mantissa[i] = (bigit_t)carry;
  388. carry >>= bigit_bits();
  389. carry |= carry << bigit_bits();
  390. }
  391. carry += 1;
  392. /* Renormalise if we underflowed the mantissa */
  393. if (carry == 0)
  394. {
  395. /* How much do we need to shift the mantissa? FIXME: this could
  396. * be computed above */
  397. off = 0;
  398. for (int i = 0; i < bigit_count(); ++i)
  399. {
  400. if (!ret.m_mantissa[i])
  401. {
  402. off += bigit_bits();
  403. continue;
  404. }
  405. /* “~tmp > tmp” checks that the MSB is not set */
  406. for (bigit_t tmp = ret.m_mantissa[i]; ~tmp > tmp; tmp <<= 1)
  407. off++;
  408. break;
  409. }
  410. if (off == total_bits())
  411. ret.m_mantissa.resize(0);
  412. else
  413. {
  414. off++; /* Shift once more to get rid of the leading 1 */
  415. ret.m_exponent -= off;
  416. bigoff = off / bigit_bits();
  417. off -= bigoff * bigit_bits();
  418. for (int i = 0; i < bigit_count(); ++i)
  419. {
  420. bigit_t tmp = 0;
  421. if (i + bigoff < bigit_count())
  422. tmp |= ret.m_mantissa[i + bigoff] << off;
  423. if (off && i + bigoff + 1 < bigit_count())
  424. tmp |= ret.m_mantissa[i + bigoff + 1] >> (bigit_bits() - off);
  425. ret.m_mantissa[i] = tmp;
  426. }
  427. }
  428. }
  429. return ret;
  430. }
  431. template<> inline real real::operator *(real const &x) const
  432. {
  433. real ret;
  434. /* The sign is easy to compute */
  435. ret.m_sign = is_negative() ^ x.is_negative();
  436. /* If any operand is zero, return zero. FIXME: 0 * Inf? */
  437. if (is_zero() || x.is_zero())
  438. return ret;
  439. ret.m_mantissa.resize(bigit_count());
  440. ret.m_exponent = m_exponent + x.m_exponent;
  441. /* Accumulate low order product; no need to store it, we just
  442. * want the carry value */
  443. uint64_t carry = 0, hicarry = 0, prev;
  444. for (int i = 0; i < bigit_count(); ++i)
  445. {
  446. for (int j = 0; j < i + 1; j++)
  447. {
  448. prev = carry;
  449. carry += (uint64_t)m_mantissa[bigit_count() - 1 - j]
  450. * (uint64_t)x.m_mantissa[bigit_count() - 1 + j - i];
  451. if (carry < prev)
  452. hicarry++;
  453. }
  454. carry >>= bigit_bits();
  455. carry |= hicarry << bigit_bits();
  456. hicarry >>= bigit_bits();
  457. }
  458. /* Multiply the other components */
  459. for (int i = 0; i < bigit_count(); ++i)
  460. {
  461. for (int j = i + 1; j < bigit_count(); j++)
  462. {
  463. prev = carry;
  464. carry += (uint64_t)m_mantissa[bigit_count() - 1 - j]
  465. * (uint64_t)x.m_mantissa[j - 1 - i];
  466. if (carry < prev)
  467. hicarry++;
  468. }
  469. prev = carry;
  470. carry += m_mantissa[bigit_count() - 1 - i];
  471. carry += x.m_mantissa[bigit_count() - 1 - i];
  472. if (carry < prev)
  473. hicarry++;
  474. ret.m_mantissa[bigit_count() - 1 - i] = carry & ~(bigit_t)0;
  475. carry >>= bigit_bits();
  476. carry |= hicarry << bigit_bits();
  477. hicarry >>= bigit_bits();
  478. }
  479. /* Renormalise in case we overflowed the mantissa */
  480. if (carry)
  481. {
  482. carry--;
  483. for (int i = 0; i < bigit_count(); ++i)
  484. {
  485. bigit_t tmp = ret.m_mantissa[i];
  486. ret.m_mantissa[i] = ((bigit_t)carry << (bigit_bits() - 1))
  487. | (tmp >> 1);
  488. carry = tmp & 1u;
  489. }
  490. ++ret.m_exponent;
  491. }
  492. return ret;
  493. }
  494. template<> inline real real::operator /(real const &x) const
  495. {
  496. return *this * inverse(x);
  497. }
  498. template<> inline real const &real::operator +=(real const &x)
  499. {
  500. real tmp = *this;
  501. return *this = tmp + x;
  502. }
  503. template<> inline real const &real::operator -=(real const &x)
  504. {
  505. real tmp = *this;
  506. return *this = tmp - x;
  507. }
  508. template<> inline real const &real::operator *=(real const &x)
  509. {
  510. real tmp = *this;
  511. return *this = tmp * x;
  512. }
  513. template<> inline real const &real::operator /=(real const &x)
  514. {
  515. real tmp = *this;
  516. return *this = tmp / x;
  517. }
  518. template<> inline bool real::operator ==(real const &x) const
  519. {
  520. /* If NaN is involved, return false */
  521. if (is_nan() || x.is_nan())
  522. return false;
  523. /* If both zero, they are equal; if either is zero, they are different */
  524. if (is_zero() || x.is_zero())
  525. return is_zero() && x.is_zero();
  526. /* FIXME: handle NaN/Inf */
  527. return m_exponent == x.m_exponent && m_mantissa == x.m_mantissa;
  528. }
  529. template<> inline bool real::operator !=(real const &x) const
  530. {
  531. return !(is_nan() || x.is_nan() || *this == x);
  532. }
  533. template<> inline bool real::operator <(real const &x) const
  534. {
  535. /* If NaN is involved, return false */
  536. if (is_nan() || x.is_nan())
  537. return false;
  538. /* Ensure we are positive */
  539. if (is_negative())
  540. return -*this > -x;
  541. /* If x is zero or negative, we can’t be < x */
  542. if (x.is_negative() || x.is_zero())
  543. return false;
  544. /* If we are zero, we must be < x */
  545. if (is_zero())
  546. return true;
  547. /* Compare exponents */
  548. if (m_exponent != x.m_exponent)
  549. return m_exponent < x.m_exponent;
  550. /* Compare all relevant bits */
  551. for (int i = 0; i < bigit_count(); ++i)
  552. if (m_mantissa[i] != x.m_mantissa[i])
  553. return m_mantissa[i] < x.m_mantissa[i];
  554. return false;
  555. }
  556. template<> inline bool real::operator <=(real const &x) const
  557. {
  558. return !(is_nan() || x.is_nan() || *this > x);
  559. }
  560. template<> inline bool real::operator >(real const &x) const
  561. {
  562. /* If NaN is involved, return false */
  563. if (is_nan() || x.is_nan())
  564. return false;
  565. /* Ensure we are positive */
  566. if (is_negative())
  567. return -*this < -x;
  568. /* If x is zero, we’re > x iff we’re non-zero since we’re positive */
  569. if (x.is_zero())
  570. return !is_zero();
  571. /* If x is strictly negative, we’re > x */
  572. if (x.is_negative())
  573. return true;
  574. /* If we are zero, we can’t be > x */
  575. if (is_zero())
  576. return false;
  577. /* Compare exponents */
  578. if (m_exponent != x.m_exponent)
  579. return m_exponent > x.m_exponent;
  580. /* Compare all relevant bits */
  581. for (int i = 0; i < bigit_count(); ++i)
  582. if (m_mantissa[i] != x.m_mantissa[i])
  583. return m_mantissa[i] > x.m_mantissa[i];
  584. return false;
  585. }
  586. template<> inline bool real::operator >=(real const &x) const
  587. {
  588. return !(is_nan() || x.is_nan() || *this < x);
  589. }
  590. template<> inline bool real::operator !() const
  591. {
  592. return !(bool)*this;
  593. }
  594. template<> inline real::operator bool() const
  595. {
  596. /* A real is "true" if it is non-zero AND not NaN */
  597. return !is_zero() && !is_nan();
  598. }
  599. template<> inline real min(real const &a, real const &b)
  600. {
  601. return (a < b) ? a : b;
  602. }
  603. template<> inline real max(real const &a, real const &b)
  604. {
  605. return (a > b) ? a : b;
  606. }
  607. template<> inline real clamp(real const &x, real const &a, real const &b)
  608. {
  609. return (x < a) ? a : (x > b) ? b : x;
  610. }
  611. template<> inline real inverse(real const &x)
  612. {
  613. real ret;
  614. /* If zero, return infinite */
  615. if (x.is_zero())
  616. return copysign(real::R_INF(), x);
  617. /* Use the system’s float inversion to approximate 1/x */
  618. union { float f; uint32_t x; } u = { 1.0f };
  619. u.x |= x.m_mantissa[0] >> 9;
  620. u.f = 1.0f / u.f;
  621. ret.m_mantissa.resize(x.bigit_count());
  622. ret.m_mantissa[0] = u.x << 9;
  623. ret.m_sign = x.m_sign;
  624. ret.m_exponent = -x.m_exponent + (u.x >> 23) - 0x7f;
  625. /* FIXME: 1+log2(bigit_count) steps of Newton-Raphson seems to be enough for
  626. * convergence, but this hasn’t been checked seriously. */
  627. for (int i = 1; i <= x.bigit_count(); i *= 2)
  628. ret = ret * (real::R_2() - ret * x);
  629. return ret;
  630. }
  631. template<> inline real sqrt(real const &x)
  632. {
  633. /* if zero, return x (FIXME: negative zero?) */
  634. if (x.is_zero())
  635. return x;
  636. /* if negative, return NaN */
  637. if (x.is_negative())
  638. return real::R_NAN();
  639. int tweak = x.m_exponent & 1;
  640. /* Use the system’s float inversion to approximate 1/sqrt(x). First
  641. * we construct a float in the [1..4[ range that has roughly the same
  642. * mantissa as our real. Its exponent is 0 or 1, depending on the
  643. * parity of x’s exponent. The final exponent is 0, -1 or -2. We use
  644. * the final exponent and final mantissa to pre-fill the result. */
  645. union { float f; uint32_t x; } u = { 1.0f };
  646. u.x += tweak << 23;
  647. u.x |= x.m_mantissa[0] >> 9;
  648. u.f = 1.0f / sqrtf(u.f);
  649. real ret;
  650. ret.m_mantissa.resize(x.bigit_count());
  651. ret.m_mantissa[0] = u.x << 9;
  652. ret.m_exponent = -(x.m_exponent - tweak) / 2 + (u.x >> 23) - 0x7f;
  653. /* FIXME: 1+log2(bigit_count()) steps of Newton-Raphson seems to be enough for
  654. * convergence, but this hasn’t been checked seriously. */
  655. for (int i = 1; i <= x.bigit_count(); i *= 2)
  656. {
  657. ret = ret * (real::R_3() - ret * ret * x);
  658. --ret.m_exponent;
  659. }
  660. return ret * x;
  661. }
  662. template<> inline real cbrt(real const &x)
  663. {
  664. /* if zero, return x */
  665. if (x.is_zero())
  666. return x;
  667. int tweak = x.m_exponent % 3;
  668. if (tweak < 0)
  669. tweak += 3;
  670. /* Use the system’s float inversion to approximate cbrt(x). First
  671. * we construct a float in the [1..8[ range that has roughly the same
  672. * mantissa as our real. Its exponent is 0, 1 or 2, depending on the
  673. * value of x. The final exponent is 0 or 1 (special case). We use
  674. * the final exponent and final mantissa to pre-fill the result. */
  675. union { float f; uint32_t x; } u = { 1.0f };
  676. u.x += tweak << 23;
  677. u.x |= x.m_mantissa[0] >> 9;
  678. u.f = powf(u.f, 1.f / 3);
  679. real ret;
  680. ret.m_mantissa.resize(x.bigit_count());
  681. ret.m_mantissa[0] = u.x << 9;
  682. ret.m_exponent = (x.m_exponent - tweak) / 3 + (u.x >> 23) - 0x7f;
  683. ret.m_sign = x.m_sign;
  684. /* FIXME: 1+log2(bigit_count()) steps of Newton-Raphson seems to be enough
  685. * for convergence, but this hasn’t been checked seriously. */
  686. real third = inverse(real::R_3());
  687. for (int i = 1; i <= x.bigit_count(); i *= 2)
  688. {
  689. ret = third * (x / (ret * ret) + (ret * 2));
  690. }
  691. return ret;
  692. }
  693. template<> inline real pow(real const &x, real const &y)
  694. {
  695. /* Shortcuts for degenerate cases */
  696. if (!y)
  697. return real::R_1();
  698. if (!x)
  699. return real::R_0();
  700. /* Small integer exponent: use exponentiation by squaring */
  701. int64_t int_y = (int64_t)y;
  702. if (y == (real)int_y)
  703. {
  704. real ret = real::R_1();
  705. real x_n = int_y > 0 ? x : inverse(x);
  706. while (int_y) /* Can be > 0 or < 0 */
  707. {
  708. if (int_y & 1)
  709. ret *= x_n;
  710. x_n *= x_n;
  711. int_y /= 2;
  712. }
  713. return ret;
  714. }
  715. /* If x is positive, nothing special to do. */
  716. if (x > real::R_0())
  717. return exp(y * log(x));
  718. /* XXX: manpage for pow() says “If x is a finite value less than 0,
  719. * and y is a finite noninteger, a domain error occurs, and a NaN is
  720. * returned”. We check whether y is closer to an even number or to
  721. * an odd number and return something reasonable. */
  722. real round_y = round(y);
  723. bool is_odd = round_y / 2 == round(round_y / 2);
  724. return is_odd ? exp(y * log(-x)) : -exp(y * log(-x));
  725. }
  726. /* A fast factorial implementation for small numbers. An optional
  727. * step argument allows to compute double factorials (i.e. with
  728. * only the odd or the even terms. */
  729. static real fast_fact(int x, int step = 1)
  730. {
  731. if (x < step)
  732. return 1;
  733. if (x == step)
  734. return x;
  735. unsigned int start = (x + step - 1) % step + 1;
  736. real ret(start);
  737. uint64_t multiplier = 1;
  738. for (int i = start, exponent = 0;;)
  739. {
  740. if (i >= x)
  741. return ldexp(ret * multiplier, exponent);
  742. i += step;
  743. /* Accumulate the power of two part in the exponent */
  744. unsigned int tmp = i;
  745. while ((tmp & 1) == 0)
  746. {
  747. tmp >>= 1;
  748. exponent++;
  749. }
  750. /* Accumulate the other factors in the multiplier */
  751. if (multiplier * tmp / tmp != multiplier)
  752. {
  753. ret *= multiplier;
  754. multiplier = 1;
  755. }
  756. multiplier *= tmp;
  757. }
  758. }
  759. template<> inline real gamma(real const &x)
  760. {
  761. static float pi = acosf(-1.f);
  762. /* We use Spouge’s formula. FIXME: precision is far from acceptable,
  763. * especially with large values. We need to compute this with higher
  764. * precision values in order to attain the desired accuracy. It might
  765. * also be useful to sort the ck values by decreasing absolute value
  766. * and do the addition in this order. */
  767. int a = (int)ceilf(logf(2) / logf(2 * pi) * x.total_bits());
  768. real ret = sqrt(real::R_PI() * 2);
  769. real fact_k_1 = real::R_1();
  770. for (int k = 1; k < a; k++)
  771. {
  772. real a_k = (real)(a - k);
  773. real ck = pow(a_k, (real)((float)k - 0.5)) * exp(a_k)
  774. / (fact_k_1 * (x + (real)(k - 1)));
  775. ret += ck;
  776. fact_k_1 *= (real)-k;
  777. }
  778. ret *= pow(x + (real)(a - 1), x - (real::R_1() / 2));
  779. ret *= exp(-x - (real)(a - 1));
  780. return ret;
  781. }
  782. template<> inline real fabs(real const &x)
  783. {
  784. real ret = x;
  785. ret.m_sign = false;
  786. return ret;
  787. }
  788. template<> inline real abs(real const &x)
  789. {
  790. return fabs(x);
  791. }
  792. template<> inline real fract(real const &x)
  793. {
  794. return x - floor(x);
  795. }
  796. template<> inline real degrees(real const &x)
  797. {
  798. /* FIXME: need to recompute this for different mantissa sizes */
  799. static real mul = real(180) * real::R_1_PI();
  800. return x * mul;
  801. }
  802. template<> inline real radians(real const &x)
  803. {
  804. /* FIXME: need to recompute this for different mantissa sizes */
  805. static real mul = real::R_PI() / real(180);
  806. return x * mul;
  807. }
  808. static real fast_log(real const &x)
  809. {
  810. /* This fast log method is tuned to work on the [1..2] range and
  811. * no effort whatsoever was made to improve convergence outside this
  812. * domain of validity. It can converge pretty fast, provided we use
  813. * the following variable substitutions:
  814. * y = sqrt(x)
  815. * z = (y - 1) / (y + 1)
  816. *
  817. * And the following identities:
  818. * ln(x) = 2 ln(y)
  819. * = 2 ln((1 + z) / (1 - z))
  820. * = 4 z (1 + z^2 / 3 + z^4 / 5 + z^6 / 7...)
  821. *
  822. * Any additional sqrt() call would halve the convergence time, but
  823. * would also impact the final precision. For now we stick with one
  824. * sqrt() call. */
  825. real y = sqrt(x);
  826. real z = (y - real::R_1()) / (y + real::R_1()), z2 = z * z, zn = z2;
  827. real sum = real::R_1();
  828. for (int i = 3; ; i += 2)
  829. {
  830. real newsum = sum + zn / (real)i;
  831. if (newsum == sum)
  832. break;
  833. sum = newsum;
  834. zn *= z2;
  835. }
  836. return z * sum * 4;
  837. }
  838. template<> inline real log(real const &x)
  839. {
  840. /* Strategy for log(x): if x = 2^E*M then log(x) = E log(2) + log(M),
  841. * with the property that M is in [1..2[, so fast_log() applies here. */
  842. if (x.is_negative() || x.is_zero())
  843. return real::R_NAN();
  844. real tmp(x);
  845. tmp.m_exponent = 0;
  846. return real(x.m_exponent) * real::R_LN2() + fast_log(tmp);
  847. }
  848. template<> inline real log2(real const &x)
  849. {
  850. /* Strategy for log2(x): see log(x). */
  851. if (x.is_negative() || x.is_zero())
  852. return real::R_NAN();
  853. real tmp(x);
  854. tmp.m_exponent = 0;
  855. return real(x.m_exponent) + fast_log(tmp) * real::R_LOG2E();
  856. }
  857. template<> inline real log10(real const &x)
  858. {
  859. return log(x) * real::R_LOG10E();
  860. }
  861. static real fast_exp_sub(real const &x, real const &y)
  862. {
  863. /* This fast exp method is tuned to work on the [-1..1] range and
  864. * no effort whatsoever was made to improve convergence outside this
  865. * domain of validity. The argument y is used for cases where we
  866. * don’t want the leading 1 in the Taylor series. */
  867. real ret = real::R_1() - y, xn = x;
  868. int i = 1;
  869. for (;;)
  870. {
  871. real newret = ret + xn;
  872. if (newret == ret)
  873. break;
  874. ret = newret * ++i;
  875. xn *= x;
  876. }
  877. return ret / fast_fact(i);
  878. }
  879. template<> inline real exp(real const &x)
  880. {
  881. /* Strategy for exp(x): the Taylor series does not converge very fast
  882. * with large positive or negative values.
  883. *
  884. * However, since the result is going to be in the form M*2^E, we first
  885. * try to predict a value for E, which is approximately:
  886. * E ≈ log2(exp(x)) = x / log(2)
  887. *
  888. * Let E0 be an integer close to x / log(2). We need to find a value x0
  889. * such that exp(x) = 2^E0 * exp(x0). We get x0 = x - E0 log(2).
  890. *
  891. * Thus the final algorithm:
  892. * int E0 = x / log(2)
  893. * real x0 = x - E0 log(2)
  894. * real x1 = exp(x0)
  895. * return x1 * 2^E0
  896. */
  897. real::exponent_t e0 = x / real::R_LN2();
  898. real x0 = x - (real)e0 * real::R_LN2();
  899. real x1 = fast_exp_sub(x0, real::R_0());
  900. x1.m_exponent += e0;
  901. return x1;
  902. }
  903. template<> inline real exp2(real const &x)
  904. {
  905. /* Strategy for exp2(x): see strategy in exp(). */
  906. real::exponent_t e0 = x;
  907. real x0 = x - (real)e0;
  908. real x1 = fast_exp_sub(x0 * real::R_LN2(), real::R_0());
  909. x1.m_exponent += e0;
  910. return x1;
  911. }
  912. template<> inline real erf(real const &x)
  913. {
  914. /* Strategy for erf(x):
  915. * - if x<0, erf(x) = -erf(-x)
  916. * - if x<7, erf(x) = sum((-1)^n·x^(2n+1)/((2n+1)·n!))/sqrt(π/4)
  917. * - if x≥7, erf(x) = 1+exp(-x²)/(x·sqrt(π))·sum((-1)^n·(2n-1)!!/(2x²)^n
  918. *
  919. * FIXME: do not compute factorials at each iteration, accumulate
  920. * them instead (see fast_exp_sub).
  921. * FIXME: For a potentially faster implementation, see “Expanding the
  922. * Error Function erf(z)” at:
  923. * http://www.mathematica-journal.com/2014/11/on-burmanns-theorem-and-its-application-to-problems-of-linear-and-nonlinear-heat-transfer-and-diffusion/#more-39602/
  924. */
  925. if (x.is_negative())
  926. return -erf(-x);
  927. real sum = real::R_0();
  928. real x2 = x * x;
  929. /* FIXME: this test is inefficient; the series converges slowly for x≥1 */
  930. if (x < real(7))
  931. {
  932. real xn = x, xmul = x2;
  933. for (int n = 0;; ++n, xn *= xmul)
  934. {
  935. real tmp = xn / (fast_fact(n) * (2 * n + 1));
  936. real newsum = (n & 1) ? sum - tmp : sum + tmp;
  937. if (newsum == sum)
  938. break;
  939. sum = newsum;
  940. }
  941. return sum * real::R_2_SQRTPI();
  942. }
  943. else
  944. {
  945. real xn = real::R_1(), xmul = inverse(x2 + x2);
  946. /* FIXME: this does not converge well! We need to stop at 30
  947. * iterations and sacrifice some accuracy. */
  948. for (int n = 0; n < 30; ++n, xn *= xmul)
  949. {
  950. real tmp = xn * fast_fact(n * 2 - 1, 2);
  951. real newsum = (n & 1) ? sum - tmp : sum + tmp;
  952. if (newsum == sum)
  953. break;
  954. sum = newsum;
  955. }
  956. return real::R_1() - exp(-x2) / (x * sqrt(real::R_PI())) * sum;
  957. }
  958. }
  959. template<> inline real sinh(real const &x)
  960. {
  961. /* We cannot always use (exp(x)-exp(-x))/2 because we'll lose
  962. * accuracy near zero. We only use this identity for |x|>0.5. If
  963. * |x|<=0.5, we compute exp(x)-1 and exp(-x)-1 instead. */
  964. bool near_zero = (fabs(x) < real::R_1() / 2);
  965. real x1 = near_zero ? fast_exp_sub(x, real::R_1()) : exp(x);
  966. real x2 = near_zero ? fast_exp_sub(-x, real::R_1()) : exp(-x);
  967. return (x1 - x2) / 2;
  968. }
  969. template<> inline real tanh(real const &x)
  970. {
  971. /* See sinh() for the strategy here */
  972. bool near_zero = (fabs(x) < real::R_1() / 2);
  973. real x1 = near_zero ? fast_exp_sub(x, real::R_1()) : exp(x);
  974. real x2 = near_zero ? fast_exp_sub(-x, real::R_1()) : exp(-x);
  975. real x3 = near_zero ? x1 + x2 + real::R_2() : x1 + x2;
  976. return (x1 - x2) / x3;
  977. }
  978. template<> inline real cosh(real const &x)
  979. {
  980. /* No need to worry about accuracy here; maybe the last bit is slightly
  981. * off, but that's about it. */
  982. return (exp(x) + exp(-x)) / 2;
  983. }
  984. template<> inline real frexp(real const &x, real::exponent_t *exp)
  985. {
  986. if (!x)
  987. {
  988. *exp = 0;
  989. return x;
  990. }
  991. /* FIXME: check that this works */
  992. *exp = x.m_exponent;
  993. real ret = x;
  994. ret.m_exponent = 0;
  995. return ret;
  996. }
  997. template<> inline real ldexp(real const &x, real::exponent_t exp)
  998. {
  999. real ret = x;
  1000. if (ret) /* Only do something if non-zero */
  1001. ret.m_exponent += exp;
  1002. return ret;
  1003. }
  1004. template<> inline real modf(real const &x, real *iptr)
  1005. {
  1006. real absx = fabs(x);
  1007. real tmp = floor(absx);
  1008. *iptr = copysign(tmp, x);
  1009. return copysign(absx - tmp, x);
  1010. }
  1011. template<> inline real nextafter(real const &x, real const &y)
  1012. {
  1013. /* Linux manpage: “If x equals y, the functions return y.” */
  1014. if (x == y)
  1015. return y;
  1016. /* Ensure x is positive. */
  1017. if (x.is_negative())
  1018. return -nextafter(-x, -y);
  1019. /* FIXME: broken for now */
  1020. real ulp = ldexp(x, -x.total_bits());
  1021. return x < y ? x + ulp : x - ulp;
  1022. }
  1023. template<> inline real copysign(real const &x, real const &y)
  1024. {
  1025. real ret = x;
  1026. ret.m_sign = y.m_sign;
  1027. return ret;
  1028. }
  1029. template<> inline real floor(real const &x)
  1030. {
  1031. /* Strategy for floor(x):
  1032. * - if negative, return -ceil(-x)
  1033. * - if zero or negative zero, return x
  1034. * - if less than one, return zero
  1035. * - otherwise, if e is the exponent, clear all bits except the
  1036. * first e. */
  1037. if (x < -real::R_0())
  1038. return -ceil(-x);
  1039. if (!x)
  1040. return x;
  1041. if (x < real::R_1())
  1042. return real::R_0();
  1043. real ret = x;
  1044. real::exponent_t exponent = x.m_exponent;
  1045. for (int i = 0; i < x.bigit_count(); ++i)
  1046. {
  1047. if (exponent <= 0)
  1048. ret.m_mantissa[i] = 0;
  1049. else if (exponent < real::bigit_bits())
  1050. ret.m_mantissa[i] &= ~((1 << (real::bigit_bits() - exponent)) - 1);
  1051. exponent -= real::bigit_bits();
  1052. }
  1053. return ret;
  1054. }
  1055. template<> inline real ceil(real const &x)
  1056. {
  1057. /* Strategy for ceil(x):
  1058. * - if negative, return -floor(-x)
  1059. * - if x == floor(x), return x
  1060. * - otherwise, return floor(x) + 1 */
  1061. if (x < -real::R_0())
  1062. return -floor(-x);
  1063. real ret = floor(x);
  1064. if (ret < x)
  1065. ret += real::R_1();
  1066. return ret;
  1067. }
  1068. template<> inline real round(real const &x)
  1069. {
  1070. if (x < real::R_0())
  1071. return -round(-x);
  1072. return floor(x + (real::R_1() / 2));
  1073. }
  1074. template<> inline real fmod(real const &x, real const &y)
  1075. {
  1076. if (!y)
  1077. return real::R_0(); /* FIXME: return NaN */
  1078. if (!x)
  1079. return x;
  1080. real tmp = round(x / y);
  1081. return x - tmp * y;
  1082. }
  1083. template<> inline real sin(real const &x)
  1084. {
  1085. bool switch_sign = x.is_negative();
  1086. real absx = fmod(fabs(x), real::R_PI() * 2);
  1087. if (absx > real::R_PI())
  1088. {
  1089. absx -= real::R_PI();
  1090. switch_sign = !switch_sign;
  1091. }
  1092. if (absx > real::R_PI_2())
  1093. absx = real::R_PI() - absx;
  1094. real ret = real::R_0(), fact = real::R_1(), xn = absx, mx2 = -absx * absx;
  1095. int i = 1;
  1096. for (;;)
  1097. {
  1098. real newret = ret + xn;
  1099. if (newret == ret)
  1100. break;
  1101. ret = newret * ((i + 1) * (i + 2));
  1102. xn *= mx2;
  1103. i += 2;
  1104. }
  1105. ret /= fast_fact(i);
  1106. /* Propagate sign */
  1107. ret.m_sign ^= switch_sign;
  1108. return ret;
  1109. }
  1110. template<> inline real cos(real const &x)
  1111. {
  1112. return sin(real::R_PI_2() - x);
  1113. }
  1114. template<> inline real tan(real const &x)
  1115. {
  1116. /* Constrain input to [-π,π] */
  1117. real y = fmod(x, real::R_PI());
  1118. /* Constrain input to [-π/2,π/2] */
  1119. if (y < -real::R_PI_2())
  1120. y += real::R_PI();
  1121. else if (y > real::R_PI_2())
  1122. y -= real::R_PI();
  1123. /* In [-π/4,π/4] return sin/cos */
  1124. if (fabs(y) <= real::R_PI_4())
  1125. return sin(y) / cos(y);
  1126. /* Otherwise, return cos/sin */
  1127. if (y > real::R_0())
  1128. y = real::R_PI_2() - y;
  1129. else
  1130. y = -real::R_PI_2() - y;
  1131. return cos(y) / sin(y);
  1132. }
  1133. static inline real asinacos(real const &x, int is_asin)
  1134. {
  1135. /* Strategy for asin(): in [-0.5..0.5], use a Taylor series around
  1136. * zero. In [0.5..1], use asin(x) = π/2 - 2*asin(sqrt((1-x)/2)), and
  1137. * in [-1..-0.5] just revert the sign.
  1138. * Strategy for acos(): use acos(x) = π/2 - asin(x) and try not to
  1139. * lose the precision around x=1. */
  1140. real absx = fabs(x);
  1141. int around_zero = (absx < (real::R_1() / 2));
  1142. if (!around_zero)
  1143. absx = sqrt((real::R_1() - absx) / 2);
  1144. real ret = absx, xn = absx, x2 = absx * absx, fact1 = 2, fact2 = 1;
  1145. for (int i = 1; ; ++i)
  1146. {
  1147. xn *= x2;
  1148. real mul = (real)(2 * i + 1);
  1149. real newret = ret + ldexp(fact1 * xn / (mul * fact2), -2 * i);
  1150. if (newret == ret)
  1151. break;
  1152. ret = newret;
  1153. fact1 *= (real)((2 * i + 1) * (2 * i + 2));
  1154. fact2 *= (real)((i + 1) * (i + 1));
  1155. }
  1156. if (x.is_negative())
  1157. ret = -ret;
  1158. if (around_zero)
  1159. ret = is_asin ? ret : real::R_PI_2() - ret;
  1160. else
  1161. {
  1162. real adjust = x.is_negative() ? real::R_PI() : real::R_0();
  1163. if (is_asin)
  1164. ret = real::R_PI_2() - adjust - ret * 2;
  1165. else
  1166. ret = adjust + ret * 2;
  1167. }
  1168. return ret;
  1169. }
  1170. template<> inline real asin(real const &x)
  1171. {
  1172. return asinacos(x, 1);
  1173. }
  1174. template<> inline real acos(real const &x)
  1175. {
  1176. return asinacos(x, 0);
  1177. }
  1178. template<> inline real atan(real const &x)
  1179. {
  1180. /* Computing atan(x): we choose a different Taylor series depending on
  1181. * the value of x to help with convergence.
  1182. *
  1183. * If |x| < 0.5 we evaluate atan(y) near 0:
  1184. * atan(y) = y - y^3/3 + y^5/5 - y^7/7 + y^9/9 ...
  1185. *
  1186. * If 0.5 <= |x| < 1.5 we evaluate atan(1+y) near 0:
  1187. * atan(1+y) = π/4 + y/(1*2^1) - y^2/(2*2^1) + y^3/(3*2^2)
  1188. * - y^5/(5*2^3) + y^6/(6*2^3) - y^7/(7*2^4)
  1189. * + y^9/(9*2^5) - y^10/(10*2^5) + y^11/(11*2^6) ...
  1190. *
  1191. * If 1.5 <= |x| < 2 we evaluate atan(sqrt(3)+2y) near 0:
  1192. * atan(sqrt(3)+2y) = π/3 + 1/2 y - sqrt(3)/2 y^2/2
  1193. * + y^3/3 - sqrt(3)/2 y^4/4 + 1/2 y^5/5
  1194. * - 1/2 y^7/7 + sqrt(3)/2 y^8/8
  1195. * - y^9/9 + sqrt(3)/2 y^10/10 - 1/2 y^11/11
  1196. * + 1/2 y^13/13 - sqrt(3)/2 y^14/14
  1197. * + y^15/15 - sqrt(3)/2 y^16/16 + 1/2 y^17/17 ...
  1198. *
  1199. * If |x| >= 2 we evaluate atan(y) near +∞:
  1200. * atan(y) = π/2 - y^-1 + y^-3/3 - y^-5/5 + y^-7/7 - y^-9/9 ...
  1201. */
  1202. real absx = fabs(x);
  1203. if (absx < (real::R_1() / 2))
  1204. {
  1205. real ret = x, xn = x, mx2 = -x * x;
  1206. for (int i = 3; ; i += 2)
  1207. {
  1208. xn *= mx2;
  1209. real newret = ret + xn / (real)i;
  1210. if (newret == ret)
  1211. break;
  1212. ret = newret;
  1213. }
  1214. return ret;
  1215. }
  1216. real ret = 0;
  1217. if (absx < (real::R_3() / 2))
  1218. {
  1219. real y = real::R_1() - absx;
  1220. real yn = y, my2 = -y * y;
  1221. for (int i = 0; ; i += 2)
  1222. {
  1223. real newret = ret + ldexp(yn / (real)(2 * i + 1), -i - 1);
  1224. yn *= y;
  1225. newret += ldexp(yn / (real)(2 * i + 2), -i - 1);
  1226. yn *= y;
  1227. newret += ldexp(yn / (real)(2 * i + 3), -i - 2);
  1228. if (newret == ret)
  1229. break;
  1230. ret = newret;
  1231. yn *= my2;
  1232. }
  1233. ret = real::R_PI_4() - ret;
  1234. }
  1235. else if (absx < real::R_2())
  1236. {
  1237. real y = (absx - real::R_SQRT3()) / 2;
  1238. real yn = y, my2 = -y * y;
  1239. for (int i = 1; ; i += 6)
  1240. {
  1241. real newret = ret + ((yn / (real)i) / 2);
  1242. yn *= y;
  1243. newret -= (real::R_SQRT3() / 2) * yn / (real)(i + 1);
  1244. yn *= y;
  1245. newret += yn / (real)(i + 2);
  1246. yn *= y;
  1247. newret -= (real::R_SQRT3() / 2) * yn / (real)(i + 3);
  1248. yn *= y;
  1249. newret += (yn / (real)(i + 4)) / 2;
  1250. if (newret == ret)
  1251. break;
  1252. ret = newret;
  1253. yn *= my2;
  1254. }
  1255. ret = real::R_PI_3() + ret;
  1256. }
  1257. else
  1258. {
  1259. real y = inverse(absx);
  1260. real yn = y, my2 = -y * y;
  1261. ret = y;
  1262. for (int i = 3; ; i += 2)
  1263. {
  1264. yn *= my2;
  1265. real newret = ret + yn / (real)i;
  1266. if (newret == ret)
  1267. break;
  1268. ret = newret;
  1269. }
  1270. ret = real::R_PI_2() - ret;
  1271. }
  1272. /* Propagate sign */
  1273. ret.m_sign = x.m_sign;
  1274. return ret;
  1275. }
  1276. template<> inline real atan2(real const &y, real const &x)
  1277. {
  1278. if (!y)
  1279. {
  1280. if (!x.is_negative())
  1281. return y;
  1282. return y.is_negative() ? -real::R_PI() : real::R_PI();
  1283. }
  1284. if (!x)
  1285. {
  1286. return y.is_negative() ? -real::R_PI() : real::R_PI();
  1287. }
  1288. /* FIXME: handle the Inf and NaN cases */
  1289. real z = y / x;
  1290. real ret = atan(z);
  1291. if (x < real::R_0())
  1292. ret += (y > real::R_0()) ? real::R_PI() : -real::R_PI();
  1293. return ret;
  1294. }
  1295. /* Franke’s function, used as a test for interpolation methods */
  1296. template<> inline real franke(real const &x, real const &y)
  1297. {
  1298. /* Compute 9x and 9y */
  1299. real nx = x + x; nx += nx; nx += nx + x;
  1300. real ny = y + y; ny += ny; ny += ny + y;
  1301. /* Temporary variables for the formula */
  1302. real a = nx - real::R_2();
  1303. real b = ny - real::R_2();
  1304. real c = nx + real::R_1();
  1305. real d = ny + real::R_1();
  1306. real e = nx - real(7);
  1307. real f = ny - real::R_3();
  1308. real g = nx - real(4);
  1309. real h = ny - real(7);
  1310. return exp(-(a * a + b * b) * real(0.25)) * real(0.75)
  1311. + exp(-(c * c / real(49) + d * d / real::R_10())) * real(0.75)
  1312. + exp(-(e * e + f * f) * real(0.25)) * real(0.5)
  1313. - exp(-(g * g + h * h)) / real(5);
  1314. }
  1315. /* The Peaks example function from Matlab */
  1316. template<> inline real peaks(real const &x, real const &y)
  1317. {
  1318. real x2 = x * x;
  1319. real y2 = y * y;
  1320. /* 3 * (1-x)^2 * exp(-x^2 - (y+1)^2) */
  1321. real ret = real::R_3()
  1322. * (x2 - x - x + real::R_1())
  1323. * exp(- x2 - y2 - y - y - real::R_1());
  1324. /* -10 * (x/5 - x^3 - y^5) * exp(-x^2 - y^2) */
  1325. ret -= (x + x - real::R_10() * (x2 * x + y2 * y2 * y)) * exp(-x2 - y2);
  1326. /* -1/3 * exp(-(x+1)^2 - y^2) */
  1327. ret -= exp(-x2 - x - x - real::R_1() - y2) / real::R_3();
  1328. return ret;
  1329. }
  1330. template<> inline
  1331. std::ostream& operator <<(std::ostream &s, real const &x)
  1332. {
  1333. bool hex = (s.flags() & std::ios_base::basefield) == std::ios_base::hex;
  1334. s << (hex ? x.xstr() : x.str((int)s.precision()));
  1335. return s;
  1336. }
  1337. template<> inline std::string real::str(int ndigits) const
  1338. {
  1339. std::stringstream ss;
  1340. real x = *this;
  1341. if (x.is_negative())
  1342. {
  1343. ss << '-';
  1344. x = -x;
  1345. }
  1346. if (!x)
  1347. {
  1348. ss << '0';
  1349. return ss.str();
  1350. }
  1351. // Normalise x so that mantissa is in [1..9.999]
  1352. // FIXME: better use int64_t when the cast is implemented
  1353. // FIXME: does not work with R_MAX and probably R_MIN
  1354. int exponent = ceil(log10(x));
  1355. x *= pow(R_10(), -(real)exponent);
  1356. if (ndigits < 1)
  1357. ndigits = 1;
  1358. // Add a bias to simulate some naive rounding
  1359. x += real(4.99f) * pow(R_10(), -(real)(ndigits + 1));
  1360. if (x < R_1())
  1361. {
  1362. x *= R_10();
  1363. exponent--;
  1364. }
  1365. // Print digits
  1366. for (int i = 0; i < ndigits; ++i)
  1367. {
  1368. int digit = (int)floor(x);
  1369. ss << (char)('0' + digit);
  1370. if (i == 0)
  1371. ss << '.';
  1372. x -= real(digit);
  1373. x *= R_10();
  1374. }
  1375. // Remove trailing zeroes
  1376. std::string ret = ss.str();
  1377. ss.str("");
  1378. size_t end = ret.find_last_not_of('0');
  1379. if (end != std::string::npos)
  1380. ss << ret.substr(0, end + 1);
  1381. // Print exponent information
  1382. if (exponent)
  1383. ss << 'e' << (exponent >= 0 ? '+' : '-') << std::abs(exponent);
  1384. return ss.str();
  1385. }
  1386. template<> inline std::string real::xstr() const
  1387. {
  1388. std::stringstream ss;
  1389. if (is_negative())
  1390. ss << '-';
  1391. ss << "0x1." << std::hex << std::setfill('0');
  1392. for (int i = 0; i < bigit_count(); ++i)
  1393. ss << std::setw(8) << m_mantissa[i];
  1394. ss << std::dec;
  1395. // Remove trailing zeroes
  1396. std::string ret = ss.str();
  1397. ss.str("");
  1398. size_t end = ret.find_last_not_of('0');
  1399. if (end != std::string::npos)
  1400. ss << ret.substr(0, end + 1);
  1401. ss << 'p' << m_exponent;
  1402. return ss.str();
  1403. }
  1404. static real load_min()
  1405. {
  1406. real ret = 1;
  1407. return ldexp(ret, std::numeric_limits<real::exponent_t>::min());
  1408. }
  1409. static real load_max()
  1410. {
  1411. /* FIXME: the last bits of the mantissa are not properly handled in this
  1412. * code! So we fallback to a slow but exact method. */
  1413. #if 0
  1414. real ret = 1;
  1415. ret = ldexp(ret, real::TOTAL_BITS - 1) - ret;
  1416. return ldexp(ret, real::EXPONENT_BIAS + 2 - real::TOTAL_BITS);
  1417. #endif
  1418. /* Generates 0x1.ffff..ffffp18446744073709551615 */
  1419. char str[160];
  1420. std::sprintf(str, "0x1.%llx%llx%llx%llx%llx%llx%llx%llxp%lld",
  1421. -1ll, -1ll, -1ll, -1ll, -1ll, -1ll, -1ll, -1ll,
  1422. (long long int)std::numeric_limits<int64_t>::max());
  1423. return real(str);
  1424. }
  1425. static real load_pi()
  1426. {
  1427. /* Approximate π using Machin’s formula: 16*atan(1/5)-4*atan(1/239) */
  1428. real ret = 0, x0 = 5, x1 = 239;
  1429. real const m0 = -x0 * x0, m1 = -x1 * x1, r16 = 16, r4 = 4;
  1430. for (int i = 1; ; i += 2)
  1431. {
  1432. real newret = ret + r16 / (x0 * (real)i) - r4 / (x1 * (real)i);
  1433. if (newret == ret)
  1434. break;
  1435. ret = newret;
  1436. x0 *= m0;
  1437. x1 *= m1;
  1438. }
  1439. return ret;
  1440. }
  1441. } /* namespace lol */