qdivrem.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /*-
  2. * Copyright (c) 1992, 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * This software was developed by the Computer Systems Engineering group
  6. * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
  7. * contributed to Berkeley.
  8. *
  9. * Redistribution and use in source and binary forms, with or without
  10. * modification, are permitted provided that the following conditions
  11. * are met:
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. * 3. Neither the name of the University nor the names of its contributors
  18. * may be used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. *
  33. * From:
  34. * @(#)qdivrem.c 8.1 (Berkeley) 6/4/93
  35. * NetBSD: qdivrem.c,v 1.1 2005/12/20 19:28:51 christos Exp
  36. */
  37. /*
  38. * Multiprecision divide. This algorithm is from Knuth vol. 2 (2nd ed),
  39. * section 4.3.1, pp. 257--259.
  40. */
  41. #include "longlong.h"
  42. #define B ((int)1 << HALF_BITS) /* digit base */
  43. /* Combine two `digits' to make a single two-digit number. */
  44. #define COMBINE(a, b) (((unsigned int)(a) << HALF_BITS) | (b))
  45. /* select a type for digits in base B: use unsigned short if they fit */
  46. #if UINT_MAX == 0xffffffffU && USHRT_MAX >= 0xffff
  47. typedef unsigned short digit;
  48. #else
  49. typedef unsigned int digit;
  50. #endif
  51. static void shl(digit *p, int len, int sh);
  52. /*
  53. * __qdivrem(u, v, rem) returns u/v and, optionally, sets *rem to u%v.
  54. *
  55. * We do this in base 2-sup-HALF_BITS, so that all intermediate
  56. * products fit within unsigned int. As a consequence, the maximum
  57. * length dividend and divisor are 4 `digits' in this base (they are
  58. * shorter if they have leading zeros).
  59. */
  60. unsigned long long
  61. __qdivrem(unsigned long long ull, unsigned long long vll,
  62. unsigned long long *arq)
  63. {
  64. union uu tmp;
  65. digit *u, *v, *q;
  66. digit v1, v2;
  67. unsigned int qhat, rhat, t;
  68. int m, n, d, j, i;
  69. digit uspace[5], vspace[5], qspace[5];
  70. /*
  71. * Take care of special cases: divide by zero, and u < v.
  72. */
  73. if (vll == 0) {
  74. /* divide by zero. */
  75. static volatile const unsigned int zero = 0;
  76. tmp.ui[H] = tmp.ui[L] = 1 / zero;
  77. if (arq)
  78. *arq = ull;
  79. return (tmp.ll);
  80. }
  81. if (ull < vll) {
  82. if (arq)
  83. *arq = ull;
  84. return (0);
  85. }
  86. u = &uspace[0];
  87. v = &vspace[0];
  88. q = &qspace[0];
  89. /*
  90. * Break dividend and divisor into digits in base B, then
  91. * count leading zeros to determine m and n. When done, we
  92. * will have:
  93. * u = (u[1]u[2]...u[m+n]) sub B
  94. * v = (v[1]v[2]...v[n]) sub B
  95. * v[1] != 0
  96. * 1 < n <= 4 (if n = 1, we use a different division algorithm)
  97. * m >= 0 (otherwise u < v, which we already checked)
  98. * m + n = 4
  99. * and thus
  100. * m = 4 - n <= 2
  101. */
  102. tmp.ull = ull;
  103. u[0] = 0;
  104. u[1] = (digit)HHALF(tmp.ui[H]);
  105. u[2] = (digit)LHALF(tmp.ui[H]);
  106. u[3] = (digit)HHALF(tmp.ui[L]);
  107. u[4] = (digit)LHALF(tmp.ui[L]);
  108. tmp.ull = vll;
  109. v[1] = (digit)HHALF(tmp.ui[H]);
  110. v[2] = (digit)LHALF(tmp.ui[H]);
  111. v[3] = (digit)HHALF(tmp.ui[L]);
  112. v[4] = (digit)LHALF(tmp.ui[L]);
  113. for (n = 4; v[1] == 0; v++) {
  114. if (--n == 1) {
  115. unsigned int rbj; /* r*B+u[j] (not root boy jim) */
  116. digit q1, q2, q3, q4;
  117. /*
  118. * Change of plan, per exercise 16.
  119. * r = 0;
  120. * for j = 1..4:
  121. * q[j] = floor((r*B + u[j]) / v),
  122. * r = (r*B + u[j]) % v;
  123. * We unroll this completely here.
  124. */
  125. t = v[2]; /* nonzero, by definition */
  126. q1 = (digit)(u[1] / t);
  127. rbj = COMBINE(u[1] % t, u[2]);
  128. q2 = (digit)(rbj / t);
  129. rbj = COMBINE(rbj % t, u[3]);
  130. q3 = (digit)(rbj / t);
  131. rbj = COMBINE(rbj % t, u[4]);
  132. q4 = (digit)(rbj / t);
  133. if (arq)
  134. *arq = rbj % t;
  135. tmp.ui[H] = COMBINE(q1, q2);
  136. tmp.ui[L] = COMBINE(q3, q4);
  137. return (tmp.ll);
  138. }
  139. }
  140. /*
  141. * By adjusting q once we determine m, we can guarantee that
  142. * there is a complete four-digit quotient at &qspace[1] when
  143. * we finally stop.
  144. */
  145. for (m = 4 - n; u[1] == 0; u++)
  146. m--;
  147. for (i = 4 - m; --i >= 0;)
  148. q[i] = 0;
  149. q += 4 - m;
  150. /*
  151. * Here we run Program D, translated from MIX to C and acquiring
  152. * a few minor changes.
  153. *
  154. * D1: choose multiplier 1 << d to ensure v[1] >= B/2.
  155. */
  156. d = 0;
  157. for (t = v[1]; t < B / 2; t <<= 1)
  158. d++;
  159. if (d > 0) {
  160. shl(&u[0], m + n, d); /* u <<= d */
  161. shl(&v[1], n - 1, d); /* v <<= d */
  162. }
  163. /*
  164. * D2: j = 0.
  165. */
  166. j = 0;
  167. v1 = v[1]; /* for D3 -- note that v[1..n] are constant */
  168. v2 = v[2]; /* for D3 */
  169. do {
  170. digit uj0, uj1, uj2;
  171. /*
  172. * D3: Calculate qhat (\^q, in TeX notation).
  173. * Let qhat = min((u[j]*B + u[j+1])/v[1], B-1), and
  174. * let rhat = (u[j]*B + u[j+1]) mod v[1].
  175. * While rhat < B and v[2]*qhat > rhat*B+u[j+2],
  176. * decrement qhat and increase rhat correspondingly.
  177. * Note that if rhat >= B, v[2]*qhat < rhat*B.
  178. */
  179. uj0 = u[j + 0]; /* for D3 only -- note that u[j+...] change */
  180. uj1 = u[j + 1]; /* for D3 only */
  181. uj2 = u[j + 2]; /* for D3 only */
  182. if (uj0 == v1) {
  183. qhat = B;
  184. rhat = uj1;
  185. goto qhat_too_big;
  186. } else {
  187. unsigned int nn = COMBINE(uj0, uj1);
  188. qhat = nn / v1;
  189. rhat = nn % v1;
  190. }
  191. while (v2 * qhat > COMBINE(rhat, uj2)) {
  192. qhat_too_big:
  193. qhat--;
  194. if ((rhat += v1) >= B)
  195. break;
  196. }
  197. /*
  198. * D4: Multiply and subtract.
  199. * The variable `t' holds any borrows across the loop.
  200. * We split this up so that we do not require v[0] = 0,
  201. * and to eliminate a final special case.
  202. */
  203. for (t = 0, i = n; i > 0; i--) {
  204. t = u[i + j] - v[i] * qhat - t;
  205. u[i + j] = (digit)LHALF(t);
  206. t = (B - HHALF(t)) & (B - 1);
  207. }
  208. t = u[j] - t;
  209. u[j] = (digit)LHALF(t);
  210. /*
  211. * D5: test remainder.
  212. * There is a borrow if and only if HHALF(t) is nonzero;
  213. * in that (rare) case, qhat was too large (by exactly 1).
  214. * Fix it by adding v[1..n] to u[j..j+n].
  215. */
  216. if (HHALF(t)) {
  217. qhat--;
  218. for (t = 0, i = n; i > 0; i--) { /* D6: add back. */
  219. t += u[i + j] + v[i];
  220. u[i + j] = (digit)LHALF(t);
  221. t = HHALF(t);
  222. }
  223. u[j] = (digit)LHALF(u[j] + t);
  224. }
  225. q[j] = (digit)qhat;
  226. } while (++j <= m); /* D7: loop on j. */
  227. /*
  228. * If caller wants the remainder, we have to calculate it as
  229. * u[m..m+n] >> d (this is at most n digits and thus fits in
  230. * u[m+1..m+n], but we may need more source digits).
  231. */
  232. if (arq) {
  233. if (d) {
  234. for (i = m + n; i > m; --i)
  235. u[i] = (digit)(((unsigned int)u[i] >> d) |
  236. LHALF((unsigned int)u[i - 1] <<
  237. (HALF_BITS - d)));
  238. u[i] = 0;
  239. }
  240. tmp.ui[H] = COMBINE(uspace[1], uspace[2]);
  241. tmp.ui[L] = COMBINE(uspace[3], uspace[4]);
  242. *arq = tmp.ll;
  243. }
  244. tmp.ui[H] = COMBINE(qspace[1], qspace[2]);
  245. tmp.ui[L] = COMBINE(qspace[3], qspace[4]);
  246. return (tmp.ll);
  247. }
  248. /*
  249. * Shift p[0]..p[len] left `sh' bits, ignoring any bits that
  250. * `fall out' the left (there never will be any such anyway).
  251. * We may assume len >= 0. NOTE THAT THIS WRITES len+1 DIGITS.
  252. */
  253. static void
  254. shl(digit *p, int len, int sh)
  255. {
  256. int i;
  257. for (i = 0; i < len; i++)
  258. p[i] = (digit)(LHALF((unsigned int)p[i] << sh) |
  259. ((unsigned int)p[i + 1] >> (HALF_BITS - sh)));
  260. p[i] = (digit)(LHALF((unsigned int)p[i] << sh));
  261. }