default_ops.hpp 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright 2011 John Maddock. Distributed under the Boost
  3. // Software License, Version 1.0. (See accompanying file
  4. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_MATH_BIG_NUM_DEF_OPS
  6. #define BOOST_MATH_BIG_NUM_DEF_OPS
  7. #include <boost/math/policies/error_handling.hpp>
  8. #include <boost/multiprecision/detail/number_base.hpp>
  9. #include <boost/math/special_functions/fpclassify.hpp>
  10. #include <boost/utility/enable_if.hpp>
  11. #include <boost/mpl/front.hpp>
  12. #include <boost/mpl/fold.hpp>
  13. #include <boost/cstdint.hpp>
  14. #include <boost/type_traits/make_unsigned.hpp>
  15. #ifndef INSTRUMENT_BACKEND
  16. #ifndef BOOST_MP_INSTRUMENT
  17. #define INSTRUMENT_BACKEND(x)
  18. #else
  19. #define INSTRUMENT_BACKEND(x)\
  20. std::cout << BOOST_STRINGIZE(x) << " = " << x.str(0, std::ios_base::scientific) << std::endl;
  21. #endif
  22. #endif
  23. namespace boost{ namespace multiprecision{ namespace default_ops{
  24. #ifdef BOOST_MSVC
  25. // warning C4127: conditional expression is constant
  26. #pragma warning(push)
  27. #pragma warning(disable:4127)
  28. #endif
  29. //
  30. // Default versions of mixed arithmetic, these just construct a temporary
  31. // from the arithmetic value and then do the arithmetic on that, two versions
  32. // of each depending on whether the backend can be directly constructed from type V.
  33. //
  34. // Note that we have to provide *all* the template parameters to class number when used in
  35. // enable_if as MSVC-10 won't compile the code if we rely on a computed-default parameter.
  36. // Since the result of the test doesn't depend on whether expression templates are on or off
  37. // we just use et_on everywhere. We could use a BOOST_WORKAROUND but that just obfuscates the
  38. // code even more....
  39. //
  40. template <class T, class V>
  41. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && !is_convertible<V, T>::value >::type
  42. eval_add(T& result, V const& v)
  43. {
  44. T t;
  45. t = v;
  46. eval_add(result, t);
  47. }
  48. template <class T, class V>
  49. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && is_convertible<V, T>::value >::type
  50. eval_add(T& result, V const& v)
  51. {
  52. T t(v);
  53. eval_add(result, t);
  54. }
  55. template <class T, class V>
  56. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && !is_convertible<V, T>::value>::type
  57. eval_subtract(T& result, V const& v)
  58. {
  59. T t;
  60. t = v;
  61. eval_subtract(result, t);
  62. }
  63. template <class T, class V>
  64. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && is_convertible<V, T>::value>::type
  65. eval_subtract(T& result, V const& v)
  66. {
  67. T t(v);
  68. eval_subtract(result, t);
  69. }
  70. template <class T, class V>
  71. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && !is_convertible<V, T>::value>::type
  72. eval_multiply(T& result, V const& v)
  73. {
  74. T t;
  75. t = v;
  76. eval_multiply(result, t);
  77. }
  78. template <class T, class V>
  79. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && is_convertible<V, T>::value>::type
  80. eval_multiply(T& result, V const& v)
  81. {
  82. T t(v);
  83. eval_multiply(result, t);
  84. }
  85. template <class T, class U, class V>
  86. void eval_multiply(T& t, const U& u, const V& v);
  87. template <class T, class U, class V>
  88. inline typename disable_if_c<!is_same<T, U>::value && is_same<T, V>::value>::type eval_multiply_add(T& t, const U& u, const V& v)
  89. {
  90. T z;
  91. eval_multiply(z, u, v);
  92. eval_add(t, z);
  93. }
  94. template <class T, class U, class V>
  95. inline typename enable_if_c<!is_same<T, U>::value && is_same<T, V>::value>::type eval_multiply_add(T& t, const U& u, const V& v)
  96. {
  97. eval_multiply_add(t, v, u);
  98. }
  99. template <class T, class U, class V>
  100. inline typename disable_if_c<!is_same<T, U>::value && is_same<T, V>::value>::type eval_multiply_subtract(T& t, const U& u, const V& v)
  101. {
  102. T z;
  103. eval_multiply(z, u, v);
  104. eval_subtract(t, z);
  105. }
  106. template <class T, class U, class V>
  107. inline typename enable_if_c<!is_same<T, U>::value && is_same<T, V>::value>::type eval_multiply_subtract(T& t, const U& u, const V& v)
  108. {
  109. eval_multiply_subtract(t, v, u);
  110. }
  111. template <class T, class V>
  112. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && !is_convertible<V, T>::value>::type
  113. eval_divide(T& result, V const& v)
  114. {
  115. T t;
  116. t = v;
  117. eval_divide(result, t);
  118. }
  119. template <class T, class V>
  120. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && is_convertible<V, T>::value>::type
  121. eval_divide(T& result, V const& v)
  122. {
  123. T t(v);
  124. eval_divide(result, t);
  125. }
  126. template <class T, class V>
  127. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && !is_convertible<V, T>::value>::type
  128. eval_modulus(T& result, V const& v)
  129. {
  130. T t;
  131. t = v;
  132. eval_modulus(result, t);
  133. }
  134. template <class T, class V>
  135. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value&& is_convertible<V, T>::value>::type
  136. eval_modulus(T& result, V const& v)
  137. {
  138. T t(v);
  139. eval_modulus(result, t);
  140. }
  141. template <class T, class V>
  142. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && !is_convertible<V, T>::value>::type
  143. eval_bitwise_and(T& result, V const& v)
  144. {
  145. T t;
  146. t = v;
  147. eval_bitwise_and(result, t);
  148. }
  149. template <class T, class V>
  150. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && is_convertible<V, T>::value>::type
  151. eval_bitwise_and(T& result, V const& v)
  152. {
  153. T t(v);
  154. eval_bitwise_and(result, t);
  155. }
  156. template <class T, class V>
  157. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && !is_convertible<V, T>::value>::type
  158. eval_bitwise_or(T& result, V const& v)
  159. {
  160. T t;
  161. t = v;
  162. eval_bitwise_or(result, t);
  163. }
  164. template <class T, class V>
  165. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && is_convertible<V, T>::value>::type
  166. eval_bitwise_or(T& result, V const& v)
  167. {
  168. T t(v);
  169. eval_bitwise_or(result, t);
  170. }
  171. template <class T, class V>
  172. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && !is_convertible<V, T>::value>::type
  173. eval_bitwise_xor(T& result, V const& v)
  174. {
  175. T t;
  176. t = v;
  177. eval_bitwise_xor(result, t);
  178. }
  179. template <class T, class V>
  180. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && is_convertible<V, T>::value>::type
  181. eval_bitwise_xor(T& result, V const& v)
  182. {
  183. T t(v);
  184. eval_bitwise_xor(result, t);
  185. }
  186. template <class T, class V>
  187. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && !is_convertible<V, T>::value>::type
  188. eval_complement(T& result, V const& v)
  189. {
  190. T t;
  191. t = v;
  192. eval_complement(result, t);
  193. }
  194. template <class T, class V>
  195. inline typename enable_if_c<is_convertible<V, number<T, et_on> >::value && is_convertible<V, T>::value>::type
  196. eval_complement(T& result, V const& v)
  197. {
  198. T t(v);
  199. eval_complement(result, t);
  200. }
  201. //
  202. // Default versions of 3-arg arithmetic functions, these mostly just forward to the 2 arg versions:
  203. //
  204. template <class T, class U, class V>
  205. void eval_add(T& t, const U& u, const V& v);
  206. template <class T>
  207. inline void eval_add_default(T& t, const T& u, const T& v)
  208. {
  209. if(&t == &v)
  210. {
  211. eval_add(t, u);
  212. }
  213. else if(&t == &u)
  214. {
  215. eval_add(t, v);
  216. }
  217. else
  218. {
  219. t = u;
  220. eval_add(t, v);
  221. }
  222. }
  223. template <class T, class U>
  224. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && !is_convertible<U, T>::value>::type eval_add_default(T& t, const T& u, const U& v)
  225. {
  226. T vv;
  227. vv = v;
  228. eval_add(t, u, vv);
  229. }
  230. template <class T, class U>
  231. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_convertible<U, T>::value>::type eval_add_default(T& t, const T& u, const U& v)
  232. {
  233. T vv(v);
  234. eval_add(t, u, vv);
  235. }
  236. template <class T, class U>
  237. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value>::type eval_add_default(T& t, const U& u, const T& v)
  238. {
  239. eval_add(t, v, u);
  240. }
  241. template <class T, class U, class V>
  242. inline void eval_add_default(T& t, const U& u, const V& v)
  243. {
  244. if(is_same<T, V>::value && ((void*)&t == (void*)&v))
  245. {
  246. eval_add(t, u);
  247. }
  248. else
  249. {
  250. t = u;
  251. eval_add(t, v);
  252. }
  253. }
  254. template <class T, class U, class V>
  255. inline void eval_add(T& t, const U& u, const V& v)
  256. {
  257. eval_add_default(t, u, v);
  258. }
  259. template <class T, class U, class V>
  260. void eval_subtract(T& t, const U& u, const V& v);
  261. template <class T>
  262. inline void eval_subtract_default(T& t, const T& u, const T& v)
  263. {
  264. if((&t == &v) && is_signed_number<T>::value)
  265. {
  266. eval_subtract(t, u);
  267. t.negate();
  268. }
  269. else if(&t == &u)
  270. {
  271. eval_subtract(t, v);
  272. }
  273. else
  274. {
  275. t = u;
  276. eval_subtract(t, v);
  277. }
  278. }
  279. template <class T, class U>
  280. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && !is_convertible<U, T>::value>::type eval_subtract_default(T& t, const T& u, const U& v)
  281. {
  282. T vv;
  283. vv = v;
  284. eval_subtract(t, u, vv);
  285. }
  286. template <class T, class U>
  287. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_convertible<U, T>::value>::type eval_subtract_default(T& t, const T& u, const U& v)
  288. {
  289. T vv(v);
  290. eval_subtract(t, u, vv);
  291. }
  292. template <class T, class U>
  293. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_signed_number<T>::value>::type eval_subtract_default(T& t, const U& u, const T& v)
  294. {
  295. eval_subtract(t, v, u);
  296. t.negate();
  297. }
  298. template <class T, class U>
  299. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_unsigned_number<T>::value>::type eval_subtract_default(T& t, const U& u, const T& v)
  300. {
  301. T temp(u);
  302. eval_subtract(t, temp, v);
  303. }
  304. template <class T, class U, class V>
  305. inline void eval_subtract_default(T& t, const U& u, const V& v)
  306. {
  307. if(is_same<T, V>::value && ((void*)&t == (void*)&v))
  308. {
  309. eval_subtract(t, u);
  310. t.negate();
  311. }
  312. else
  313. {
  314. t = u;
  315. eval_subtract(t, v);
  316. }
  317. }
  318. template <class T, class U, class V>
  319. inline void eval_subtract(T& t, const U& u, const V& v)
  320. {
  321. eval_subtract_default(t, u, v);
  322. }
  323. template <class T>
  324. inline void eval_multiply_default(T& t, const T& u, const T& v)
  325. {
  326. if(&t == &v)
  327. {
  328. eval_multiply(t, u);
  329. }
  330. else if(&t == &u)
  331. {
  332. eval_multiply(t, v);
  333. }
  334. else
  335. {
  336. t = u;
  337. eval_multiply(t, v);
  338. }
  339. }
  340. template <class T, class U>
  341. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && !is_convertible<U, T>::value>::type eval_multiply_default(T& t, const T& u, const U& v)
  342. {
  343. T vv;
  344. vv = v;
  345. eval_multiply(t, u, vv);
  346. }
  347. template <class T, class U>
  348. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_convertible<U, T>::value>::type eval_multiply_default(T& t, const T& u, const U& v)
  349. {
  350. T vv(v);
  351. eval_multiply(t, u, vv);
  352. }
  353. template <class T, class U>
  354. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value>::type eval_multiply_default(T& t, const U& u, const T& v)
  355. {
  356. eval_multiply(t, v, u);
  357. }
  358. template <class T, class U, class V>
  359. inline void eval_multiply_default(T& t, const U& u, const V& v)
  360. {
  361. if(is_same<T, V>::value && ((void*)&t == (void*)&v))
  362. {
  363. eval_multiply(t, u);
  364. }
  365. else
  366. {
  367. t = u;
  368. eval_multiply(t, v);
  369. }
  370. }
  371. template <class T, class U, class V>
  372. inline void eval_multiply(T& t, const U& u, const V& v)
  373. {
  374. eval_multiply_default(t, u, v);
  375. }
  376. template <class T, class U, class V, class X>
  377. inline typename disable_if_c<!is_same<T, U>::value && is_same<T, V>::value>::type eval_multiply_add(T& t, const U& u, const V& v, const X& x)
  378. {
  379. if((void*)&x == (void*)&t)
  380. {
  381. T z;
  382. z = x;
  383. eval_multiply_add(t, u, v, z);
  384. }
  385. else
  386. {
  387. eval_multiply(t, u, v);
  388. eval_add(t, x);
  389. }
  390. }
  391. template <class T, class U, class V, class X>
  392. inline typename enable_if_c<!is_same<T, U>::value && is_same<T, V>::value>::type eval_multiply_add(T& t, const U& u, const V& v, const X& x)
  393. {
  394. eval_multiply_add(t, v, u, x);
  395. }
  396. template <class T, class U, class V, class X>
  397. inline typename disable_if_c<!is_same<T, U>::value && is_same<T, V>::value>::type eval_multiply_subtract(T& t, const U& u, const V& v, const X& x)
  398. {
  399. if((void*)&x == (void*)&t)
  400. {
  401. T z;
  402. z = x;
  403. eval_multiply_subtract(t, u, v, z);
  404. }
  405. else
  406. {
  407. eval_multiply(t, u, v);
  408. eval_subtract(t, x);
  409. }
  410. }
  411. template <class T, class U, class V, class X>
  412. inline typename enable_if_c<!is_same<T, U>::value && is_same<T, V>::value>::type eval_multiply_subtract(T& t, const U& u, const V& v, const X& x)
  413. {
  414. eval_multiply_subtract(t, v, u, x);
  415. }
  416. template <class T, class U, class V>
  417. void eval_divide(T& t, const U& u, const V& v);
  418. template <class T>
  419. inline void eval_divide_default(T& t, const T& u, const T& v)
  420. {
  421. if(&t == &u)
  422. eval_divide(t, v);
  423. else if(&t == &v)
  424. {
  425. T temp;
  426. eval_divide(temp, u, v);
  427. temp.swap(t);
  428. }
  429. else
  430. {
  431. t = u;
  432. eval_divide(t, v);
  433. }
  434. }
  435. template <class T, class U>
  436. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && !is_convertible<U, T>::value>::type eval_divide_default(T& t, const T& u, const U& v)
  437. {
  438. T vv;
  439. vv = v;
  440. eval_divide(t, u, vv);
  441. }
  442. template <class T, class U>
  443. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_convertible<U, T>::value>::type eval_divide_default(T& t, const T& u, const U& v)
  444. {
  445. T vv(v);
  446. eval_divide(t, u, vv);
  447. }
  448. template <class T, class U>
  449. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && !is_convertible<U, T>::value>::type eval_divide_default(T& t, const U& u, const T& v)
  450. {
  451. T uu;
  452. uu = u;
  453. eval_divide(t, uu, v);
  454. }
  455. template <class T, class U>
  456. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_convertible<U, T>::value>::type eval_divide_default(T& t, const U& u, const T& v)
  457. {
  458. T uu(u);
  459. eval_divide(t, uu, v);
  460. }
  461. template <class T, class U, class V>
  462. inline void eval_divide_default(T& t, const U& u, const V& v)
  463. {
  464. if(is_same<T, V>::value && ((void*)&t == (void*)&v))
  465. {
  466. T temp(u);
  467. eval_divide(temp, v);
  468. t = temp;
  469. }
  470. else
  471. {
  472. t = u;
  473. eval_divide(t, v);
  474. }
  475. }
  476. template <class T, class U, class V>
  477. inline void eval_divide(T& t, const U& u, const V& v)
  478. {
  479. eval_divide_default(t, u, v);
  480. }
  481. template <class T, class U, class V>
  482. void eval_modulus(T& t, const U& u, const V& v);
  483. template <class T>
  484. inline void eval_modulus_default(T& t, const T& u, const T& v)
  485. {
  486. if(&t == &u)
  487. eval_modulus(t, v);
  488. else if(&t == &v)
  489. {
  490. T temp;
  491. eval_modulus(temp, u, v);
  492. temp.swap(t);
  493. }
  494. else
  495. {
  496. t = u;
  497. eval_modulus(t, v);
  498. }
  499. }
  500. template <class T, class U>
  501. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && !is_convertible<U, T>::value>::type eval_modulus_default(T& t, const T& u, const U& v)
  502. {
  503. T vv;
  504. vv = v;
  505. eval_modulus(t, u, vv);
  506. }
  507. template <class T, class U>
  508. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_convertible<U, T>::value>::type eval_modulus_default(T& t, const T& u, const U& v)
  509. {
  510. T vv(v);
  511. eval_modulus(t, u, vv);
  512. }
  513. template <class T, class U>
  514. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && !is_convertible<U, T>::value>::type eval_modulus_default(T& t, const U& u, const T& v)
  515. {
  516. T uu;
  517. uu = u;
  518. eval_modulus(t, uu, v);
  519. }
  520. template <class T, class U>
  521. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_convertible<U, T>::value>::type eval_modulus_default(T& t, const U& u, const T& v)
  522. {
  523. T uu(u);
  524. eval_modulus(t, uu, v);
  525. }
  526. template <class T, class U, class V>
  527. inline void eval_modulus_default(T& t, const U& u, const V& v)
  528. {
  529. if(is_same<T, V>::value && ((void*)&t == (void*)&v))
  530. {
  531. T temp(u);
  532. eval_modulus(temp, v);
  533. t = temp;
  534. }
  535. else
  536. {
  537. t = u;
  538. eval_modulus(t, v);
  539. }
  540. }
  541. template <class T, class U, class V>
  542. inline void eval_modulus(T& t, const U& u, const V& v)
  543. {
  544. eval_modulus_default(t, u, v);
  545. }
  546. template <class T, class U, class V>
  547. void eval_bitwise_and(T& t, const U& u, const V& v);
  548. template <class T>
  549. inline void eval_bitwise_and_default(T& t, const T& u, const T& v)
  550. {
  551. if(&t == &v)
  552. {
  553. eval_bitwise_and(t, u);
  554. }
  555. else if(&t == &u)
  556. {
  557. eval_bitwise_and(t, v);
  558. }
  559. else
  560. {
  561. t = u;
  562. eval_bitwise_and(t, v);
  563. }
  564. }
  565. template <class T, class U>
  566. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && !is_convertible<U, T>::value>::type eval_bitwise_and_default(T& t, const T& u, const U& v)
  567. {
  568. T vv;
  569. vv = v;
  570. eval_bitwise_and(t, u, vv);
  571. }
  572. template <class T, class U>
  573. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_convertible<U, T>::value>::type eval_bitwise_and_default(T& t, const T& u, const U& v)
  574. {
  575. T vv(v);
  576. eval_bitwise_and(t, u, vv);
  577. }
  578. template <class T, class U>
  579. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value>::type eval_bitwise_and_default(T& t, const U& u, const T& v)
  580. {
  581. eval_bitwise_and(t, v, u);
  582. }
  583. template <class T, class U, class V>
  584. inline void eval_bitwise_and_default(T& t, const U& u, const V& v)
  585. {
  586. if(is_same<T, V>::value && ((void*)&t == (void*)&v))
  587. {
  588. eval_bitwise_and(t, u);
  589. }
  590. else
  591. {
  592. t = u;
  593. eval_bitwise_and(t, v);
  594. }
  595. }
  596. template <class T, class U, class V>
  597. inline void eval_bitwise_and(T& t, const U& u, const V& v)
  598. {
  599. eval_bitwise_and_default(t, u, v);
  600. }
  601. template <class T, class U, class V>
  602. void eval_bitwise_or(T& t, const U& u, const V& v);
  603. template <class T>
  604. inline void eval_bitwise_or_default(T& t, const T& u, const T& v)
  605. {
  606. if(&t == &v)
  607. {
  608. eval_bitwise_or(t, u);
  609. }
  610. else if(&t == &u)
  611. {
  612. eval_bitwise_or(t, v);
  613. }
  614. else
  615. {
  616. t = u;
  617. eval_bitwise_or(t, v);
  618. }
  619. }
  620. template <class T, class U>
  621. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && !is_convertible<U, T>::value>::type eval_bitwise_or_default(T& t, const T& u, const U& v)
  622. {
  623. T vv;
  624. vv = v;
  625. eval_bitwise_or(t, u, vv);
  626. }
  627. template <class T, class U>
  628. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_convertible<U, T>::value>::type eval_bitwise_or_default(T& t, const T& u, const U& v)
  629. {
  630. T vv(v);
  631. eval_bitwise_or(t, u, vv);
  632. }
  633. template <class T, class U>
  634. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value>::type eval_bitwise_or_default(T& t, const U& u, const T& v)
  635. {
  636. eval_bitwise_or(t, v, u);
  637. }
  638. template <class T, class U, class V>
  639. inline void eval_bitwise_or_default(T& t, const U& u, const V& v)
  640. {
  641. if(is_same<T, V>::value && ((void*)&t == (void*)&v))
  642. {
  643. eval_bitwise_or(t, u);
  644. }
  645. else
  646. {
  647. t = u;
  648. eval_bitwise_or(t, v);
  649. }
  650. }
  651. template <class T, class U, class V>
  652. inline void eval_bitwise_or(T& t, const U& u, const V& v)
  653. {
  654. eval_bitwise_or_default(t, u, v);
  655. }
  656. template <class T, class U, class V>
  657. void eval_bitwise_xor(T& t, const U& u, const V& v);
  658. template <class T>
  659. inline void eval_bitwise_xor_default(T& t, const T& u, const T& v)
  660. {
  661. if(&t == &v)
  662. {
  663. eval_bitwise_xor(t, u);
  664. }
  665. else if(&t == &u)
  666. {
  667. eval_bitwise_xor(t, v);
  668. }
  669. else
  670. {
  671. t = u;
  672. eval_bitwise_xor(t, v);
  673. }
  674. }
  675. template <class T, class U>
  676. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && !is_convertible<U, T>::value>::type eval_bitwise_xor_default(T& t, const T& u, const U& v)
  677. {
  678. T vv;
  679. vv = v;
  680. eval_bitwise_xor(t, u, vv);
  681. }
  682. template <class T, class U>
  683. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value && is_convertible<U, T>::value>::type eval_bitwise_xor_default(T& t, const T& u, const U& v)
  684. {
  685. T vv(v);
  686. eval_bitwise_xor(t, u, vv);
  687. }
  688. template <class T, class U>
  689. inline typename enable_if_c<is_convertible<U, number<T, et_on> >::value>::type eval_bitwise_xor_default(T& t, const U& u, const T& v)
  690. {
  691. eval_bitwise_xor(t, v, u);
  692. }
  693. template <class T, class U, class V>
  694. inline void eval_bitwise_xor_default(T& t, const U& u, const V& v)
  695. {
  696. if(is_same<T, V>::value && ((void*)&t == (void*)&v))
  697. {
  698. eval_bitwise_xor(t, u);
  699. }
  700. else
  701. {
  702. t = u;
  703. eval_bitwise_xor(t, v);
  704. }
  705. }
  706. template <class T, class U, class V>
  707. inline void eval_bitwise_xor(T& t, const U& u, const V& v)
  708. {
  709. eval_bitwise_xor_default(t, u, v);
  710. }
  711. template <class T>
  712. inline void eval_increment(T& val)
  713. {
  714. typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
  715. eval_add(val, static_cast<ui_type>(1u));
  716. }
  717. template <class T>
  718. inline void eval_decrement(T& val)
  719. {
  720. typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
  721. eval_subtract(val, static_cast<ui_type>(1u));
  722. }
  723. template <class T, class V>
  724. inline void eval_left_shift(T& result, const T& arg, const V val)
  725. {
  726. result = arg;
  727. eval_left_shift(result, val);
  728. }
  729. template <class T, class V>
  730. inline void eval_right_shift(T& result, const T& arg, const V val)
  731. {
  732. result = arg;
  733. eval_right_shift(result, val);
  734. }
  735. template <class T>
  736. inline bool eval_is_zero(const T& val)
  737. {
  738. typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
  739. return val.compare(static_cast<ui_type>(0)) == 0;
  740. }
  741. template <class T>
  742. inline int eval_get_sign(const T& val)
  743. {
  744. typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
  745. return val.compare(static_cast<ui_type>(0));
  746. }
  747. template <class T, class V>
  748. inline void assign_components_imp(T& result, const V& v1, const V& v2, const mpl::int_<number_kind_rational>&)
  749. {
  750. result = v1;
  751. T t;
  752. t = v2;
  753. eval_divide(result, t);
  754. }
  755. template <class T, class V>
  756. inline void assign_components(T& result, const V& v1, const V& v2)
  757. {
  758. return assign_components_imp(result, v1, v2, typename number_category<T>::type());
  759. }
  760. template <class R, int b>
  761. struct has_enough_bits
  762. {
  763. template <class T>
  764. struct type : public mpl::and_<mpl::not_<is_same<R, T> >, mpl::bool_<std::numeric_limits<T>::digits >= b> >{};
  765. };
  766. template <class R>
  767. struct terminal
  768. {
  769. terminal(const R& v) : value(v){}
  770. terminal(){}
  771. terminal& operator = (R val) { value = val; }
  772. R value;
  773. operator R()const { return value; }
  774. };
  775. template<class R, class B>
  776. struct calculate_next_larger_type
  777. {
  778. // Find which list we're looking through:
  779. typedef typename mpl::if_<
  780. is_signed<R>,
  781. typename B::signed_types,
  782. typename mpl::if_<
  783. is_unsigned<R>,
  784. typename B::unsigned_types,
  785. typename B::float_types
  786. >::type
  787. >::type list_type;
  788. // A predicate to find a type with enough bits:
  789. typedef typename has_enough_bits<R, std::numeric_limits<R>::digits>::template type<mpl::_> pred_type;
  790. // See if the last type is in the list, if so we have to start after this:
  791. typedef typename mpl::find_if<
  792. list_type,
  793. is_same<R, mpl::_>
  794. >::type start_last;
  795. // Where we're starting from, either the start of the sequence or the last type found:
  796. typedef typename mpl::if_<is_same<start_last, typename mpl::end<list_type>::type>, typename mpl::begin<list_type>::type, start_last>::type start_seq;
  797. // The range we're searching:
  798. typedef mpl::iterator_range<start_seq, typename mpl::end<list_type>::type> range;
  799. // Find the next type:
  800. typedef typename mpl::find_if<
  801. range,
  802. pred_type
  803. >::type iter_type;
  804. // Either the next type, or a "terminal" to indicate we've run out of types to search:
  805. typedef typename mpl::eval_if<
  806. is_same<typename mpl::end<list_type>::type, iter_type>,
  807. mpl::identity<terminal<R> >,
  808. mpl::deref<iter_type>
  809. >::type type;
  810. };
  811. template <class R, class T>
  812. inline bool check_in_range(const T& t)
  813. {
  814. // Can t fit in an R?
  815. if(std::numeric_limits<R>::is_specialized && std::numeric_limits<R>::is_bounded && (t > (std::numeric_limits<R>::max)()))
  816. return true;
  817. return false;
  818. }
  819. template <class R, class T>
  820. inline bool check_in_range(const terminal<T>&)
  821. {
  822. return false;
  823. }
  824. template <class R, class B>
  825. inline void eval_convert_to(R* result, const B& backend)
  826. {
  827. typedef typename calculate_next_larger_type<R, B>::type next_type;
  828. next_type n;
  829. eval_convert_to(&n, backend);
  830. if(check_in_range<R>(n))
  831. {
  832. *result = (std::numeric_limits<R>::max)();
  833. }
  834. else
  835. *result = static_cast<R>(n);
  836. }
  837. template <class R, class B>
  838. inline void eval_convert_to(terminal<R>* result, const B& backend)
  839. {
  840. //
  841. // We ran out of types to try for the conversion, try
  842. // a lexical_cast and hope for the best:
  843. //
  844. result->value = boost::lexical_cast<R>(backend.str(0, std::ios_base::fmtflags(0)));
  845. }
  846. template <class B>
  847. inline void eval_convert_to(std::string* result, const B& backend)
  848. {
  849. *result = backend.str(0, std::ios_base::fmtflags(0));
  850. }
  851. //
  852. // Functions:
  853. //
  854. template <class T>
  855. void eval_abs(T& result, const T& arg)
  856. {
  857. typedef typename T::signed_types type_list;
  858. typedef typename mpl::front<type_list>::type front;
  859. result = arg;
  860. if(arg.compare(front(0)) < 0)
  861. result.negate();
  862. }
  863. template <class T>
  864. void eval_fabs(T& result, const T& arg)
  865. {
  866. BOOST_STATIC_ASSERT_MSG(number_category<T>::value == number_kind_floating_point, "The fabs function is only valid for floating point types.");
  867. typedef typename T::signed_types type_list;
  868. typedef typename mpl::front<type_list>::type front;
  869. result = arg;
  870. if(arg.compare(front(0)) < 0)
  871. result.negate();
  872. }
  873. template <class Backend>
  874. inline int eval_fpclassify(const Backend& arg)
  875. {
  876. BOOST_STATIC_ASSERT_MSG(number_category<Backend>::value == number_kind_floating_point, "The fpclassify function is only valid for floating point types.");
  877. return eval_is_zero(arg) ? FP_ZERO : FP_NORMAL;
  878. }
  879. template <class T>
  880. inline void eval_fmod(T& result, const T& a, const T& b)
  881. {
  882. BOOST_STATIC_ASSERT_MSG(number_category<T>::value == number_kind_floating_point, "The fmod function is only valid for floating point types.");
  883. if((&result == &a) || (&result == &b))
  884. {
  885. T temp;
  886. eval_fmod(temp, a, b);
  887. result = temp;
  888. return;
  889. }
  890. T n;
  891. eval_divide(result, a, b);
  892. if(eval_get_sign(a) < 0)
  893. eval_ceil(n, result);
  894. else
  895. eval_floor(n, result);
  896. eval_multiply(n, b);
  897. eval_subtract(result, a, n);
  898. }
  899. template<class T, class A>
  900. inline typename enable_if<is_arithmetic<A>, void>::type eval_fmod(T& result, const T& x, const A& a)
  901. {
  902. typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
  903. typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
  904. cast_type c;
  905. c = a;
  906. eval_fmod(result, x, c);
  907. }
  908. template<class T, class A>
  909. inline typename enable_if<is_arithmetic<A>, void>::type eval_fmod(T& result, const A& x, const T& a)
  910. {
  911. typedef typename boost::multiprecision::detail::canonical<A, T>::type canonical_type;
  912. typedef typename mpl::if_<is_same<A, canonical_type>, T, canonical_type>::type cast_type;
  913. cast_type c;
  914. c = x;
  915. eval_fmod(result, c, a);
  916. }
  917. template <class T>
  918. inline void eval_trunc(T& result, const T& a)
  919. {
  920. BOOST_STATIC_ASSERT_MSG(number_category<T>::value == number_kind_floating_point, "The trunc function is only valid for floating point types.");
  921. int c = eval_fpclassify(a);
  922. if(c == FP_NAN || c == FP_INFINITE)
  923. {
  924. result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, number<T>(a), number<T>(a), boost::math::policies::policy<>()).backend();
  925. return;
  926. }
  927. if(eval_get_sign(a) < 0)
  928. eval_ceil(result, a);
  929. else
  930. eval_floor(result, a);
  931. }
  932. template <class T>
  933. inline void eval_round(T& result, const T& a)
  934. {
  935. BOOST_STATIC_ASSERT_MSG(number_category<T>::value == number_kind_floating_point, "The round function is only valid for floating point types.");
  936. typedef typename boost::multiprecision::detail::canonical<float, T>::type fp_type;
  937. int c = eval_fpclassify(a);
  938. if(c == FP_NAN || c == FP_INFINITE)
  939. {
  940. result = boost::math::policies::raise_rounding_error("boost::multiprecision::round<%1%>(%1%)", 0, number<T>(a), number<T>(a), boost::math::policies::policy<>()).backend();
  941. return;
  942. }
  943. if(eval_get_sign(a) < 0)
  944. {
  945. eval_subtract(result, a, fp_type(0.5f));
  946. eval_ceil(result, result);
  947. }
  948. else
  949. {
  950. eval_add(result, a, fp_type(0.5f));
  951. eval_floor(result, result);
  952. }
  953. }
  954. template <class B>
  955. void eval_lcm(B& result, const B& a, const B& b);
  956. template <class B>
  957. void eval_gcd(B& result, const B& a, const B& b);
  958. template <class T, class Arithmetic>
  959. inline typename enable_if<is_integral<Arithmetic> >::type eval_gcd(T& result, const T& a, const Arithmetic& b)
  960. {
  961. typedef typename boost::multiprecision::detail::canonical<Arithmetic, T>::type si_type;
  962. using default_ops::eval_gcd;
  963. T t;
  964. t = static_cast<si_type>(b);
  965. eval_gcd(result, a, t);
  966. }
  967. template <class T, class Arithmetic>
  968. inline typename enable_if<is_integral<Arithmetic> >::type eval_gcd(T& result, const Arithmetic& a, const T& b)
  969. {
  970. eval_gcd(result, b, a);
  971. }
  972. template <class T, class Arithmetic>
  973. inline typename enable_if<is_integral<Arithmetic> >::type eval_lcm(T& result, const T& a, const Arithmetic& b)
  974. {
  975. typedef typename boost::multiprecision::detail::canonical<Arithmetic, T>::type si_type;
  976. using default_ops::eval_lcm;
  977. T t;
  978. t = static_cast<si_type>(b);
  979. eval_lcm(result, a, t);
  980. }
  981. template <class T, class Arithmetic>
  982. inline typename enable_if<is_integral<Arithmetic> >::type eval_lcm(T& result, const Arithmetic& a, const T& b)
  983. {
  984. eval_lcm(result, b, a);
  985. }
  986. template <class T>
  987. inline unsigned eval_lsb(const T& val)
  988. {
  989. typedef typename boost::multiprecision::detail::canonical<unsigned, T>::type ui_type;
  990. int c = eval_get_sign(val);
  991. if(c == 0)
  992. {
  993. BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand."));
  994. }
  995. if(c < 0)
  996. {
  997. BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined."));
  998. }
  999. unsigned result = 0;
  1000. T mask, t;
  1001. mask = ui_type(1);
  1002. do
  1003. {
  1004. eval_bitwise_and(t, mask, val);
  1005. ++result;
  1006. eval_left_shift(mask, 1);
  1007. }
  1008. while(eval_is_zero(t));
  1009. return --result;
  1010. }
  1011. template <class T>
  1012. inline int eval_msb(const T& val)
  1013. {
  1014. int c = eval_get_sign(val);
  1015. if(c == 0)
  1016. {
  1017. BOOST_THROW_EXCEPTION(std::range_error("No bits were set in the operand."));
  1018. }
  1019. if(c < 0)
  1020. {
  1021. BOOST_THROW_EXCEPTION(std::range_error("Testing individual bits in negative values is not supported - results are undefined."));
  1022. }
  1023. //
  1024. // This implementation is really really rubbish - it does
  1025. // a linear scan for the most-significant-bit. We should really
  1026. // do a binary search, but as none of our backends actually needs
  1027. // this implementation, we'll leave it for now. In fact for most
  1028. // backends it's likely that there will always be a more efficient
  1029. // native implementation possible.
  1030. //
  1031. unsigned result = 0;
  1032. T t(val);
  1033. while(!eval_is_zero(t))
  1034. {
  1035. eval_right_shift(t, 1);
  1036. ++result;
  1037. }
  1038. return --result;
  1039. }
  1040. template <class T>
  1041. inline bool eval_bit_test(const T& val, unsigned index)
  1042. {
  1043. typedef typename boost::multiprecision::detail::canonical<unsigned, T>::type ui_type;
  1044. T mask, t;
  1045. mask = ui_type(1);
  1046. eval_left_shift(mask, index);
  1047. eval_bitwise_and(t, mask, val);
  1048. return !eval_is_zero(t);
  1049. }
  1050. template <class T>
  1051. inline void eval_bit_set(T& val, unsigned index)
  1052. {
  1053. typedef typename boost::multiprecision::detail::canonical<unsigned, T>::type ui_type;
  1054. T mask;
  1055. mask = ui_type(1);
  1056. eval_left_shift(mask, index);
  1057. eval_bitwise_or(val, mask);
  1058. }
  1059. template <class T>
  1060. inline void eval_bit_flip(T& val, unsigned index)
  1061. {
  1062. typedef typename boost::multiprecision::detail::canonical<unsigned, T>::type ui_type;
  1063. T mask;
  1064. mask = ui_type(1);
  1065. eval_left_shift(mask, index);
  1066. eval_bitwise_xor(val, mask);
  1067. }
  1068. template <class T>
  1069. inline void eval_bit_unset(T& val, unsigned index)
  1070. {
  1071. typedef typename boost::multiprecision::detail::canonical<unsigned, T>::type ui_type;
  1072. T mask, t;
  1073. mask = ui_type(1);
  1074. eval_left_shift(mask, index);
  1075. eval_bitwise_and(t, mask, val);
  1076. if(!eval_is_zero(t))
  1077. eval_bitwise_xor(val, mask);
  1078. }
  1079. template <class B>
  1080. void eval_integer_sqrt(B& s, B& r, const B& x)
  1081. {
  1082. //
  1083. // This is slow bit-by-bit integer square root, see for example
  1084. // http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_.28base_2.29
  1085. // There are better methods such as http://hal.inria.fr/docs/00/07/28/54/PDF/RR-3805.pdf
  1086. // and http://hal.inria.fr/docs/00/07/21/13/PDF/RR-4475.pdf which should be implemented
  1087. // at some point.
  1088. //
  1089. typedef typename boost::multiprecision::detail::canonical<unsigned char, B>::type ui_type;
  1090. s = ui_type(0u);
  1091. if(eval_get_sign(x) == 0)
  1092. {
  1093. r = ui_type(0u);
  1094. return;
  1095. }
  1096. int g = eval_msb(x);
  1097. if(g == 0)
  1098. {
  1099. r = ui_type(1);
  1100. return;
  1101. }
  1102. B t;
  1103. r = x;
  1104. g /= 2;
  1105. int org_g = g;
  1106. eval_bit_set(s, g);
  1107. eval_bit_set(t, 2 * g);
  1108. eval_subtract(r, x, t);
  1109. --g;
  1110. if(eval_get_sign(r) == 0)
  1111. return;
  1112. int msbr = eval_msb(r);
  1113. do
  1114. {
  1115. if(msbr >= org_g + g + 1)
  1116. {
  1117. t = s;
  1118. eval_left_shift(t, g + 1);
  1119. eval_bit_set(t, 2 * g);
  1120. if(t.compare(r) <= 0)
  1121. {
  1122. eval_bit_set(s, g);
  1123. eval_subtract(r, t);
  1124. if(eval_get_sign(r) == 0)
  1125. return;
  1126. msbr = eval_msb(r);
  1127. }
  1128. }
  1129. --g;
  1130. }
  1131. while(g >= 0);
  1132. }
  1133. //
  1134. // These have to implemented by the backend, declared here so that our macro generated code compiles OK.
  1135. //
  1136. template <class T>
  1137. typename enable_if_c<sizeof(T) == 0>::type eval_floor();
  1138. template <class T>
  1139. typename enable_if_c<sizeof(T) == 0>::type eval_ceil();
  1140. template <class T>
  1141. typename enable_if_c<sizeof(T) == 0>::type eval_trunc();
  1142. template <class T>
  1143. typename enable_if_c<sizeof(T) == 0>::type eval_sqrt();
  1144. template <class T>
  1145. typename enable_if_c<sizeof(T) == 0>::type eval_ldexp();
  1146. template <class T>
  1147. typename enable_if_c<sizeof(T) == 0>::type eval_frexp();
  1148. //
  1149. // These functions are implemented in separate files, but expanded inline here,
  1150. // DO NOT CHANGE THE ORDER OF THESE INCLUDES:
  1151. //
  1152. #include <boost/multiprecision/detail/functions/constants.hpp>
  1153. #include <boost/multiprecision/detail/functions/pow.hpp>
  1154. #include <boost/multiprecision/detail/functions/trig.hpp>
  1155. }
  1156. } // namespace multiprecision
  1157. namespace math{
  1158. //
  1159. // Default versions of floating point classification routines:
  1160. //
  1161. template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
  1162. inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg)
  1163. {
  1164. using multiprecision::default_ops::eval_fpclassify;
  1165. return eval_fpclassify(arg.backend());
  1166. }
  1167. template <class tag, class A1, class A2, class A3, class A4>
  1168. inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg)
  1169. {
  1170. typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type;
  1171. return (fpclassify)(value_type(arg));
  1172. }
  1173. template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
  1174. inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg)
  1175. {
  1176. int v = (fpclassify)(arg);
  1177. return (v != FP_INFINITE) && (v != FP_NAN);
  1178. }
  1179. template <class tag, class A1, class A2, class A3, class A4>
  1180. inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg)
  1181. {
  1182. typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type;
  1183. return (isfinite)(value_type(arg));
  1184. }
  1185. template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
  1186. inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg)
  1187. {
  1188. return (fpclassify)(arg) == FP_NAN;
  1189. }
  1190. template <class tag, class A1, class A2, class A3, class A4>
  1191. inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg)
  1192. {
  1193. typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type;
  1194. return (isnan)(value_type(arg));
  1195. }
  1196. template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
  1197. inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg)
  1198. {
  1199. return (fpclassify)(arg) == FP_INFINITE;
  1200. }
  1201. template <class tag, class A1, class A2, class A3, class A4>
  1202. inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg)
  1203. {
  1204. typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type;
  1205. return (isinf)(value_type(arg));
  1206. }
  1207. template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
  1208. inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::number<Backend, ExpressionTemplates>& arg)
  1209. {
  1210. return (fpclassify)(arg) == FP_NORMAL;
  1211. }
  1212. template <class tag, class A1, class A2, class A3, class A4>
  1213. inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const multiprecision::detail::expression<tag, A1, A2, A3, A4>& arg)
  1214. {
  1215. typedef typename multiprecision::detail::expression<tag, A1, A2, A3, A4>::result_type value_type;
  1216. return (isnormal)(value_type(arg));
  1217. }
  1218. } // namespace math
  1219. namespace multiprecision{
  1220. template <class B1, class B2, class B3, expression_template_option ET1, expression_template_option ET2, expression_template_option ET3>
  1221. inline number<B1, ET1>& add(number<B1, ET1>& result, const number<B2, ET2>& a, const number<B3, ET3>& b)
  1222. {
  1223. BOOST_STATIC_ASSERT_MSG((is_convertible<B2, B1>::value), "No conversion to the target of a mixed precision addition exists");
  1224. BOOST_STATIC_ASSERT_MSG((is_convertible<B3, B1>::value), "No conversion to the target of a mixed precision addition exists");
  1225. using default_ops::eval_add;
  1226. eval_add(result.backend(), a.backend(), b.backend());
  1227. return result;
  1228. }
  1229. template <class B1, class B2, class B3, expression_template_option ET1, expression_template_option ET2, expression_template_option ET3>
  1230. inline number<B1, ET1>& subtract(number<B1, ET1>& result, const number<B2, ET2>& a, const number<B3, ET3>& b)
  1231. {
  1232. BOOST_STATIC_ASSERT_MSG((is_convertible<B2, B1>::value), "No conversion to the target of a mixed precision addition exists");
  1233. BOOST_STATIC_ASSERT_MSG((is_convertible<B3, B1>::value), "No conversion to the target of a mixed precision addition exists");
  1234. using default_ops::eval_subtract;
  1235. eval_subtract(result.backend(), a.backend(), b.backend());
  1236. return result;
  1237. }
  1238. template <class B1, class B2, class B3, expression_template_option ET1, expression_template_option ET2, expression_template_option ET3>
  1239. inline number<B1, ET1>& multiply(number<B1, ET1>& result, const number<B2, ET2>& a, const number<B3, ET3>& b)
  1240. {
  1241. BOOST_STATIC_ASSERT_MSG((is_convertible<B2, B1>::value), "No conversion to the target of a mixed precision addition exists");
  1242. BOOST_STATIC_ASSERT_MSG((is_convertible<B3, B1>::value), "No conversion to the target of a mixed precision addition exists");
  1243. using default_ops::eval_multiply;
  1244. eval_multiply(result.backend(), a.backend(), b.backend());
  1245. return result;
  1246. }
  1247. template <class B, expression_template_option ET, class I>
  1248. inline typename enable_if_c<is_integral<I>::value, number<B, ET>&>::type
  1249. add(number<B, ET>& result, const I& a, const I& b)
  1250. {
  1251. using default_ops::eval_add;
  1252. typedef typename detail::canonical<I, B>::type canonical_type;
  1253. eval_add(result.backend(), static_cast<canonical_type>(a), static_cast<canonical_type>(b));
  1254. return result;
  1255. }
  1256. template <class B, expression_template_option ET, class I>
  1257. inline typename enable_if_c<is_integral<I>::value, number<B, ET>&>::type
  1258. subtract(number<B, ET>& result, const I& a, const I& b)
  1259. {
  1260. using default_ops::eval_subtract;
  1261. typedef typename detail::canonical<I, B>::type canonical_type;
  1262. eval_subtract(result.backend(), static_cast<canonical_type>(a), static_cast<canonical_type>(b));
  1263. return result;
  1264. }
  1265. template <class B, expression_template_option ET, class I>
  1266. inline typename enable_if_c<is_integral<I>::value, number<B, ET>&>::type
  1267. multiply(number<B, ET>& result, const I& a, const I& b)
  1268. {
  1269. using default_ops::eval_multiply;
  1270. typedef typename detail::canonical<I, B>::type canonical_type;
  1271. eval_multiply(result.backend(), static_cast<canonical_type>(a), static_cast<canonical_type>(b));
  1272. return result;
  1273. }
  1274. template <class tag, class A1, class A2, class A3, class A4, class Policy>
  1275. inline typename detail::expression<tag, A1, A2, A3, A4>::result_type trunc(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
  1276. {
  1277. typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
  1278. return BOOST_MP_MOVE(trunc(number_type(v), pol));
  1279. }
  1280. template <class Backend, expression_template_option ExpressionTemplates, class Policy>
  1281. inline number<Backend, ExpressionTemplates> trunc(const number<Backend, ExpressionTemplates>& v, const Policy&)
  1282. {
  1283. using default_ops::eval_trunc;
  1284. number<Backend, ExpressionTemplates> result;
  1285. eval_trunc(result.backend(), v.backend());
  1286. return BOOST_MP_MOVE(result);
  1287. }
  1288. template <class tag, class A1, class A2, class A3, class A4, class Policy>
  1289. inline int itrunc(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
  1290. {
  1291. typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
  1292. number_type r = trunc(v, pol);
  1293. if((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !(boost::math::isfinite)(v))
  1294. return boost::math::policies::raise_rounding_error("boost::multiprecision::itrunc<%1%>(%1%)", 0, number_type(v), 0, pol);
  1295. return r.template convert_to<int>();
  1296. }
  1297. template <class tag, class A1, class A2, class A3, class A4>
  1298. inline int itrunc(const detail::expression<tag, A1, A2, A3, A4>& v)
  1299. {
  1300. return itrunc(v, boost::math::policies::policy<>());
  1301. }
  1302. template <class Backend, expression_template_option ExpressionTemplates, class Policy>
  1303. inline int itrunc(const number<Backend, ExpressionTemplates>& v, const Policy& pol)
  1304. {
  1305. number<Backend, ExpressionTemplates> r = trunc(v, pol);
  1306. if((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !(boost::math::isfinite)(v))
  1307. return boost::math::policies::raise_rounding_error("boost::multiprecision::itrunc<%1%>(%1%)", 0, v, 0, pol);
  1308. return r.template convert_to<int>();
  1309. }
  1310. template <class Backend, expression_template_option ExpressionTemplates>
  1311. inline int itrunc(const number<Backend, ExpressionTemplates>& v)
  1312. {
  1313. return itrunc(v, boost::math::policies::policy<>());
  1314. }
  1315. template <class tag, class A1, class A2, class A3, class A4, class Policy>
  1316. inline long ltrunc(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
  1317. {
  1318. typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
  1319. number_type r = trunc(v, pol);
  1320. if((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !(boost::math::isfinite)(v))
  1321. return boost::math::policies::raise_rounding_error("boost::multiprecision::ltrunc<%1%>(%1%)", 0, number_type(v), 0L, pol);
  1322. return r.template convert_to<long>();
  1323. }
  1324. template <class tag, class A1, class A2, class A3, class A4>
  1325. inline long ltrunc(const detail::expression<tag, A1, A2, A3, A4>& v)
  1326. {
  1327. return ltrunc(v, boost::math::policies::policy<>());
  1328. }
  1329. template <class T, expression_template_option ExpressionTemplates, class Policy>
  1330. inline long ltrunc(const number<T, ExpressionTemplates>& v, const Policy& pol)
  1331. {
  1332. number<T, ExpressionTemplates> r = trunc(v, pol);
  1333. if((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !(boost::math::isfinite)(v))
  1334. return boost::math::policies::raise_rounding_error("boost::multiprecision::ltrunc<%1%>(%1%)", 0, v, 0L, pol);
  1335. return r.template convert_to<long>();
  1336. }
  1337. template <class T, expression_template_option ExpressionTemplates>
  1338. inline long ltrunc(const number<T, ExpressionTemplates>& v)
  1339. {
  1340. return ltrunc(v, boost::math::policies::policy<>());
  1341. }
  1342. #ifndef BOOST_NO_LONG_LONG
  1343. template <class tag, class A1, class A2, class A3, class A4, class Policy>
  1344. inline long long lltrunc(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
  1345. {
  1346. typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
  1347. number_type r = trunc(v, pol);
  1348. if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !(boost::math::isfinite)(v))
  1349. return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, number_type(v), 0LL, pol);
  1350. return r.template convert_to<long long>();
  1351. }
  1352. template <class tag, class A1, class A2, class A3, class A4>
  1353. inline long long lltrunc(const detail::expression<tag, A1, A2, A3, A4>& v)
  1354. {
  1355. return lltrunc(v, boost::math::policies::policy<>());
  1356. }
  1357. template <class T, expression_template_option ExpressionTemplates, class Policy>
  1358. inline long long lltrunc(const number<T, ExpressionTemplates>& v, const Policy& pol)
  1359. {
  1360. number<T, ExpressionTemplates> r = trunc(v, pol);
  1361. if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !(boost::math::isfinite)(v))
  1362. return boost::math::policies::raise_rounding_error("boost::multiprecision::lltrunc<%1%>(%1%)", 0, v, 0LL, pol);
  1363. return r.template convert_to<long long>();
  1364. }
  1365. template <class T, expression_template_option ExpressionTemplates>
  1366. inline long long lltrunc(const number<T, ExpressionTemplates>& v)
  1367. {
  1368. return lltrunc(v, boost::math::policies::policy<>());
  1369. }
  1370. #endif
  1371. template <class tag, class A1, class A2, class A3, class A4, class Policy>
  1372. inline typename detail::expression<tag, A1, A2, A3, A4>::result_type round(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
  1373. {
  1374. typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
  1375. return BOOST_MP_MOVE(round(static_cast<number_type>(v), pol));
  1376. }
  1377. template <class T, expression_template_option ExpressionTemplates, class Policy>
  1378. inline number<T, ExpressionTemplates> round(const number<T, ExpressionTemplates>& v, const Policy&)
  1379. {
  1380. using default_ops::eval_round;
  1381. number<T, ExpressionTemplates> result;
  1382. eval_round(result.backend(), v.backend());
  1383. return BOOST_MP_MOVE(result);
  1384. }
  1385. template <class tag, class A1, class A2, class A3, class A4, class Policy>
  1386. inline int iround(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
  1387. {
  1388. typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
  1389. number_type r = round(v, pol);
  1390. if((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !(boost::math::isfinite)(v))
  1391. return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, number_type(v), 0, pol);
  1392. return r.template convert_to<int>();
  1393. }
  1394. template <class tag, class A1, class A2, class A3, class A4>
  1395. inline int iround(const detail::expression<tag, A1, A2, A3, A4>& v)
  1396. {
  1397. return iround(v, boost::math::policies::policy<>());
  1398. }
  1399. template <class T, expression_template_option ExpressionTemplates, class Policy>
  1400. inline int iround(const number<T, ExpressionTemplates>& v, const Policy& pol)
  1401. {
  1402. number<T, ExpressionTemplates> r = round(v, pol);
  1403. if((r > (std::numeric_limits<int>::max)()) || r < (std::numeric_limits<int>::min)() || !(boost::math::isfinite)(v))
  1404. return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, v, 0, pol);
  1405. return r.template convert_to<int>();
  1406. }
  1407. template <class T, expression_template_option ExpressionTemplates>
  1408. inline int iround(const number<T, ExpressionTemplates>& v)
  1409. {
  1410. return iround(v, boost::math::policies::policy<>());
  1411. }
  1412. template <class tag, class A1, class A2, class A3, class A4, class Policy>
  1413. inline long lround(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
  1414. {
  1415. typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
  1416. number_type r = round(v, pol);
  1417. if((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !(boost::math::isfinite)(v))
  1418. return boost::math::policies::raise_rounding_error("boost::multiprecision::lround<%1%>(%1%)", 0, number_type(v), 0L, pol);
  1419. return r.template convert_to<long>();
  1420. }
  1421. template <class tag, class A1, class A2, class A3, class A4>
  1422. inline long lround(const detail::expression<tag, A1, A2, A3, A4>& v)
  1423. {
  1424. return lround(v, boost::math::policies::policy<>());
  1425. }
  1426. template <class T, expression_template_option ExpressionTemplates, class Policy>
  1427. inline long lround(const number<T, ExpressionTemplates>& v, const Policy& pol)
  1428. {
  1429. number<T, ExpressionTemplates> r = round(v, pol);
  1430. if((r > (std::numeric_limits<long>::max)()) || r < (std::numeric_limits<long>::min)() || !(boost::math::isfinite)(v))
  1431. return boost::math::policies::raise_rounding_error("boost::multiprecision::lround<%1%>(%1%)", 0, v, 0L, pol);
  1432. return r.template convert_to<long>();
  1433. }
  1434. template <class T, expression_template_option ExpressionTemplates>
  1435. inline long lround(const number<T, ExpressionTemplates>& v)
  1436. {
  1437. return lround(v, boost::math::policies::policy<>());
  1438. }
  1439. #ifndef BOOST_NO_LONG_LONG
  1440. template <class tag, class A1, class A2, class A3, class A4, class Policy>
  1441. inline long long llround(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
  1442. {
  1443. typedef typename detail::expression<tag, A1, A2, A3, A4>::result_type number_type;
  1444. number_type r = round(v, pol);
  1445. if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !(boost::math::isfinite)(v))
  1446. return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, number_type(v), 0LL, pol);
  1447. return r.template convert_to<long long>();
  1448. }
  1449. template <class tag, class A1, class A2, class A3, class A4>
  1450. inline long long llround(const detail::expression<tag, A1, A2, A3, A4>& v)
  1451. {
  1452. return llround(v, boost::math::policies::policy<>());
  1453. }
  1454. template <class T, expression_template_option ExpressionTemplates, class Policy>
  1455. inline long long llround(const number<T, ExpressionTemplates>& v, const Policy& pol)
  1456. {
  1457. number<T, ExpressionTemplates> r = round(v, pol);
  1458. if((r > (std::numeric_limits<long long>::max)()) || r < (std::numeric_limits<long long>::min)() || !(boost::math::isfinite)(v))
  1459. return boost::math::policies::raise_rounding_error("boost::multiprecision::iround<%1%>(%1%)", 0, v, 0LL, pol);
  1460. return r.template convert_to<long long>();
  1461. }
  1462. template <class T, expression_template_option ExpressionTemplates>
  1463. inline long long llround(const number<T, ExpressionTemplates>& v)
  1464. {
  1465. return llround(v, boost::math::policies::policy<>());
  1466. }
  1467. #endif
  1468. template <class B, expression_template_option ExpressionTemplates>
  1469. inline typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, ExpressionTemplates> >::type
  1470. sqrt(const number<B, ExpressionTemplates>& x)
  1471. {
  1472. using default_ops::eval_integer_sqrt;
  1473. number<B, ExpressionTemplates> s, r;
  1474. eval_integer_sqrt(s.backend(), r.backend(), x.backend());
  1475. return s;
  1476. }
  1477. template <class B, expression_template_option ExpressionTemplates>
  1478. inline typename enable_if_c<number_category<B>::value == number_kind_integer, number<B, ExpressionTemplates> >::type
  1479. sqrt(const number<B, ExpressionTemplates>& x, number<B, ExpressionTemplates>& r)
  1480. {
  1481. using default_ops::eval_integer_sqrt;
  1482. number<B, ExpressionTemplates> s;
  1483. eval_integer_sqrt(s.backend(), r.backend(), x.backend());
  1484. return s;
  1485. }
  1486. #define UNARY_OP_FUNCTOR(func, category)\
  1487. namespace detail{\
  1488. template <class Backend> \
  1489. struct BOOST_JOIN(func, _funct)\
  1490. {\
  1491. void operator()(Backend& result, const Backend& arg)const\
  1492. {\
  1493. using default_ops::BOOST_JOIN(eval_,func);\
  1494. BOOST_JOIN(eval_,func)(result, arg);\
  1495. }\
  1496. };\
  1497. \
  1498. }\
  1499. \
  1500. template <class tag, class A1, class A2, class A3, class A4> \
  1501. inline typename enable_if_c<number_category<detail::expression<tag, A1, A2, A3, A4> >::value == category,\
  1502. detail::expression<\
  1503. detail::function\
  1504. , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type> \
  1505. , detail::expression<tag, A1, A2, A3, A4> > \
  1506. >::type \
  1507. func(const detail::expression<tag, A1, A2, A3, A4>& arg)\
  1508. {\
  1509. return detail::expression<\
  1510. detail::function\
  1511. , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type> \
  1512. , detail::expression<tag, A1, A2, A3, A4> \
  1513. > (\
  1514. detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>() \
  1515. , arg \
  1516. );\
  1517. }\
  1518. template <class Backend> \
  1519. inline typename enable_if_c<number_category<Backend>::value == category,\
  1520. detail::expression<\
  1521. detail::function\
  1522. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1523. , number<Backend, et_on> > \
  1524. >::type \
  1525. func(const number<Backend, et_on>& arg)\
  1526. {\
  1527. return detail::expression<\
  1528. detail::function\
  1529. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1530. , number<Backend, et_on> \
  1531. >(\
  1532. detail::BOOST_JOIN(func, _funct)<Backend>() \
  1533. , arg \
  1534. );\
  1535. }\
  1536. template <class Backend> \
  1537. inline typename boost::enable_if_c<\
  1538. boost::multiprecision::number_category<Backend>::value == category,\
  1539. number<Backend, et_off> >::type \
  1540. func(const number<Backend, et_off>& arg)\
  1541. {\
  1542. number<Backend, et_off> result;\
  1543. using default_ops::BOOST_JOIN(eval_,func);\
  1544. BOOST_JOIN(eval_,func)(result.backend(), arg.backend());\
  1545. return BOOST_MP_MOVE(result);\
  1546. }
  1547. #define BINARY_OP_FUNCTOR(func, category)\
  1548. namespace detail{\
  1549. template <class Backend> \
  1550. struct BOOST_JOIN(func, _funct)\
  1551. {\
  1552. void operator()(Backend& result, const Backend& arg, const Backend& a)const\
  1553. {\
  1554. using default_ops:: BOOST_JOIN(eval_,func);\
  1555. BOOST_JOIN(eval_,func)(result, arg, a);\
  1556. }\
  1557. template <class Arithmetic> \
  1558. void operator()(Backend& result, const Backend& arg, const Arithmetic& a)const\
  1559. {\
  1560. using default_ops:: BOOST_JOIN(eval_,func);\
  1561. BOOST_JOIN(eval_,func)(result, arg, a);\
  1562. }\
  1563. template <class Arithmetic> \
  1564. void operator()(Backend& result, const Arithmetic& arg, const Backend& a)const\
  1565. {\
  1566. using default_ops:: BOOST_JOIN(eval_,func);\
  1567. BOOST_JOIN(eval_,func)(result, arg, a);\
  1568. }\
  1569. };\
  1570. \
  1571. }\
  1572. template <class Backend> \
  1573. inline typename enable_if_c<number_category<Backend>::value == category,\
  1574. detail::expression<\
  1575. detail::function\
  1576. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1577. , number<Backend, et_on> \
  1578. , number<Backend, et_on> > \
  1579. >::type \
  1580. func(const number<Backend, et_on>& arg, const number<Backend, et_on>& a)\
  1581. {\
  1582. return detail::expression<\
  1583. detail::function\
  1584. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1585. , number<Backend, et_on> \
  1586. , number<Backend, et_on> \
  1587. >(\
  1588. detail::BOOST_JOIN(func, _funct)<Backend>() \
  1589. , arg,\
  1590. a\
  1591. );\
  1592. }\
  1593. template <class Backend, class tag, class A1, class A2, class A3, class A4> \
  1594. inline typename enable_if_c<\
  1595. (number_category<Backend>::value == category) && (number_category<detail::expression<tag, A1, A2, A3, A4> >::value == category),\
  1596. detail::expression<\
  1597. detail::function\
  1598. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1599. , number<Backend, et_on> \
  1600. , detail::expression<tag, A1, A2, A3, A4> > \
  1601. >::type \
  1602. func(const number<Backend, et_on>& arg, const detail::expression<tag, A1, A2, A3, A4>& a)\
  1603. {\
  1604. return detail::expression<\
  1605. detail::function\
  1606. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1607. , number<Backend, et_on> \
  1608. , detail::expression<tag, A1, A2, A3, A4> \
  1609. >(\
  1610. detail::BOOST_JOIN(func, _funct)<Backend>() \
  1611. , arg,\
  1612. a\
  1613. );\
  1614. }\
  1615. template <class tag, class A1, class A2, class A3, class A4, class Backend> \
  1616. inline typename enable_if_c<\
  1617. (number_category<Backend>::value == category) && (number_category<detail::expression<tag, A1, A2, A3, A4> >::value == category),\
  1618. detail::expression<\
  1619. detail::function\
  1620. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1621. , detail::expression<tag, A1, A2, A3, A4> \
  1622. , number<Backend, et_on> > \
  1623. >::type \
  1624. func(const detail::expression<tag, A1, A2, A3, A4>& arg, const number<Backend, et_on>& a)\
  1625. {\
  1626. return detail::expression<\
  1627. detail::function\
  1628. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1629. , detail::expression<tag, A1, A2, A3, A4> \
  1630. , number<Backend, et_on> \
  1631. >(\
  1632. detail::BOOST_JOIN(func, _funct)<Backend>() \
  1633. , arg,\
  1634. a\
  1635. );\
  1636. }\
  1637. template <class tag, class A1, class A2, class A3, class A4, class tagb, class A1b, class A2b, class A3b, class A4b> \
  1638. inline typename enable_if_c<\
  1639. (number_category<detail::expression<tag, A1, A2, A3, A4> >::value == category) && (number_category<detail::expression<tagb, A1b, A2b, A3b, A4b> >::value == category),\
  1640. detail::expression<\
  1641. detail::function\
  1642. , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type> \
  1643. , detail::expression<tag, A1, A2, A3, A4> \
  1644. , detail::expression<tagb, A1b, A2b, A3b, A4b> > \
  1645. >::type \
  1646. func(const detail::expression<tag, A1, A2, A3, A4>& arg, const detail::expression<tagb, A1b, A2b, A3b, A4b>& a)\
  1647. {\
  1648. return detail::expression<\
  1649. detail::function\
  1650. , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type> \
  1651. , detail::expression<tag, A1, A2, A3, A4> \
  1652. , detail::expression<tagb, A1b, A2b, A3b, A4b> \
  1653. >(\
  1654. detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>() \
  1655. , arg,\
  1656. a\
  1657. );\
  1658. }\
  1659. template <class Backend, class Arithmetic> \
  1660. inline typename enable_if_c<\
  1661. is_arithmetic<Arithmetic>::value && (number_category<Backend>::value == category),\
  1662. detail::expression<\
  1663. detail::function\
  1664. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1665. , number<Backend, et_on> \
  1666. , Arithmetic\
  1667. > \
  1668. >::type \
  1669. func(const number<Backend, et_on>& arg, const Arithmetic& a)\
  1670. {\
  1671. return detail::expression<\
  1672. detail::function\
  1673. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1674. , number<Backend, et_on> \
  1675. , Arithmetic\
  1676. >(\
  1677. detail::BOOST_JOIN(func, _funct)<Backend>() \
  1678. , arg,\
  1679. a\
  1680. );\
  1681. }\
  1682. template <class tag, class A1, class A2, class A3, class A4, class Arithmetic> \
  1683. inline typename enable_if_c<\
  1684. is_arithmetic<Arithmetic>::value && (number_category<detail::expression<tag, A1, A2, A3, A4> >::value == category),\
  1685. detail::expression<\
  1686. detail::function\
  1687. , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type> \
  1688. , detail::expression<tag, A1, A2, A3, A4> \
  1689. , Arithmetic\
  1690. > \
  1691. >::type \
  1692. func(const detail::expression<tag, A1, A2, A3, A4>& arg, const Arithmetic& a)\
  1693. {\
  1694. return detail::expression<\
  1695. detail::function\
  1696. , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type> \
  1697. , detail::expression<tag, A1, A2, A3, A4> \
  1698. , Arithmetic\
  1699. >(\
  1700. detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>() \
  1701. , arg,\
  1702. a\
  1703. );\
  1704. }\
  1705. template <class Backend, class Arithmetic> \
  1706. inline typename enable_if_c<\
  1707. is_arithmetic<Arithmetic>::value && (number_category<Backend>::value == category),\
  1708. detail::expression<\
  1709. detail::function\
  1710. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1711. , Arithmetic \
  1712. , number<Backend, et_on> \
  1713. > \
  1714. >::type \
  1715. func(const Arithmetic& arg, const number<Backend, et_on>& a)\
  1716. {\
  1717. return detail::expression<\
  1718. detail::function\
  1719. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1720. , Arithmetic \
  1721. , number<Backend, et_on> \
  1722. >(\
  1723. detail::BOOST_JOIN(func, _funct)<Backend>() \
  1724. , arg,\
  1725. a\
  1726. );\
  1727. }\
  1728. template <class tag, class A1, class A2, class A3, class A4, class Arithmetic> \
  1729. inline typename enable_if_c<\
  1730. is_arithmetic<Arithmetic>::value && (number_category<detail::expression<tag, A1, A2, A3, A4> >::value == category),\
  1731. detail::expression<\
  1732. detail::function\
  1733. , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type> \
  1734. , Arithmetic \
  1735. , detail::expression<tag, A1, A2, A3, A4> \
  1736. > \
  1737. >::type \
  1738. func(const Arithmetic& arg, const detail::expression<tag, A1, A2, A3, A4>& a)\
  1739. {\
  1740. return detail::expression<\
  1741. detail::function\
  1742. , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type> \
  1743. , Arithmetic \
  1744. , detail::expression<tag, A1, A2, A3, A4> \
  1745. >(\
  1746. detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>() \
  1747. , arg,\
  1748. a\
  1749. );\
  1750. }\
  1751. template <class Backend> \
  1752. inline typename enable_if_c<(number_category<Backend>::value == category),\
  1753. number<Backend, et_off> >::type \
  1754. func(const number<Backend, et_off>& arg, const number<Backend, et_off>& a)\
  1755. {\
  1756. number<Backend, et_off> result;\
  1757. using default_ops:: BOOST_JOIN(eval_,func);\
  1758. BOOST_JOIN(eval_,func)(result.backend(), arg.backend(), a.backend());\
  1759. return BOOST_MP_MOVE(result);\
  1760. }\
  1761. template <class Backend, class Arithmetic> \
  1762. inline typename enable_if_c<\
  1763. is_arithmetic<Arithmetic>::value && (number_category<Backend>::value == category),\
  1764. number<Backend, et_off> \
  1765. >::type \
  1766. func(const number<Backend, et_off>& arg, const Arithmetic& a)\
  1767. {\
  1768. typedef typename detail::canonical<Arithmetic, Backend>::type canonical_type;\
  1769. number<Backend, et_off> result;\
  1770. using default_ops:: BOOST_JOIN(eval_,func);\
  1771. BOOST_JOIN(eval_,func)(result.backend(), arg.backend(), static_cast<canonical_type>(a));\
  1772. return BOOST_MP_MOVE(result);\
  1773. }\
  1774. template <class Backend, class Arithmetic> \
  1775. inline typename enable_if_c<\
  1776. is_arithmetic<Arithmetic>::value && (number_category<Backend>::value == category),\
  1777. number<Backend, et_off> \
  1778. >::type \
  1779. func(const Arithmetic& a, const number<Backend, et_off>& arg)\
  1780. {\
  1781. typedef typename detail::canonical<Arithmetic, Backend>::type canonical_type;\
  1782. number<Backend, et_off> result;\
  1783. using default_ops:: BOOST_JOIN(eval_,func);\
  1784. BOOST_JOIN(eval_,func)(result.backend(), static_cast<canonical_type>(a), arg.backend());\
  1785. return BOOST_MP_MOVE(result);\
  1786. }\
  1787. #define HETERO_BINARY_OP_FUNCTOR_B(func, Arg2, category)\
  1788. template <class tag, class A1, class A2, class A3, class A4> \
  1789. inline typename enable_if_c<\
  1790. (number_category<detail::expression<tag, A1, A2, A3, A4> >::value == category),\
  1791. detail::expression<\
  1792. detail::function\
  1793. , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type> \
  1794. , detail::expression<tag, A1, A2, A3, A4> \
  1795. , Arg2> \
  1796. >::type \
  1797. func(const detail::expression<tag, A1, A2, A3, A4>& arg, Arg2 const& a)\
  1798. {\
  1799. return detail::expression<\
  1800. detail::function\
  1801. , detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type> \
  1802. , detail::expression<tag, A1, A2, A3, A4> \
  1803. , Arg2\
  1804. >(\
  1805. detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>() \
  1806. , arg, a \
  1807. );\
  1808. }\
  1809. template <class Backend> \
  1810. inline typename enable_if_c<\
  1811. (number_category<Backend>::value == category),\
  1812. detail::expression<\
  1813. detail::function\
  1814. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1815. , number<Backend, et_on> \
  1816. , Arg2> \
  1817. >::type \
  1818. func(const number<Backend, et_on>& arg, Arg2 const& a)\
  1819. {\
  1820. return detail::expression<\
  1821. detail::function\
  1822. , detail::BOOST_JOIN(func, _funct)<Backend> \
  1823. , number<Backend, et_on> \
  1824. , Arg2\
  1825. >(\
  1826. detail::BOOST_JOIN(func, _funct)<Backend>() \
  1827. , arg,\
  1828. a\
  1829. );\
  1830. }\
  1831. template <class Backend> \
  1832. inline typename enable_if_c<\
  1833. (number_category<Backend>::value == category),\
  1834. number<Backend, et_off> >::type \
  1835. func(const number<Backend, et_off>& arg, Arg2 const& a)\
  1836. {\
  1837. number<Backend, et_off> result;\
  1838. using default_ops:: BOOST_JOIN(eval_,func);\
  1839. BOOST_JOIN(eval_,func)(result.backend(), arg.backend(), a);\
  1840. return BOOST_MP_MOVE(result);\
  1841. }\
  1842. #define HETERO_BINARY_OP_FUNCTOR(func, Arg2, category)\
  1843. namespace detail{\
  1844. template <class Backend> \
  1845. struct BOOST_JOIN(func, _funct)\
  1846. {\
  1847. template <class Arg>\
  1848. void operator()(Backend& result, Backend const& arg, Arg a)const\
  1849. {\
  1850. using default_ops:: BOOST_JOIN(eval_,func);\
  1851. BOOST_JOIN(eval_,func)(result, arg, a);\
  1852. }\
  1853. };\
  1854. \
  1855. }\
  1856. \
  1857. HETERO_BINARY_OP_FUNCTOR_B(func, Arg2, category)
  1858. namespace detail{
  1859. template <class Backend>
  1860. struct abs_funct
  1861. {
  1862. void operator()(Backend& result, const Backend& arg)const
  1863. {
  1864. using default_ops::eval_abs;
  1865. eval_abs(result, arg);
  1866. }
  1867. };
  1868. }
  1869. template <class tag, class A1, class A2, class A3, class A4>
  1870. inline detail::expression<
  1871. detail::function
  1872. , detail::abs_funct<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>
  1873. , detail::expression<tag, A1, A2, A3, A4> >
  1874. abs(const detail::expression<tag, A1, A2, A3, A4>& arg)
  1875. {
  1876. return detail::expression<
  1877. detail::function
  1878. , detail::abs_funct<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>
  1879. , detail::expression<tag, A1, A2, A3, A4>
  1880. > (
  1881. detail::abs_funct<typename detail::backend_type<detail::expression<tag, A1, A2, A3, A4> >::type>()
  1882. , arg
  1883. );
  1884. }
  1885. template <class Backend>
  1886. inline detail::expression<
  1887. detail::function
  1888. , detail::abs_funct<Backend>
  1889. , number<Backend, et_on> >
  1890. abs(const number<Backend, et_on>& arg)
  1891. {
  1892. return detail::expression<
  1893. detail::function
  1894. , detail::abs_funct<Backend>
  1895. , number<Backend, et_on>
  1896. >(
  1897. detail::abs_funct<Backend>()
  1898. , arg
  1899. );
  1900. }
  1901. template <class Backend>
  1902. inline number<Backend, et_off>
  1903. abs(const number<Backend, et_off>& arg)
  1904. {
  1905. number<Backend, et_off> result;
  1906. using default_ops::eval_abs;
  1907. eval_abs(result.backend(), arg.backend());
  1908. return BOOST_MP_MOVE(result);
  1909. }
  1910. UNARY_OP_FUNCTOR(fabs, number_kind_floating_point)
  1911. UNARY_OP_FUNCTOR(sqrt, number_kind_floating_point)
  1912. UNARY_OP_FUNCTOR(floor, number_kind_floating_point)
  1913. UNARY_OP_FUNCTOR(ceil, number_kind_floating_point)
  1914. UNARY_OP_FUNCTOR(trunc, number_kind_floating_point)
  1915. UNARY_OP_FUNCTOR(round, number_kind_floating_point)
  1916. UNARY_OP_FUNCTOR(exp, number_kind_floating_point)
  1917. UNARY_OP_FUNCTOR(log, number_kind_floating_point)
  1918. UNARY_OP_FUNCTOR(log10, number_kind_floating_point)
  1919. UNARY_OP_FUNCTOR(cos, number_kind_floating_point)
  1920. UNARY_OP_FUNCTOR(sin, number_kind_floating_point)
  1921. UNARY_OP_FUNCTOR(tan, number_kind_floating_point)
  1922. UNARY_OP_FUNCTOR(asin, number_kind_floating_point)
  1923. UNARY_OP_FUNCTOR(acos, number_kind_floating_point)
  1924. UNARY_OP_FUNCTOR(atan, number_kind_floating_point)
  1925. UNARY_OP_FUNCTOR(cosh, number_kind_floating_point)
  1926. UNARY_OP_FUNCTOR(sinh, number_kind_floating_point)
  1927. UNARY_OP_FUNCTOR(tanh, number_kind_floating_point)
  1928. HETERO_BINARY_OP_FUNCTOR(ldexp, int, number_kind_floating_point)
  1929. HETERO_BINARY_OP_FUNCTOR(frexp, int*, number_kind_floating_point)
  1930. HETERO_BINARY_OP_FUNCTOR_B(ldexp, long, number_kind_floating_point)
  1931. HETERO_BINARY_OP_FUNCTOR_B(frexp, long*, number_kind_floating_point)
  1932. HETERO_BINARY_OP_FUNCTOR_B(ldexp, long long, number_kind_floating_point)
  1933. HETERO_BINARY_OP_FUNCTOR_B(frexp, long long*, number_kind_floating_point)
  1934. BINARY_OP_FUNCTOR(pow, number_kind_floating_point)
  1935. BINARY_OP_FUNCTOR(fmod, number_kind_floating_point)
  1936. BINARY_OP_FUNCTOR(atan2, number_kind_floating_point)
  1937. //
  1938. // Integer functions:
  1939. //
  1940. BINARY_OP_FUNCTOR(gcd, number_kind_integer)
  1941. BINARY_OP_FUNCTOR(lcm, number_kind_integer)
  1942. HETERO_BINARY_OP_FUNCTOR_B(pow, unsigned, number_kind_integer)
  1943. #undef BINARY_OP_FUNCTOR
  1944. #undef UNARY_OP_FUNCTOR
  1945. } //namespace multiprecision
  1946. namespace math{
  1947. //
  1948. // Overload of Boost.Math functions that find the wrong overload when used with number:
  1949. //
  1950. namespace detail{
  1951. template <class T> T sinc_pi_imp(T);
  1952. template <class T> T sinhc_pi_imp(T);
  1953. }
  1954. template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
  1955. inline multiprecision::number<Backend, ExpressionTemplates> sinc_pi(const multiprecision::number<Backend, ExpressionTemplates>& x)
  1956. {
  1957. return BOOST_MP_MOVE(detail::sinc_pi_imp(x));
  1958. }
  1959. template <class Backend, multiprecision::expression_template_option ExpressionTemplates, class Policy>
  1960. inline multiprecision::number<Backend, ExpressionTemplates> sinc_pi(const multiprecision::number<Backend, ExpressionTemplates>& x, const Policy&)
  1961. {
  1962. return BOOST_MP_MOVE(detail::sinc_pi_imp(x));
  1963. }
  1964. template <class Backend, multiprecision::expression_template_option ExpressionTemplates>
  1965. inline multiprecision::number<Backend, ExpressionTemplates> sinhc_pi(const multiprecision::number<Backend, ExpressionTemplates>& x)
  1966. {
  1967. return BOOST_MP_MOVE(detail::sinhc_pi_imp(x));
  1968. }
  1969. template <class Backend, multiprecision::expression_template_option ExpressionTemplates, class Policy>
  1970. inline multiprecision::number<Backend, ExpressionTemplates> sinhc_pi(const multiprecision::number<Backend, ExpressionTemplates>& x, const Policy&)
  1971. {
  1972. return BOOST_MP_MOVE(boost::math::sinhc_pi(x));
  1973. }
  1974. #ifdef BOOST_MSVC
  1975. #pragma warning(pop)
  1976. #endif
  1977. } // namespace math
  1978. } // namespace boost
  1979. //
  1980. // This has to come last of all:
  1981. //
  1982. #include <boost/multiprecision/detail/no_et_ops.hpp>
  1983. #include <boost/multiprecision/detail/et_ops.hpp>
  1984. #endif