divide.hpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. ///////////////////////////////////////////////////////////////
  2. // Copyright 2012 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_
  5. //
  6. // Comparison operators for cpp_int_backend:
  7. //
  8. #ifndef BOOST_MP_CPP_INT_DIV_HPP
  9. #define BOOST_MP_CPP_INT_DIV_HPP
  10. namespace boost{ namespace multiprecision{ namespace backends{
  11. template <class CppInt1, class CppInt2, class CppInt3>
  12. void divide_unsigned_helper(
  13. CppInt1* result,
  14. const CppInt2& x,
  15. const CppInt3& y,
  16. CppInt1& r)
  17. {
  18. if(((void*)result == (void*)&x) || ((void*)&r == (void*)&x))
  19. {
  20. CppInt2 t(x);
  21. divide_unsigned_helper(result, t, y, r);
  22. return;
  23. }
  24. if(((void*)result == (void*)&y) || ((void*)&r == (void*)&y))
  25. {
  26. CppInt3 t(y);
  27. divide_unsigned_helper(result, x, t, r);
  28. return;
  29. }
  30. /*
  31. Very simple, fairly braindead long division.
  32. Start by setting the remainder equal to x, and the
  33. result equal to 0. Then in each loop we calculate our
  34. "best guess" for how many times y divides into r,
  35. add our guess to the result, and subtract guess*y
  36. from the remainder r. One wrinkle is that the remainder
  37. may go negative, in which case we subtract the current guess
  38. from the result rather than adding. The value of the guess
  39. is determined by dividing the most-significant-limb of the
  40. current remainder by the most-significant-limb of y.
  41. Note that there are more efficient algorithms than this
  42. available, in particular see Knuth Vol 2. However for small
  43. numbers of limbs this generally outperforms the alternatives
  44. and avoids the normalisation step which would require extra storage.
  45. */
  46. using default_ops::eval_subtract;
  47. if(result == &r)
  48. {
  49. CppInt1 rem;
  50. divide_unsigned_helper(result, x, y, rem);
  51. r = rem;
  52. return;
  53. }
  54. //
  55. // Find the most significant words of numerator and denominator.
  56. //
  57. limb_type y_order = y.size() - 1;
  58. if(y_order == 0)
  59. {
  60. //
  61. // Only a single non-zero limb in the denominator, in this case
  62. // we can use a specialized divide-by-single-limb routine which is
  63. // much faster. This also handles division by zero:
  64. //
  65. divide_unsigned_helper(result, x, y.limbs()[y_order], r);
  66. return;
  67. }
  68. typename CppInt2::const_limb_pointer px = x.limbs();
  69. typename CppInt3::const_limb_pointer py = y.limbs();
  70. limb_type r_order = x.size() - 1;
  71. if((r_order == 0) && (*px == 0))
  72. {
  73. // x is zero, so is the result:
  74. r = x;
  75. if(result)
  76. *result = x;
  77. return;
  78. }
  79. r = x;
  80. r.sign(false);
  81. if(result)
  82. *result = static_cast<limb_type>(0u);
  83. //
  84. // Check if the remainder is already less than the divisor, if so
  85. // we already have the result. Note we try and avoid a full compare
  86. // if we can:
  87. //
  88. if(r_order <= y_order)
  89. {
  90. if((r_order < y_order) || (r.compare_unsigned(y) < 0))
  91. {
  92. return;
  93. }
  94. }
  95. CppInt1 t;
  96. bool r_neg = false;
  97. //
  98. // See if we can short-circuit long division, and use basic arithmetic instead:
  99. //
  100. if(r_order == 0)
  101. {
  102. if(result)
  103. {
  104. *result = px[0] / py[0];
  105. }
  106. r = px[0] % py[0];
  107. return;
  108. }
  109. else if(r_order == 1)
  110. {
  111. double_limb_type a, b;
  112. a = (static_cast<double_limb_type>(px[1]) << CppInt1::limb_bits) | px[0];
  113. b = y_order ?
  114. (static_cast<double_limb_type>(py[1]) << CppInt1::limb_bits) | py[0]
  115. : py[0];
  116. if(result)
  117. {
  118. *result = a / b;
  119. }
  120. r = a % b;
  121. return;
  122. }
  123. //
  124. // prepare result:
  125. //
  126. if(result)
  127. result->resize(1 + r_order - y_order, 1 + r_order - y_order);
  128. typename CppInt1::const_limb_pointer prem = r.limbs();
  129. // This is initialised just to keep the compiler from emitting useless warnings later on:
  130. typename CppInt1::limb_pointer pr
  131. = typename CppInt1::limb_pointer();
  132. if(result)
  133. {
  134. pr = result->limbs();
  135. for(unsigned i = 1; i < 1 + r_order - y_order; ++i)
  136. pr[i] = 0;
  137. }
  138. bool first_pass = true;
  139. do
  140. {
  141. //
  142. // Calculate our best guess for how many times y divides into r:
  143. //
  144. limb_type guess;
  145. if((prem[r_order] <= py[y_order]) && (r_order > 0))
  146. {
  147. double_limb_type a, b, v;
  148. a = (static_cast<double_limb_type>(prem[r_order]) << CppInt1::limb_bits) | prem[r_order - 1];
  149. b = py[y_order];
  150. v = a / b;
  151. if(v > CppInt1::max_limb_value)
  152. guess = 1;
  153. else
  154. {
  155. guess = static_cast<limb_type>(v);
  156. --r_order;
  157. }
  158. }
  159. else if(r_order == 0)
  160. {
  161. guess = prem[0] / py[y_order];
  162. }
  163. else
  164. {
  165. double_limb_type a, b, v;
  166. a = (static_cast<double_limb_type>(prem[r_order]) << CppInt1::limb_bits) | prem[r_order - 1];
  167. b = (y_order > 0) ? (static_cast<double_limb_type>(py[y_order]) << CppInt1::limb_bits) | py[y_order - 1] : (static_cast<double_limb_type>(py[y_order]) << CppInt1::limb_bits);
  168. v = a / b;
  169. guess = static_cast<limb_type>(v);
  170. }
  171. BOOST_ASSERT(guess); // If the guess ever gets to zero we go on forever....
  172. //
  173. // Update result:
  174. //
  175. limb_type shift = r_order - y_order;
  176. if(result)
  177. {
  178. if(r_neg)
  179. {
  180. if(pr[shift] > guess)
  181. pr[shift] -= guess;
  182. else
  183. {
  184. t.resize(shift + 1, shift + 1);
  185. t.limbs()[shift] = guess;
  186. for(unsigned i = 0; i < shift; ++i)
  187. t.limbs()[i] = 0;
  188. eval_subtract(*result, t);
  189. }
  190. }
  191. else if(CppInt1::max_limb_value - pr[shift] > guess)
  192. pr[shift] += guess;
  193. else
  194. {
  195. t.resize(shift + 1, shift + 1);
  196. t.limbs()[shift] = guess;
  197. for(unsigned i = 0; i < shift; ++i)
  198. t.limbs()[i] = 0;
  199. eval_add(*result, t);
  200. }
  201. }
  202. //
  203. // Calculate guess * y, we use a fused mutiply-shift O(N) for this
  204. // rather than a full O(N^2) multiply:
  205. //
  206. double_limb_type carry = 0;
  207. t.resize(y.size() + shift + 1, y.size() + shift);
  208. bool truncated_t = (t.size() != y.size() + shift + 1);
  209. typename CppInt1::limb_pointer pt = t.limbs();
  210. for(unsigned i = 0; i < shift; ++i)
  211. pt[i] = 0;
  212. for(unsigned i = 0; i < y.size(); ++i)
  213. {
  214. carry += static_cast<double_limb_type>(py[i]) * static_cast<double_limb_type>(guess);
  215. #ifdef __MSVC_RUNTIME_CHECKS
  216. pt[i + shift] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
  217. #else
  218. pt[i + shift] = static_cast<limb_type>(carry);
  219. #endif
  220. carry >>= CppInt1::limb_bits;
  221. }
  222. if(carry && !truncated_t)
  223. {
  224. #ifdef __MSVC_RUNTIME_CHECKS
  225. pt[t.size() - 1] = static_cast<limb_type>(carry & ~static_cast<limb_type>(0));
  226. #else
  227. pt[t.size() - 1] = static_cast<limb_type>(carry);
  228. #endif
  229. }
  230. else if(!truncated_t)
  231. {
  232. t.resize(t.size() - 1, t.size() - 1);
  233. }
  234. //
  235. // Update r in a way that won't actually produce a negative result
  236. // in case the argument types are unsigned:
  237. //
  238. if(truncated_t && carry)
  239. {
  240. // We need to calculate 2^n + t - r
  241. // where n is the number of bits in this type.
  242. // Simplest way is to get 2^n - r by complementing
  243. // r, then add t to it. Note that we can't call eval_complement
  244. // in case this is a signed checked type:
  245. for(unsigned i = 0; i <= r_order; ++i)
  246. r.limbs()[i] = ~prem[i];
  247. r.normalize();
  248. eval_increment(r);
  249. eval_add(r, t);
  250. r_neg = !r_neg;
  251. }
  252. else if(r.compare(t) > 0)
  253. {
  254. eval_subtract(r, t);
  255. }
  256. else
  257. {
  258. r.swap(t);
  259. eval_subtract(r, t);
  260. prem = r.limbs();
  261. r_neg = !r_neg;
  262. }
  263. //
  264. // First time through we need to strip any leading zero, otherwise
  265. // the termination condition goes belly-up:
  266. //
  267. if(result && first_pass)
  268. {
  269. first_pass = false;
  270. while(pr[result->size() - 1] == 0)
  271. result->resize(result->size() - 1, result->size() - 1);
  272. }
  273. //
  274. // Update r_order:
  275. //
  276. r_order = r.size() - 1;
  277. if(r_order < y_order)
  278. break;
  279. }
  280. // Termination condition is really just a check that r > y, but with a common
  281. // short-circuit case handled first:
  282. while((r_order > y_order) || (r.compare_unsigned(y) >= 0));
  283. //
  284. // We now just have to normalise the result:
  285. //
  286. if(r_neg && eval_get_sign(r))
  287. {
  288. // We have one too many in the result:
  289. if(result)
  290. eval_decrement(*result);
  291. if(y.sign())
  292. {
  293. r.negate();
  294. eval_subtract(r, y);
  295. }
  296. else
  297. eval_subtract(r, y, r);
  298. }
  299. BOOST_ASSERT(r.compare_unsigned(y) < 0); // remainder must be less than the divisor or our code has failed
  300. }
  301. template <class CppInt1, class CppInt2>
  302. void divide_unsigned_helper(
  303. CppInt1* result,
  304. const CppInt2& x,
  305. limb_type y,
  306. CppInt1& r)
  307. {
  308. if(((void*)result == (void*)&x) || ((void*)&r == (void*)&x))
  309. {
  310. CppInt2 t(x);
  311. divide_unsigned_helper(result, t, y, r);
  312. return;
  313. }
  314. if(result == &r)
  315. {
  316. CppInt1 rem;
  317. divide_unsigned_helper(result, x, y, rem);
  318. r = rem;
  319. return;
  320. }
  321. // As above, but simplified for integer divisor:
  322. using default_ops::eval_subtract;
  323. if(y == 0)
  324. {
  325. BOOST_THROW_EXCEPTION(std::overflow_error("Integer Division by zero."));
  326. }
  327. //
  328. // Find the most significant word of numerator.
  329. //
  330. limb_type r_order = x.size() - 1;
  331. //
  332. // Set remainder and result to their initial values:
  333. //
  334. r = x;
  335. r.sign(false);
  336. typename CppInt1::limb_pointer pr = r.limbs();
  337. //
  338. // check for x < y, try to do this without actually having to
  339. // do a full comparison:
  340. //
  341. if((r_order == 0) && (*pr < y))
  342. {
  343. if(result)
  344. *result = static_cast<limb_type>(0u);
  345. return;
  346. }
  347. //
  348. // See if we can short-circuit long division, and use basic arithmetic instead:
  349. //
  350. if(r_order == 0)
  351. {
  352. if(result)
  353. {
  354. *result = *pr / y;
  355. result->sign(x.sign());
  356. }
  357. *pr %= y;
  358. r.sign(x.sign());
  359. return;
  360. }
  361. else if(r_order == 1)
  362. {
  363. double_limb_type a;
  364. a = (static_cast<double_limb_type>(pr[r_order]) << CppInt1::limb_bits) | pr[0];
  365. if(result)
  366. {
  367. *result = a / y;
  368. result->sign(x.sign());
  369. }
  370. r = a % y;
  371. r.sign(x.sign());
  372. return;
  373. }
  374. // This is initialised just to keep the compiler from emitting useless warnings later on:
  375. typename CppInt1::limb_pointer pres = typename CppInt1::limb_pointer();
  376. if(result)
  377. {
  378. result->resize(r_order + 1, r_order + 1);
  379. pres = result->limbs();
  380. if(result->size() > r_order)
  381. pres[r_order] = 0; // just in case we don't set the most significant limb below.
  382. }
  383. do
  384. {
  385. //
  386. // Calculate our best guess for how many times y divides into r:
  387. //
  388. if((pr[r_order] < y) && r_order)
  389. {
  390. double_limb_type a, b;
  391. a = (static_cast<double_limb_type>(pr[r_order]) << CppInt1::limb_bits) | pr[r_order - 1];
  392. b = a % y;
  393. r.resize(r.size() - 1, r.size() - 1);
  394. --r_order;
  395. pr[r_order] = static_cast<limb_type>(b);
  396. if(result)
  397. pres[r_order] = static_cast<limb_type>(a / y);
  398. if(r_order && pr[r_order] == 0)
  399. {
  400. --r_order; // No remainder, division was exact.
  401. r.resize(r.size() - 1, r.size() - 1);
  402. if(result)
  403. pres[r_order] = static_cast<limb_type>(0u);
  404. }
  405. }
  406. else
  407. {
  408. if(result)
  409. pres[r_order] = pr[r_order] / y;
  410. pr[r_order] %= y;
  411. if(r_order && pr[r_order] == 0)
  412. {
  413. --r_order; // No remainder, division was exact.
  414. r.resize(r.size() - 1, r.size() - 1);
  415. if(result)
  416. pres[r_order] = static_cast<limb_type>(0u);
  417. }
  418. }
  419. }
  420. // Termination condition is really just a check that r >= y, but with two common
  421. // short-circuit cases handled first:
  422. while(r_order || (pr[r_order] >= y));
  423. if(result)
  424. {
  425. result->normalize();
  426. result->sign(x.sign());
  427. }
  428. r.normalize();
  429. r.sign(x.sign());
  430. BOOST_ASSERT(r.compare(y) < 0); // remainder must be less than the divisor or our code has failed
  431. }
  432. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, unsigned MinBits3, unsigned MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
  433. BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value >::type
  434. eval_divide(
  435. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  436. const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
  437. const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b)
  438. {
  439. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> r;
  440. bool s = a.sign() != b.sign();
  441. divide_unsigned_helper(&result, a, b, r);
  442. result.sign(s);
  443. }
  444. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  445. BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
  446. eval_divide(
  447. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  448. const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
  449. limb_type& b)
  450. {
  451. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> r;
  452. bool s = a.sign();
  453. divide_unsigned_helper(&result, a, b, r);
  454. result.sign(s);
  455. }
  456. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  457. BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
  458. eval_divide(
  459. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  460. const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
  461. signed_limb_type& b)
  462. {
  463. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> r;
  464. bool s = a.sign() != (b < 0);
  465. divide_unsigned_helper(&result, a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(b)), r);
  466. result.sign(s);
  467. }
  468. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  469. BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
  470. eval_divide(
  471. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  472. const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& b)
  473. {
  474. // There is no in place divide:
  475. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result);
  476. eval_divide(result, a, b);
  477. }
  478. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
  479. BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
  480. eval_divide(
  481. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  482. limb_type b)
  483. {
  484. // There is no in place divide:
  485. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result);
  486. eval_divide(result, a, b);
  487. }
  488. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
  489. BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
  490. eval_divide(
  491. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  492. signed_limb_type b)
  493. {
  494. // There is no in place divide:
  495. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result);
  496. eval_divide(result, a, b);
  497. }
  498. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2, unsigned MinBits3, unsigned MaxBits3, cpp_integer_type SignType3, cpp_int_check_type Checked3, class Allocator3>
  499. BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3> >::value >::type
  500. eval_modulus(
  501. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  502. const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
  503. const cpp_int_backend<MinBits3, MaxBits3, SignType3, Checked3, Allocator3>& b)
  504. {
  505. bool s = a.sign();
  506. divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>* >(0), a, b, result);
  507. result.sign(s);
  508. }
  509. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  510. BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
  511. eval_modulus(
  512. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  513. const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a, limb_type b)
  514. {
  515. bool s = a.sign();
  516. divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>* >(0), a, b, result);
  517. result.sign(s);
  518. }
  519. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  520. BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
  521. eval_modulus(
  522. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  523. const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& a,
  524. signed_limb_type b)
  525. {
  526. bool s = a.sign();
  527. divide_unsigned_helper(static_cast<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>* >(0), a, static_cast<limb_type>(boost::multiprecision::detail::unsigned_abs(b)), result);
  528. result.sign(s);
  529. }
  530. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1, unsigned MinBits2, unsigned MaxBits2, cpp_integer_type SignType2, cpp_int_check_type Checked2, class Allocator2>
  531. BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value && !is_trivial_cpp_int<cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2> >::value >::type
  532. eval_modulus(
  533. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  534. const cpp_int_backend<MinBits2, MaxBits2, SignType2, Checked2, Allocator2>& b)
  535. {
  536. // There is no in place divide:
  537. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result);
  538. eval_modulus(result, a, b);
  539. }
  540. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
  541. BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
  542. eval_modulus(
  543. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  544. limb_type b)
  545. {
  546. // There is no in place divide:
  547. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result);
  548. eval_modulus(result, a, b);
  549. }
  550. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
  551. BOOST_MP_FORCEINLINE typename enable_if_c<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value>::type
  552. eval_modulus(
  553. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  554. signed_limb_type b)
  555. {
  556. // There is no in place divide:
  557. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> a(result);
  558. eval_modulus(result, a, b);
  559. }
  560. //
  561. // Over again for trivial cpp_int's:
  562. //
  563. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
  564. BOOST_MP_FORCEINLINE typename enable_if_c<
  565. is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
  566. && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
  567. && (is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
  568. || is_signed_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value)
  569. >::type
  570. eval_divide(
  571. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  572. const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o)
  573. {
  574. if(!*o.limbs())
  575. BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
  576. *result.limbs() /= *o.limbs();
  577. result.sign(result.sign() != o.sign());
  578. }
  579. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
  580. BOOST_MP_FORCEINLINE typename enable_if_c<
  581. is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
  582. && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
  583. && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
  584. && is_unsigned_number<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
  585. >::type
  586. eval_divide(
  587. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  588. const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o)
  589. {
  590. if(!*o.limbs())
  591. BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
  592. *result.limbs() /= *o.limbs();
  593. }
  594. template <unsigned MinBits1, unsigned MaxBits1, cpp_integer_type SignType1, cpp_int_check_type Checked1, class Allocator1>
  595. BOOST_MP_FORCEINLINE typename enable_if_c<
  596. is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
  597. && is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value
  598. >::type
  599. eval_modulus(
  600. cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result,
  601. const cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& o)
  602. {
  603. if(!*o.limbs())
  604. BOOST_THROW_EXCEPTION(std::overflow_error("Division by zero."));
  605. *result.limbs() %= *o.limbs();
  606. result.sign(result.sign());
  607. }
  608. }}} // namespaces
  609. #endif