xp.c
资源名称:c.rar [点击查看]
上传用户:shmaik
上传日期:2014-06-01
资源大小:45093k
文件大小:6k
源码类别:

VC书籍

开发平台:

C/C++

  1. static char rcsid[] = "$Id: H:/drh/idioms/book/RCS/xp.doc,v 1.10 1996/06/26 23:02:01 drh Exp $";
  2. #include <ctype.h>
  3. #include <string.h>
  4. #include "assert.h"
  5. #include "xp.h"
  6. #define T XP_T
  7. #define BASE (1<<8)
  8. static char map[] = {
  9.  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
  10. 36, 36, 36, 36, 36, 36, 36,
  11. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
  12. 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
  13. 36, 36, 36, 36, 36, 36,
  14. 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
  15. 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
  16. };
  17. unsigned long XP_fromint(int n, T z, unsigned long u) {
  18. int i = 0;
  19. do
  20. z[i++] = u%BASE;
  21. while ((u /= BASE) > 0 && i < n);
  22. for ( ; i < n; i++)
  23. z[i] = 0;
  24. return u;
  25. }
  26. unsigned long XP_toint(int n, T x) {
  27. unsigned long u = 0;
  28. int i = (int)sizeof u;
  29. if (i > n)
  30. i = n;
  31. while (--i >= 0)
  32. u = BASE*u + x[i];
  33. return u;
  34. }
  35. int XP_length(int n, T x) {
  36. while (n > 1 && x[n-1] == 0)
  37. n--;
  38. return n;
  39. }
  40. int XP_add(int n, T z, T x, T y, int carry) {
  41. int i;
  42. for (i = 0; i < n; i++) {
  43. carry += x[i] + y[i];
  44. z[i] = carry%BASE;
  45. carry /= BASE;
  46. }
  47. return carry;
  48. }
  49. int XP_sub(int n, T z, T x, T y, int borrow) {
  50. int i;
  51. for (i = 0; i < n; i++) {
  52. int d = (x[i] + BASE) - borrow - y[i];
  53. z[i] = d%BASE;
  54. borrow = 1 - d/BASE;
  55. }
  56. return borrow;
  57. }
  58. int XP_sum(int n, T z, T x, int y) {
  59. int i;
  60. for (i = 0; i < n; i++) {
  61. y += x[i];
  62. z[i] = y%BASE;
  63. y /= BASE;
  64. }
  65. return y;
  66. }
  67. int XP_diff(int n, T z, T x, int y) {
  68. int i;
  69. for (i = 0; i < n; i++) {
  70. int d = (x[i] + BASE) - y;
  71. z[i] = d%BASE;
  72. y = 1 - d/BASE;
  73. }
  74. return y;
  75. }
  76. int XP_neg(int n, T z, T x, int carry) {
  77. int i;
  78. for (i = 0; i < n; i++) {
  79. carry += (unsigned char)~x[i];
  80. z[i] = carry%BASE;
  81. carry /= BASE;
  82. }
  83. return carry;
  84. }
  85. int XP_mul(T z, int n, T x, int m, T y) {
  86. int i, j, carryout = 0;
  87. for (i = 0; i < n; i++) {
  88. unsigned carry = 0;
  89. for (j = 0; j < m; j++) {
  90. carry += x[i]*y[j] + z[i+j];
  91. z[i+j] = carry%BASE;
  92. carry /= BASE;
  93. }
  94. for ( ; j < n + m - i; j++) {
  95. carry += z[i+j];
  96. z[i+j] = carry%BASE;
  97. carry /= BASE;
  98. }
  99. carryout |= carry;
  100. }
  101. return carryout;
  102. }
  103. int XP_product(int n, T z, T x, int y) {
  104. int i;
  105. unsigned carry = 0;
  106. for (i = 0; i < n; i++) {
  107. carry += x[i]*y;
  108. z[i] = carry%BASE;
  109. carry /= BASE;
  110. }
  111. return carry;
  112. }
  113. int XP_div(int n, T q, T x, int m, T y, T r, T tmp) {
  114. int nx = n, my = m;
  115. n = XP_length(n, x);
  116. m = XP_length(m, y);
  117. if (m == 1) {
  118. if (y[0] == 0)
  119. return 0;
  120. r[0] = XP_quotient(nx, q, x, y[0]);
  121. memset(r + 1, '', my - 1);
  122. } else if (m > n) {
  123. memset(q, '', nx);
  124. memcpy(r, x, n);
  125. memset(r + n, '', my - n);
  126. } else {
  127. int k;
  128. unsigned char *rem = tmp, *dq = tmp + n + 1;
  129. assert(2 <= m && m <= n);
  130. memcpy(rem, x, n);
  131. rem[n] = 0;
  132. for (k = n - m; k >= 0; k--) {
  133. int qk;
  134. {
  135. int i;
  136. assert(2 <= m && m <= k+m && k+m <= n);
  137. {
  138. int km = k + m;
  139. unsigned long y2 = y[m-1]*BASE + y[m-2];
  140. unsigned long r3 = rem[km]*(BASE*BASE) +
  141. rem[km-1]*BASE + rem[km-2];
  142. qk = r3/y2;
  143. if (qk >= BASE)
  144. qk = BASE - 1;
  145. }
  146. dq[m] = XP_product(m, dq, y, qk);
  147. for (i = m; i > 0; i--)
  148. if (rem[i+k] != dq[i])
  149. break;
  150. if (rem[i+k] < dq[i])
  151. dq[m] = XP_product(m, dq, y, --qk);
  152. }
  153. q[k] = qk;
  154. {
  155. int borrow;
  156. assert(0 <= k && k <= k+m);
  157. borrow = XP_sub(m + 1, &rem[k], &rem[k], dq, 0);
  158. assert(borrow == 0);
  159. }
  160. }
  161. memcpy(r, rem, m);
  162. {
  163. int i;
  164. for (i = n-m+1; i < nx; i++)
  165. q[i] = 0;
  166. for (i = m; i < my; i++)
  167. r[i] = 0;
  168. }
  169. }
  170. return 1;
  171. }
  172. int XP_quotient(int n, T z, T x, int y) {
  173. int i;
  174. unsigned carry = 0;
  175. for (i = n - 1; i >= 0; i--) {
  176. carry = carry*BASE + x[i];
  177. z[i] = carry/y;
  178. carry %= y;
  179. }
  180. return carry;
  181. }
  182. int XP_cmp(int n, T x, T y) {
  183. int i = n - 1;
  184. while (i > 0 && x[i] == y[i])
  185. i--;
  186. return x[i] - y[i];
  187. }
  188. void XP_lshift(int n, T z, int m, T x, int s, int fill) {
  189. fill = fill ? 0xFF : 0;
  190. {
  191. int i, j = n - 1;
  192. if (n > m)
  193. i = m - 1;
  194. else
  195. i = n - s/8 - 1;
  196. for ( ; j >= m + s/8; j--)
  197. z[j] = 0;
  198. for ( ; i >= 0; i--, j--)
  199. z[j] = x[i];
  200. for ( ; j >= 0; j--)
  201. z[j] = fill;
  202. }
  203. s %= 8;
  204. if (s > 0)
  205. {
  206. XP_product(n, z, z, 1<<s);
  207. z[0] |= fill>>(8-s);
  208. }
  209. }
  210. void XP_rshift(int n, T z, int m, T x, int s, int fill) {
  211. fill = fill ? 0xFF : 0;
  212. {
  213. int i, j = 0;
  214. for (i = s/8; i < m && j < n; i++, j++)
  215. z[j] = x[i];
  216. for ( ; j < n; j++)
  217. z[j] = fill;
  218. }
  219. s %= 8;
  220. if (s > 0)
  221. {
  222. XP_quotient(n, z, z, 1<<s);
  223. z[n-1] |= fill<<(8-s);
  224. }
  225. }
  226. int XP_fromstr(int n, T z, const char *str,
  227. int base, char **end) {
  228. const char *p = str;
  229. assert(p);
  230. assert(base >= 2 && base <= 36);
  231. while (*p && isspace(*p))
  232. p++;
  233. if ((*p && isalnum(*p) && map[*p-'0'] < base)) {
  234. int carry;
  235. for ( ; (*p && isalnum(*p) && map[*p-'0'] < base); p++) {
  236. carry = XP_product(n, z, z, base);
  237. if (carry)
  238. break;
  239. XP_sum(n, z, z, map[*p-'0']);
  240. }
  241. if (end)
  242. *end = (char *)p;
  243. return carry;
  244. } else {
  245. if (end)
  246. *end = (char *)str;
  247. return 0;
  248. }
  249. }
  250. char *XP_tostr(char *str, int size, int base,
  251. int n, T x) {
  252. int i = 0;
  253. assert(str);
  254. assert(base >= 2 && base <= 36);
  255. do {
  256. int r = XP_quotient(n, x, x, base);
  257. assert(i < size);
  258. str[i++] =
  259. "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[r];
  260. while (n > 1 && x[n-1] == 0)
  261. n--;
  262. } while (n > 1 || x[0] != 0);
  263. assert(i < size);
  264. str[i] = '';
  265. {
  266. int j;
  267. for (j = 0; j < --i; j++) {
  268. char c = str[j];
  269. str[j] = str[i];
  270. str[i] = c;
  271. }
  272. }
  273. return str;
  274. }