home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume27 / calc-2.9.0 / part13 < prev    next >
Text File  |  1993-12-07  |  60KB  |  2,213 lines

  1. Newsgroups: comp.sources.unix
  2. From: dbell@canb.auug.org.au (David I. Bell)
  3. Subject: v27i140: calc-2.9.0 - arbitrary precision C-like programmable calculator, Part13/19
  4. References: <1.755316719.21314@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: dbell@canb.auug.org.au (David I. Bell)
  9. Posting-Number: Volume 27, Issue 140
  10. Archive-Name: calc-2.9.0/part13
  11.  
  12. #!/bin/sh
  13. # this is part 13 of a multipart archive
  14. # do not concatenate these parts, unpack them in order with /bin/sh
  15. # file calc2.9.0/zmath.h continued
  16. #
  17. CurArch=13
  18. if test ! -r s2_seq_.tmp
  19. then echo "Please unpack part 1 first!"
  20.      exit 1; fi
  21. ( read Scheck
  22.   if test "$Scheck" != $CurArch
  23.   then echo "Please unpack part $Scheck next!"
  24.        exit 1;
  25.   else exit 0; fi
  26. ) < s2_seq_.tmp || exit 1
  27. echo "x - Continuing file calc2.9.0/zmath.h"
  28. sed 's/^X//' << 'SHAR_EOF' >> calc2.9.0/zmath.h
  29. X#endif
  30. Xextern void zminmod MATH_PROTO((ZVALUE z1, ZVALUE z2, ZVALUE *res));
  31. Xextern BOOL zcmpmod MATH_PROTO((ZVALUE z1, ZVALUE z2, ZVALUE z3));
  32. X
  33. X
  34. X/*
  35. X * These functions are for internal use only.
  36. X */
  37. Xextern void ztrim MATH_PROTO((ZVALUE *z));
  38. Xextern void zshiftr MATH_PROTO((ZVALUE z, long n));
  39. Xextern void zshiftl MATH_PROTO((ZVALUE z, long n));
  40. Xextern HALF *zalloctemp MATH_PROTO((LEN len));
  41. Xextern void initmasks MATH_PROTO((void));
  42. X
  43. X
  44. X/*
  45. X * Modulo arithmetic definitions.
  46. X * Structure holding state of REDC initialization.
  47. X * Multiple instances of this structure can be used allowing
  48. X * calculations with more than one modulus at the same time.
  49. X * Len of zero means the structure is not initialized.
  50. X */
  51. Xtypedef    struct {
  52. X    LEN len;        /* number of words in binary modulus */
  53. X    ZVALUE mod;        /* modulus REDC is computing with */
  54. X    ZVALUE inv;        /* inverse of modulus in binary modulus */
  55. X    ZVALUE one;        /* REDC format for the number 1 */
  56. X} REDC;
  57. X
  58. Xextern REDC *zredcalloc MATH_PROTO((ZVALUE z1));
  59. Xextern void zredcfree MATH_PROTO((REDC *rp));
  60. Xextern void zredcencode MATH_PROTO((REDC *rp, ZVALUE z1, ZVALUE *res));
  61. Xextern void zredcdecode MATH_PROTO((REDC *rp, ZVALUE z1, ZVALUE *res));
  62. Xextern void zredcmul MATH_PROTO((REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res));
  63. Xextern void zredcsquare MATH_PROTO((REDC *rp, ZVALUE z1, ZVALUE *res));
  64. Xextern void zredcpower MATH_PROTO((REDC *rp, ZVALUE z1, ZVALUE z2, ZVALUE *res));
  65. X
  66. X
  67. X/*
  68. X * macro expansions to speed this thing up
  69. X */
  70. X#define ziseven(z)    (!(*(z).v & 01))
  71. X#define zisodd(z)    (*(z).v & 01)
  72. X#define ziszero(z)    ((*(z).v == 0) && ((z).len == 1))
  73. X#define zisneg(z)    ((z).sign)
  74. X#define zispos(z)    (((z).sign == 0) && (*(z).v || ((z).len > 1)))
  75. X#define zisunit(z)    ((*(z).v == 1) && ((z).len == 1))
  76. X#define zisone(z)    ((*(z).v == 1) && ((z).len == 1) && !(z).sign)
  77. X#define zisnegone(z)    ((*(z).v == 1) && ((z).len == 1) && (z).sign)
  78. X#define zistwo(z)    ((*(z).v == 2) && ((z).len == 1) && !(z).sign)
  79. X#define zisleone(z)    ((*(z).v <= 1) && ((z).len == 1))
  80. X#define zistiny(z)    ((z).len == 1)
  81. X#define zissmall(z)    (((z).len < 2) || (((z).len == 2) && (((short)(z).v[1]) >= 0)))
  82. X#define zisbig(z)    (((z).len > 2) || (((z).len == 2) && (((short)(z).v[1]) < 0)))
  83. X
  84. X#define z1tol(z)    ((long)((z).v[0]))
  85. X#define z2tol(z)    (((long)((z).v[0])) + \
  86. X                (((long)((z).v[1] & MAXHALF)) << BASEB))
  87. X#define    zclearval(z)    memset((z).v, 0, (z).len * sizeof(HALF))
  88. X#define    zcopyval(z1,z2)    memcpy((z2).v, (z1).v, (z1).len * sizeof(HALF))
  89. X#define zquicktrim(z)    {if (((z).len > 1) && ((z).v[(z).len-1] == 0)) \
  90. X                (z).len--;}
  91. X#define    zfree(z)    freeh((z).v)
  92. X
  93. X
  94. X/*
  95. X * Output modes for numeric displays.
  96. X */
  97. X#define MODE_DEFAULT    0
  98. X#define MODE_FRAC    1
  99. X#define MODE_INT    2
  100. X#define MODE_REAL    3
  101. X#define MODE_EXP    4
  102. X#define MODE_HEX    5
  103. X#define MODE_OCTAL    6
  104. X#define MODE_BINARY    7
  105. X#define MODE_MAX    7
  106. X
  107. X#define MODE_INITIAL    MODE_REAL
  108. X
  109. X
  110. X/*
  111. X * Output routines for either FILE handles or strings.
  112. X */
  113. Xextern void math_chr MATH_PROTO((int ch));
  114. Xextern void math_str MATH_PROTO((char *str));
  115. Xextern void math_fill MATH_PROTO((char *str, long width));
  116. Xextern void math_flush MATH_PROTO((void));
  117. Xextern void math_divertio MATH_PROTO((void));
  118. Xextern void math_cleardiversions MATH_PROTO((void));
  119. Xextern void math_setfp MATH_PROTO((FILE *fp));
  120. Xextern char *math_getdivertedio MATH_PROTO((void));
  121. Xextern int math_setmode MATH_PROTO((int mode));
  122. Xextern long math_setdigits MATH_PROTO((long digits));
  123. X
  124. X
  125. X#ifdef VARARGS
  126. Xextern void math_fmt();
  127. X#else
  128. Xextern void math_fmt MATH_PROTO((char *, ...));
  129. X#endif
  130. X
  131. X
  132. X/*
  133. X * The error routine.
  134. X */
  135. X#ifdef VARARGS
  136. Xextern void math_error();
  137. X#else
  138. Xextern void math_error MATH_PROTO((char *, ...));
  139. X#endif
  140. X
  141. X
  142. X/*
  143. X * constants used often by the arithmetic routines
  144. X */
  145. Xextern HALF _zeroval_[], _oneval_[], _twoval_[], _tenval_[];
  146. Xextern ZVALUE _zero_, _one_, _ten_;
  147. X
  148. Xextern BOOL _math_abort_;    /* nonzero to abort calculations */
  149. Xextern ZVALUE _tenpowers_[32];    /* table of 10^2^n */
  150. Xextern int _outmode_;        /* current output mode */
  151. Xextern LEN _mul2_;        /* size of number to use multiply algorithm 2 */
  152. Xextern LEN _sq2_;        /* size of number to use square algorithm 2 */
  153. Xextern LEN _pow2_;        /* size of modulus to use REDC for powers */
  154. Xextern LEN _redc2_;        /* size of modulus to use REDC algorithm 2 */
  155. Xextern HALF *bitmask;        /* bit rotation, norm 0 */
  156. X
  157. X#endif
  158. X
  159. X/* END CODE */
  160. SHAR_EOF
  161. echo "File calc2.9.0/zmath.h is complete"
  162. chmod 0644 calc2.9.0/zmath.h || echo "restore of calc2.9.0/zmath.h fails"
  163. set `wc -c calc2.9.0/zmath.h`;Sum=$1
  164. if test "$Sum" != "11814"
  165. then echo original size 11814, current size $Sum;fi
  166. echo "x - extracting calc2.9.0/zmod.c (Text)"
  167. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/zmod.c &&
  168. X/*
  169. X * Copyright (c) 1993 David I. Bell
  170. X * Permission is granted to use, distribute, or modify this source,
  171. X * provided that this copyright notice remains intact.
  172. X *
  173. X * Routines to do modulo arithmetic both normally and also using the REDC
  174. X * algorithm given by Peter L. Montgomery in Mathematics of Computation,
  175. X * volume 44, number 170 (April, 1985).  For multiple multiplies using
  176. X * the same large modulus, the REDC algorithm avoids the usual division
  177. X * by the modulus, instead replacing it with two multiplies or else a
  178. X * special algorithm.  When these two multiplies or the special algorithm
  179. X * are faster then the division, then the REDC algorithm is better.
  180. X */
  181. X
  182. X#include "zmath.h"
  183. X
  184. X
  185. X#define    POWBITS    4        /* bits for power chunks (must divide BASEB) */
  186. X#define    POWNUMS    (1<<POWBITS)    /* number of powers needed in table */
  187. X
  188. X
  189. XLEN _pow2_ = POW_ALG2;        /* modulo size to use REDC for powers */
  190. XLEN _redc2_ = REDC_ALG2;    /* modulo size to use second REDC algorithm */
  191. X
  192. Xstatic REDC *powermodredc = NULL;    /* REDC info for raising to power */
  193. X
  194. X#if 0
  195. Xextern void zaddmod MATH_PROTO((ZVALUE z1, ZVALUE z2, ZVALUE z3, ZVALUE *res));
  196. Xextern void znegmod MATH_PROTO((ZVALUE z1, ZVALUE z2, ZVALUE *res));
  197. X
  198. X/*
  199. X * Multiply two numbers together and then mod the result with a third number.
  200. X * The two numbers to be multiplied can be negative or out of modulo range.
  201. X * The result will be in the range 0 to the modulus - 1.
  202. X */
  203. Xvoid
  204. Xzmulmod(z1, z2, z3, res)
  205. X    ZVALUE z1;        /* first number to be multiplied */
  206. X    ZVALUE z2;        /* second number to be multiplied */
  207. X    ZVALUE z3;        /* number to take mod with */
  208. X    ZVALUE *res;        /* result */
  209. X{
  210. X    ZVALUE tmp;
  211. X    FULL prod;
  212. X    FULL digit;
  213. X    BOOL neg;
  214. X
  215. X    if (ziszero(z3) || zisneg(z3))
  216. X        math_error("Mod of non-positive integer");
  217. X    if (ziszero(z1) || ziszero(z2) || zisunit(z3)) {
  218. X        *res = _zero_;
  219. X        return;
  220. X    }
  221. X
  222. X    /*
  223. X     * If the modulus is a single digit number, then do the result
  224. X     * cheaply.  Check especially for a small power of two.
  225. X     */
  226. X    if (zistiny(z3)) {
  227. X        neg = (z1.sign != z2.sign);
  228. X        digit = z3.v[0];
  229. X        if ((digit & -digit) == digit) {    /* NEEDS 2'S COMP */
  230. X            prod = ((FULL) z1.v[0]) * ((FULL) z2.v[0]);
  231. X            prod &= (digit - 1);
  232. X        } else {
  233. X            z1.sign = 0;
  234. X            z2.sign = 0;
  235. X            prod = (FULL) zmodi(z1, (long) digit);
  236. X            prod *= (FULL) zmodi(z2, (long) digit);
  237. X            prod %= digit;
  238. X        }
  239. X        if (neg && prod)
  240. X            prod = digit - prod;
  241. X        itoz((long) prod, res);
  242. X        return;
  243. X    }
  244. X
  245. X    /*
  246. X     * The modulus is more than one digit.
  247. X     * Actually do the multiply and divide if necessary.
  248. X     */
  249. X    zmul(z1, z2, &tmp);
  250. X    if (zispos(tmp) && ((tmp.len < z3.len) || ((tmp.len == z3.len) &&
  251. X        (tmp.v[tmp.len-1] < z2.v[z3.len-1]))))
  252. X    {
  253. X        *res = tmp;
  254. X        return;
  255. X    }
  256. X    zmod(tmp, z3, res);
  257. X    zfree(tmp);
  258. X}
  259. X
  260. X
  261. X/*
  262. X * Square a number and then mod the result with a second number.
  263. X * The number to be squared can be negative or out of modulo range.
  264. X * The result will be in the range 0 to the modulus - 1.
  265. X */
  266. Xvoid
  267. Xzsquaremod(z1, z2, res)
  268. X    ZVALUE z1;        /* number to be squared */
  269. X    ZVALUE z2;        /* number to take mod with */
  270. X    ZVALUE *res;        /* result */
  271. X{
  272. X    ZVALUE tmp;
  273. X    FULL prod;
  274. X    FULL digit;
  275. X
  276. X    if (ziszero(z2) || zisneg(z2))
  277. X        math_error("Mod of non-positive integer");
  278. X    if (ziszero(z1) || zisunit(z2)) {
  279. X        *res = _zero_;
  280. X        return;
  281. X    }
  282. X
  283. X    /*
  284. X     * If the modulus is a single digit number, then do the result
  285. X     * cheaply.  Check especially for a small power of two.
  286. X     */
  287. X    if (zistiny(z2)) {
  288. X        digit = z2.v[0];
  289. X        if ((digit & -digit) == digit) {    /* NEEDS 2'S COMP */
  290. X            prod = (FULL) z1.v[0];
  291. X            prod = (prod * prod) & (digit - 1);
  292. X        } else {
  293. X            z1.sign = 0;
  294. X            prod = (FULL) zmodi(z1, (long) digit);
  295. X            prod = (prod * prod) % digit;
  296. X        }
  297. X        itoz((long) prod, res);
  298. X        return;
  299. X    }
  300. X
  301. X    /*
  302. X     * The modulus is more than one digit.
  303. X     * Actually do the square and divide if necessary.
  304. X     */
  305. X    zsquare(z1, &tmp);
  306. X    if ((tmp.len < z2.len) ||
  307. X        ((tmp.len == z2.len) && (tmp.v[tmp.len-1] < z2.v[z2.len-1]))) {
  308. X            *res = tmp;
  309. X            return;
  310. X    }
  311. X    zmod(tmp, z2, res);
  312. X    zfree(tmp);
  313. X}
  314. X
  315. X
  316. X/*
  317. X * Add two numbers together and then mod the result with a third number.
  318. X * The two numbers to be added can be negative or out of modulo range.
  319. X * The result will be in the range 0 to the modulus - 1.
  320. X */
  321. Xstatic void
  322. Xzaddmod(z1, z2, z3, res)
  323. X    ZVALUE z1;        /* first number to be added */
  324. X    ZVALUE z2;        /* second number to be added */
  325. X    ZVALUE z3;        /* number to take mod with */
  326. X    ZVALUE *res;        /* result */
  327. X{
  328. X    ZVALUE tmp;
  329. X    FULL sumdigit;
  330. X    FULL moddigit;
  331. X
  332. X    if (ziszero(z3) || zisneg(z3))
  333. X        math_error("Mod of non-positive integer");
  334. X    if ((ziszero(z1) && ziszero(z2)) || zisunit(z3)) {
  335. X        *res = _zero_;
  336. X        return;
  337. X    }
  338. X    if (zistwo(z2)) {
  339. X        if ((z1.v[0] + z2.v[0]) & 0x1)
  340. X            *res = _one_;
  341. X        else
  342. X            *res = _zero_;
  343. X        return;
  344. X    }
  345. X    zadd(z1, z2, &tmp);
  346. X    if (zisneg(tmp) || (tmp.len > z3.len)) {
  347. X        zmod(tmp, z3, res);
  348. X        zfree(tmp);
  349. X        return;
  350. X    }
  351. X    sumdigit = tmp.v[tmp.len - 1];
  352. X    moddigit = z3.v[z3.len - 1];
  353. X    if ((tmp.len < z3.len) || (sumdigit < moddigit)) {
  354. X        *res = tmp;
  355. X        return;
  356. X    }
  357. X    if (sumdigit < 2 * moddigit) {
  358. X        zsub(tmp, z3, res);
  359. X        zfree(tmp);
  360. X        return;
  361. X    }
  362. X    zmod(tmp, z2, res);
  363. X    zfree(tmp);
  364. X}
  365. X
  366. X
  367. X/*
  368. X * Subtract two numbers together and then mod the result with a third number.
  369. X * The two numbers to be subtract can be negative or out of modulo range.
  370. X * The result will be in the range 0 to the modulus - 1.
  371. X */
  372. Xvoid
  373. Xzsubmod(z1, z2, z3, res)
  374. X    ZVALUE z1;        /* number to be subtracted from */
  375. X    ZVALUE z2;        /* number to be subtracted */
  376. X    ZVALUE z3;        /* number to take mod with */
  377. X    ZVALUE *res;        /* result */
  378. X{
  379. X    if (ziszero(z3) || zisneg(z3))
  380. X        math_error("Mod of non-positive integer");
  381. X    if (ziszero(z2)) {
  382. X        zmod(z1, z3, res);
  383. X        return;
  384. X    }
  385. X    if (ziszero(z1)) {
  386. X        znegmod(z2, z3, res);
  387. X        return;
  388. X    }
  389. X    if ((z1.sign == z2.sign) && (z1.len == z2.len) &&
  390. X        (z1.v[0] == z2.v[0]) && (zcmp(z1, z2) == 0)) {
  391. X            *res = _zero_;
  392. X            return;
  393. X    }
  394. X    z2.sign = !z2.sign;
  395. X    zaddmod(z1, z2, z3, res);
  396. X}
  397. X
  398. X
  399. X/*
  400. X * Calculate the negative of a number modulo another number.
  401. X * The number to be negated can be negative or out of modulo range.
  402. X * The result will be in the range 0 to the modulus - 1.
  403. X */
  404. Xstatic void
  405. Xznegmod(z1, z2, res)
  406. X    ZVALUE z1;        /* number to take negative of */
  407. X    ZVALUE z2;        /* number to take mod with */
  408. X    ZVALUE *res;        /* result */
  409. X{
  410. X    int sign;
  411. X    int cv;
  412. X
  413. X    if (ziszero(z2) || zisneg(z2))
  414. X        math_error("Mod of non-positive integer");
  415. X    if (ziszero(z1) || zisunit(z2)) {
  416. X        *res = _zero_;
  417. X        return;
  418. X    }
  419. X    if (zistwo(z2)) {
  420. X        if (z1.v[0] & 0x1)
  421. X            *res = _one_;
  422. X        else
  423. X            *res = _zero_;
  424. X        return;
  425. X    }
  426. X
  427. X    /*
  428. X     * If the absolute value of the number is within the modulo range,
  429. X     * then the result is just a copy or a subtraction.  Otherwise go
  430. X     * ahead and negate and reduce the result.
  431. X     */
  432. X    sign = z1.sign;
  433. X    z1.sign = 0;
  434. X    cv = zrel(z1, z2);
  435. X    if (cv == 0) {
  436. X        *res = _zero_;
  437. X        return;
  438. X    }
  439. X    if (cv < 0) {
  440. X        if (sign)
  441. X            zcopy(z1, res);
  442. X        else
  443. X            zsub(z2, z1, res);
  444. X        return;
  445. X    }
  446. X    z1.sign = !sign;
  447. X    zmod(z1, z2, res);
  448. X}
  449. X#endif
  450. X
  451. X
  452. X/*
  453. X * Calculate the number congruent to the given number whose absolute
  454. X * value is minimal.  The number to be reduced can be negative or out of
  455. X * modulo range.  The result will be within the range -int((modulus-1)/2)
  456. X * to int(modulus/2) inclusive.  For example, for modulus 7, numbers are
  457. X * reduced to the range [-3, 3], and for modulus 8, numbers are reduced to
  458. X * the range [-3, 4].
  459. X */
  460. Xvoid
  461. Xzminmod(z1, z2, res)
  462. X    ZVALUE z1;        /* number to find minimum congruence of */
  463. X    ZVALUE z2;        /* number to take mod with */
  464. X    ZVALUE *res;        /* result */
  465. X{
  466. X    ZVALUE tmp1, tmp2;
  467. X    int sign;
  468. X    int cv;
  469. X
  470. X    if (ziszero(z2) || zisneg(z2))
  471. X        math_error("Mod of non-positive integer");
  472. X    if (ziszero(z1) || zisunit(z2)) {
  473. X        *res = _zero_;
  474. X        return;
  475. X    }
  476. X    if (zistwo(z2)) {
  477. X        if (zisodd(z1))
  478. X            *res = _one_;
  479. X        else
  480. X            *res = _zero_;
  481. X        return;
  482. X    }
  483. X
  484. X    /*
  485. X     * Do a quick check to see if the number is very small compared
  486. X     * to the modulus.  If so, then the result is obvious.
  487. X     */
  488. X    if (z1.len < z2.len - 1) {
  489. X        zcopy(z1, res);
  490. X        return;
  491. X    }
  492. X
  493. X    /*
  494. X     * Now make sure the input number is within the modulo range.
  495. X     * If not, then reduce it to be within range and make the
  496. X     * quick check again.
  497. X     */
  498. X    sign = z1.sign;
  499. X    z1.sign = 0;
  500. X    cv = zrel(z1, z2);
  501. X    if (cv == 0) {
  502. X        *res = _zero_;
  503. X        return;
  504. X    }
  505. X    tmp1 = z1;
  506. X    if (cv > 0) {
  507. X        z1.sign = (BOOL)sign;
  508. X        zmod(z1, z2, &tmp1);
  509. X        if (tmp1.len < z2.len - 1) {
  510. X            *res = tmp1;
  511. X            return;
  512. X        }
  513. X        sign = 0;
  514. X    }
  515. X
  516. X    /*
  517. X     * Now calculate the difference of the modulus and the absolute
  518. X     * value of the original number.  Compare the original number with
  519. X     * the difference, and return the one with the smallest absolute
  520. X     * value, with the correct sign.  If the two values are equal, then
  521. X     * return the positive result.
  522. X     */
  523. X    zsub(z2, tmp1, &tmp2);
  524. X    cv = zrel(tmp1, tmp2);
  525. X    if (cv < 0) {
  526. X        zfree(tmp2);
  527. X        tmp1.sign = (BOOL)sign;
  528. X        if (tmp1.v == z1.v)
  529. X            zcopy(tmp1, res);
  530. X        else
  531. X            *res = tmp1;
  532. X    } else {
  533. X        if (cv)
  534. X            tmp2.sign = !sign;
  535. X        if (tmp1.v != z1.v)
  536. X            zfree(tmp1);
  537. X        *res = tmp2;
  538. X    }
  539. X}
  540. X
  541. X
  542. X/*
  543. X * Compare two numbers for equality modulo a third number.
  544. X * The two numbers to be compared can be negative or out of modulo range.
  545. X * Returns TRUE if the numbers are not congruent, and FALSE if they are
  546. X * congruent.
  547. X */
  548. XBOOL
  549. Xzcmpmod(z1, z2, z3)
  550. X    ZVALUE z1;        /* first number to be compared */
  551. X    ZVALUE z2;        /* second number to be compared */
  552. X    ZVALUE z3;        /* modulus */
  553. X{
  554. X    ZVALUE tmp1, tmp2, tmp3;
  555. X    FULL digit;
  556. X    LEN len;
  557. X    int cv;
  558. X
  559. X    if (zisneg(z3) || ziszero(z3))
  560. X        math_error("Non-positive modulus in zcmpmod");
  561. X    if (zistwo(z3))
  562. X        return (((z1.v[0] + z2.v[0]) & 0x1) != 0);
  563. X
  564. X    /*
  565. X     * If the two numbers are equal, then their mods are equal.
  566. X     */
  567. X    if ((z1.sign == z2.sign) && (z1.len == z2.len) &&
  568. X        (z1.v[0] == z2.v[0]) && (zcmp(z1, z2) == 0))
  569. X            return FALSE;
  570. X
  571. X    /*
  572. X     * If both numbers are negative, then we can make them positive.
  573. X     */
  574. X    if (zisneg(z1) && zisneg(z2)) {
  575. X        z1.sign = 0;
  576. X        z2.sign = 0;
  577. X    }
  578. X
  579. X    /*
  580. X     * For small negative numbers, make them positive before comparing.
  581. X     * In any case, the resulting numbers are in tmp1 and tmp2.
  582. X     */
  583. X    tmp1 = z1;
  584. X    tmp2 = z2;
  585. X    len = z3.len;
  586. X    digit = z3.v[len - 1];
  587. X
  588. X    if (zisneg(z1) && ((z1.len < len) ||
  589. X        ((z1.len == len) && (z1.v[z1.len - 1] < digit))))
  590. X            zadd(z1, z3, &tmp1);
  591. X
  592. X    if (zisneg(z2) && ((z2.len < len) ||
  593. X        ((z2.len == len) && (z2.v[z2.len - 1] < digit))))
  594. X            zadd(z2, z3, &tmp2);
  595. X
  596. X    /*
  597. X     * Now compare the two numbers for equality.
  598. X     * If they are equal we are all done.
  599. X     */
  600. X    if (zcmp(tmp1, tmp2) == 0) {
  601. X        if (tmp1.v != z1.v)
  602. X            zfree(tmp1);
  603. X        if (tmp2.v != z2.v)
  604. X            zfree(tmp2);
  605. X        return FALSE;
  606. X    }
  607. X
  608. X    /*
  609. X     * They are not identical.  Now if both numbers are positive
  610. X     * and less than the modulus, then they are definitely not equal.
  611. X     */
  612. X    if ((tmp1.sign == tmp2.sign) &&
  613. X        ((tmp1.len < len) || (zrel(tmp1, z3) < 0)) &&
  614. X        ((tmp2.len < len) || (zrel(tmp2, z3) < 0)))
  615. X    {
  616. X        if (tmp1.v != z1.v)
  617. X            zfree(tmp1);
  618. X        if (tmp2.v != z2.v)
  619. X            zfree(tmp2);
  620. X        return TRUE;
  621. X    }
  622. X
  623. X    /*
  624. X     * Either one of the numbers is negative or is large.
  625. X     * So do the standard thing and subtract the two numbers.
  626. X     * Then they are equal if the result is 0 (mod z3).
  627. X     */
  628. X    zsub(tmp1, tmp2, &tmp3);
  629. X    if (tmp1.v != z1.v)
  630. X        zfree(tmp1);
  631. X    if (tmp2.v != z2.v)
  632. X        zfree(tmp2);
  633. X
  634. X    /*
  635. X     * Compare the result with the modulus to see if it is equal to
  636. X     * or less than the modulus.  If so, we know the mod result.
  637. X     */
  638. X    tmp3.sign = 0;
  639. X    cv = zrel(tmp3, z3);
  640. X    if (cv == 0) {
  641. X        zfree(tmp3);
  642. X        return FALSE;
  643. X    }
  644. X    if (cv < 0) {
  645. X        zfree(tmp3);
  646. X        return TRUE;
  647. X    }
  648. X
  649. X    /*
  650. X     * We are forced to actually do the division.
  651. X     * The numbers are congruent if the result is zero.
  652. X     */
  653. X    zmod(tmp3, z3, &tmp1);
  654. X    zfree(tmp3);
  655. X    if (ziszero(tmp1)) {
  656. X        zfree(tmp1);
  657. X        return FALSE;
  658. X    } else {
  659. X        zfree(tmp1);
  660. X        return TRUE;
  661. X    }
  662. X}
  663. X
  664. X
  665. X/*
  666. X * Compute the result of raising one number to a power modulo another number.
  667. X * That is, this computes:  a^b (modulo c).
  668. X * This calculates the result by examining the power POWBITS bits at a time,
  669. X * using a small table of POWNUMS low powers to calculate powers for those bits,
  670. X * and repeated squaring and multiplying by the partial powers to generate
  671. X * the complete power.  If the power being raised to is high enough, then
  672. X * this uses the REDC algorithm to avoid doing many divisions.  When using
  673. X * REDC, multiple calls to this routine using the same modulus will be
  674. X * slightly faster.
  675. X */
  676. Xvoid
  677. Xzpowermod(z1, z2, z3, res)
  678. X    ZVALUE z1, z2, z3, *res;
  679. X{
  680. X    HALF *hp;        /* pointer to current word of the power */
  681. X    REDC *rp;        /* REDC information to be used */
  682. X    ZVALUE *pp;        /* pointer to low power table */
  683. X    ZVALUE ans, temp;    /* calculation values */
  684. X    ZVALUE modpow;        /* current small power */
  685. X    ZVALUE lowpowers[POWNUMS];    /* low powers */
  686. X    int sign;        /* original sign of number */
  687. X    int curshift;        /* shift value for word of power */
  688. X    HALF curhalf;        /* current word of power */
  689. X    unsigned int curpow;    /* current low power */
  690. X    unsigned int curbit;    /* current bit of low power */
  691. X    int i;
  692. X
  693. X    if (zisneg(z3) || ziszero(z3))
  694. X        math_error("Non-positive modulus in zpowermod");
  695. X    if (zisneg(z2))
  696. X        math_error("Negative power in zpowermod");
  697. X
  698. X    sign = z1.sign;
  699. X    z1.sign = 0;
  700. X
  701. X    /*
  702. X     * Check easy cases first.
  703. X     */
  704. X    if (ziszero(z1) || zisunit(z3)) {    /* 0^x or mod 1 */
  705. X        *res = _zero_;
  706. X        return;
  707. X    }
  708. X    if (zistwo(z3)) {            /* mod 2 */
  709. X        if (zisodd(z1))
  710. X            *res = _one_;
  711. X        else
  712. X            *res = _zero_;
  713. X        return;
  714. X    }
  715. X    if (zisunit(z1) && (!sign || ziseven(z2))) {
  716. X        /* 1^x or (-1)^(2x) */
  717. X        *res = _one_;
  718. X        return;
  719. X    }
  720. X
  721. X    /*
  722. X     * Normalize the number being raised to be non-negative and to lie
  723. X     * within the modulo range.  Then check for zero or one specially.
  724. X     */
  725. X    zmod(z1, z3, &temp);
  726. X    if (ziszero(temp)) {
  727. X        zfree(temp);
  728. X        *res = _zero_;
  729. X        return;
  730. X    }
  731. X    z1 = temp;
  732. X    if (sign) {
  733. X        zsub(z3, z1, &temp);
  734. X        zfree(z1);
  735. X        z1 = temp;
  736. X    }
  737. X    if (zisunit(z1)) {
  738. X        zfree(z1);
  739. X        *res = _one_;
  740. X        return;
  741. X    }
  742. X
  743. X    /*
  744. X     * If the modulus is odd, large enough, is not one less than an
  745. X     * exact power of two, and if the power is large enough, then use
  746. X     * the REDC algorithm.  The size where this is done is configurable.
  747. X     */
  748. X    if ((z2.len > 1) && (z3.len >= _pow2_) && zisodd(z3)
  749. X        && !zisallbits(z3))
  750. X    {
  751. X        if (powermodredc && zcmp(powermodredc->mod, z3)) {
  752. X            zredcfree(powermodredc);
  753. X            powermodredc = NULL;
  754. X        }
  755. X        if (powermodredc == NULL)
  756. X            powermodredc = zredcalloc(z3);
  757. X        rp = powermodredc;
  758. X        zredcencode(rp, z1, &temp);
  759. X        zredcpower(rp, temp, z2, &z1);
  760. X        zfree(temp);
  761. X        zredcdecode(rp, z1, res);
  762. X        zfree(z1);
  763. X        return;
  764. X    }
  765. X
  766. X    /*
  767. X     * Modulus or power is small enough to perform the power raising
  768. X     * directly.  Initialize the table of powers.
  769. X     */
  770. X    for (pp = &lowpowers[2]; pp < &lowpowers[POWNUMS]; pp++)
  771. X        pp->len = 0;
  772. X    lowpowers[0] = _one_;
  773. X    lowpowers[1] = z1;
  774. X    ans = _one_;
  775. X
  776. X    hp = &z2.v[z2.len - 1];
  777. X    curhalf = *hp;
  778. X    curshift = BASEB - POWBITS;
  779. X    while (curshift && ((curhalf >> curshift) == 0))
  780. X        curshift -= POWBITS;
  781. X
  782. X    /*
  783. X     * Calculate the result by examining the power POWBITS bits at a time,
  784. X     * and use the table of low powers at each iteration.
  785. X     */
  786. X    for (;;) {
  787. X        curpow = (curhalf >> curshift) & (POWNUMS - 1);
  788. X        pp = &lowpowers[curpow];
  789. X
  790. X        /*
  791. X         * If the small power is not yet saved in the table, then
  792. X         * calculate it and remember it in the table for future use.
  793. X         */
  794. X        if (pp->len == 0) {
  795. X            if (curpow & 0x1)
  796. X                zcopy(z1, &modpow);
  797. X            else
  798. X                modpow = _one_;
  799. X
  800. X            for (curbit = 0x2; curbit <= curpow; curbit *= 2) {
  801. X                pp = &lowpowers[curbit];
  802. X                if (pp->len == 0) {
  803. X                    zsquare(lowpowers[curbit/2], &temp);
  804. X                    zmod(temp, z3, pp);
  805. X                    zfree(temp);
  806. X                }
  807. X                if (curbit & curpow) {
  808. X                    zmul(*pp, modpow, &temp);
  809. X                    zfree(modpow);
  810. X                    zmod(temp, z3, &modpow);
  811. X                    zfree(temp);
  812. X                }
  813. X            }
  814. X            pp = &lowpowers[curpow];
  815. X            *pp = modpow;
  816. X        }
  817. X
  818. X        /*
  819. X         * If the power is nonzero, then accumulate the small power
  820. X         * into the result.
  821. X         */
  822. X        if (curpow) {
  823. X            zmul(ans, *pp, &temp);
  824. X            zfree(ans);
  825. X            zmod(temp, z3, &ans);
  826. X            zfree(temp);
  827. X        }
  828. X
  829. X        /*
  830. X         * Select the next POWBITS bits of the power, if there is
  831. X         * any more to generate.
  832. X         */
  833. X        curshift -= POWBITS;
  834. X        if (curshift < 0) {
  835. X            if (hp-- == z2.v)
  836. X                break;
  837. X            curhalf = *hp;
  838. X            curshift = BASEB - POWBITS;
  839. X        }
  840. X
  841. X        /*
  842. X         * Square the result POWBITS times to make room for the next
  843. X         * chunk of bits.
  844. X         */
  845. X        for (i = 0; i < POWBITS; i++) {
  846. X            zsquare(ans, &temp);
  847. X            zfree(ans);
  848. X            zmod(temp, z3, &ans);
  849. X            zfree(temp);
  850. X        }
  851. X    }
  852. X
  853. X    for (pp = &lowpowers[2]; pp < &lowpowers[POWNUMS]; pp++) {
  854. X        if (pp->len)
  855. X            freeh(pp->v);
  856. X    }
  857. X    *res = ans;
  858. X}
  859. X
  860. X
  861. X/*
  862. X * Initialize the REDC algorithm for a particular modulus,
  863. X * returning a pointer to a structure that is used for other
  864. X * REDC calls.  An error is generated if the structure cannot
  865. X * be allocated.  The modulus must be odd and positive.
  866. X */
  867. XREDC *
  868. Xzredcalloc(z1)
  869. X    ZVALUE z1;        /* modulus to initialize for */
  870. X{
  871. X    REDC *rp;        /* REDC information */
  872. X    ZVALUE tmp;
  873. X    long bit;
  874. X
  875. X    if (ziseven(z1) || zisneg(z1))
  876. X        math_error("REDC requires positive odd modulus");
  877. X
  878. X    rp = (REDC *) malloc(sizeof(REDC));
  879. X    if (rp == NULL)
  880. X        math_error("Cannot allocate REDC structure");
  881. X
  882. X    /*
  883. X     * Round up the binary modulus to the next power of two
  884. X     * which is at a word boundary.  Then the shift and modulo
  885. X     * operations mod the binary modulus can be done very cheaply.
  886. X     * Calculate the REDC format for the number 1 for future use.
  887. X     */
  888. X    bit = zhighbit(z1) + 1;
  889. X    if (bit % BASEB)
  890. X        bit += (BASEB - (bit % BASEB));
  891. X    zcopy(z1, &rp->mod);
  892. X    zbitvalue(bit, &tmp);
  893. X    z1.sign = 1;
  894. X    (void) zmodinv(z1, tmp, &rp->inv);
  895. X    zmod(tmp, rp->mod, &rp->one);
  896. X    zfree(tmp);
  897. X    rp->len = bit / BASEB;
  898. X    return rp;
  899. X}
  900. X
  901. X
  902. X/*
  903. X * Free any numbers associated with the specified REDC structure,
  904. X * and then the REDC structure itself.
  905. X */
  906. Xvoid
  907. Xzredcfree(rp)
  908. X    REDC *rp;        /* REDC information to be cleared */
  909. X{
  910. X    zfree(rp->mod);
  911. X    zfree(rp->inv);
  912. X    zfree(rp->one);
  913. X    free(rp);
  914. X}
  915. X
  916. X
  917. X/*
  918. X * Convert a normal number into the specified REDC format.
  919. X * The number to be converted can be negative or out of modulo range.
  920. X * The resulting number can be used for multiplying, adding, subtracting,
  921. X * or comparing with any other such converted numbers, as if the numbers
  922. X * were being calculated modulo the number which initialized the REDC
  923. X * information.  When the final value is unconverted, the result is the
  924. X * same as if the usual operations were done with the original numbers.
  925. X */
  926. Xvoid
  927. Xzredcencode(rp, z1, res)
  928. X    REDC *rp;        /* REDC information */
  929. X    ZVALUE z1;        /* number to be converted */
  930. X    ZVALUE *res;        /* returned converted number */
  931. X{
  932. X    ZVALUE tmp1, tmp2;
  933. X
  934. X    /*
  935. X     * Handle the cases 0, 1, -1, and 2 specially since these are
  936. X     * easy to calculate.  Zero transforms to zero, and the others
  937. X     * can be obtained from the precomputed REDC format for 1 since
  938. X     * addition and subtraction act normally for REDC format numbers.
  939. X     */
  940. X    if (ziszero(z1)) {
  941. X        *res = _zero_;
  942. X        return;
  943. X    }
  944. X    if (zisone(z1)) {
  945. X        zcopy(rp->one, res);
  946. X        return;
  947. X    }
  948. X    if (zisunit(z1)) {
  949. X        zsub(rp->mod, rp->one, res);
  950. X        return;
  951. X    }
  952. X    if (zistwo(z1)) {
  953. X        zadd(rp->one, rp->one, &tmp1);
  954. X        if (zrel(tmp1, rp->mod) < 0) {
  955. X            *res = tmp1;
  956. X            return;
  957. X        }
  958. X        zsub(tmp1, rp->mod, res);
  959. X        zfree(tmp1);
  960. X        return;
  961. X    }
  962. X
  963. X    /*
  964. X     * Not a trivial number to convert, so do the full transformation.
  965. X     * Convert negative numbers to positive numbers before converting.
  966. X     */
  967. X    tmp1.len = 0;
  968. X    if (zisneg(z1)) {
  969. X        zmod(z1, rp->mod, &tmp1);
  970. X        z1 = tmp1;
  971. X    }
  972. X    zshift(z1, rp->len * BASEB, &tmp2);
  973. X    if (tmp1.len)
  974. X        zfree(tmp1);
  975. X    zmod(tmp2, rp->mod, res);
  976. X    zfree(tmp2);
  977. X}
  978. X
  979. X
  980. X/*
  981. X * The REDC algorithm used to convert numbers out of REDC format and also
  982. X * used after multiplication of two REDC numbers.  Using this routine
  983. X * avoids any divides, replacing the divide by two multiplications.
  984. X * If the numbers are very large, then these two multiplies will be
  985. X * quicker than the divide, since dividing is harder than multiplying.
  986. X */
  987. Xvoid
  988. Xzredcdecode(rp, z1, res)
  989. X    REDC *rp;        /* REDC information */
  990. X    ZVALUE z1;        /* number to be transformed */
  991. X    ZVALUE *res;        /* returned transformed number */
  992. X{
  993. X    ZVALUE tmp1, tmp2;    /* temporaries */
  994. X    HALF *hp;        /* saved pointer to tmp2 value */
  995. X
  996. X    if (zisneg(z1))
  997. X        math_error("Negative number for zredc");
  998. X
  999. X    /*
  1000. X     * Check first for the special values for 0 and 1 that are easy.
  1001. X     */
  1002. X    if (ziszero(z1)) {
  1003. X        *res = _zero_;
  1004. X        return;
  1005. X    }
  1006. X    if ((z1.len == rp->one.len) && (z1.v[0] == rp->one.v[0]) &&
  1007. X        (zcmp(z1, rp->one) == 0)) {
  1008. X            *res = _one_;
  1009. X            return;
  1010. X    }
  1011. X
  1012. X    /*
  1013. X     * First calculate the following:
  1014. X     *     tmp2 = ((z1 % 2^bitnum) * inv) % 2^bitnum.
  1015. X     * The mod operations can be done with no work since the bit
  1016. X     * number was selected as a multiple of the word size.  Just
  1017. X     * reduce the sizes of the numbers as required.
  1018. X     */
  1019. X    tmp1 = z1;
  1020. X    if (tmp1.len > rp->len)
  1021. X        tmp1.len = rp->len;
  1022. X    zmul(tmp1, rp->inv, &tmp2);
  1023. X    if (tmp2.len > rp->len)
  1024. X        tmp2.len = rp->len;
  1025. X
  1026. X    /*
  1027. X     * Next calculate the following:
  1028. X     *    res = (z1 + tmp2 * modulus) / 2^bitnum
  1029. X     * The division by a power of 2 is always exact, and requires no
  1030. X     * work.  Just adjust the address and length of the number to do
  1031. X     * the divide, but save the original pointer for freeing later.
  1032. X     */
  1033. X    zmul(tmp2, rp->mod, &tmp1);
  1034. X    zfree(tmp2);
  1035. X    zadd(z1, tmp1, &tmp2);
  1036. X    zfree(tmp1);
  1037. X    hp = tmp2.v;
  1038. X    if (tmp2.len <= rp->len) {
  1039. X        freeh(hp);
  1040. X        *res = _zero_;
  1041. X        return;
  1042. X    }
  1043. X    tmp2.v += rp->len;
  1044. X    tmp2.len -= rp->len;
  1045. X
  1046. X    /*
  1047. X     * Finally do a final modulo by a simple subtraction if necessary.
  1048. X     * This is all that is needed because the previous calculation is
  1049. X     * guaranteed to always be less than twice the modulus.
  1050. X     */
  1051. X    if (zrel(tmp2, rp->mod) < 0)
  1052. X        zcopy(tmp2, res);
  1053. X    else
  1054. X        zsub(tmp2, rp->mod, res);
  1055. X    freeh(hp);
  1056. X}
  1057. X
  1058. X
  1059. X/*
  1060. X * Multiply two numbers in REDC format together producing a result also
  1061. X * in REDC format.  If the result is converted back to a normal number,
  1062. X * then the result is the same as the modulo'd multiplication of the
  1063. X * original numbers before they were converted to REDC format.  This
  1064. X * calculation is done in one of two ways, depending on the size of the
  1065. X * modulus.  For large numbers, the REDC definition is used directly
  1066. X * which involves three multiplies overall.  For small numbers, a
  1067. X * complicated routine is used which does the indicated multiplication
  1068. X * and the REDC algorithm at the same time to produce the result.
  1069. X */
  1070. Xvoid
  1071. Xzredcmul(rp, z1, z2, res)
  1072. X    REDC *rp;        /* REDC information */
  1073. X    ZVALUE z1;        /* first REDC number to be multiplied */
  1074. X    ZVALUE z2;        /* second REDC number to be multiplied */
  1075. X    ZVALUE *res;        /* resulting REDC number */
  1076. X{
  1077. X    FULL mulb;
  1078. X    FULL muln;
  1079. X    HALF *h1;
  1080. X    HALF *h2;
  1081. X    HALF *h3;
  1082. X    HALF *hd;
  1083. X    HALF Ninv;
  1084. X    HALF topdigit;
  1085. X    LEN modlen;
  1086. X    LEN len;
  1087. X    LEN len2;
  1088. X    SIUNION sival1;
  1089. X    SIUNION sival2;
  1090. X    SIUNION sival3;
  1091. X    SIUNION carry;
  1092. X    ZVALUE tmp;
  1093. X
  1094. X    if (zisneg(z1) || (z1.len > rp->mod.len) ||
  1095. X        zisneg(z2) || (z2.len > rp->mod.len))
  1096. X            math_error("Negative or too large number in zredcmul");
  1097. X
  1098. X    /*
  1099. X     * Check for special values which we easily know the answer.
  1100. X     */
  1101. X    if (ziszero(z1) || ziszero(z2)) {
  1102. X        *res = _zero_;
  1103. X        return;
  1104. X    }
  1105. X
  1106. X    if ((z1.len == rp->one.len) && (z1.v[0] == rp->one.v[0]) &&
  1107. X        (zcmp(z1, rp->one) == 0)) {
  1108. X            zcopy(z2, res);
  1109. X            return;
  1110. X    }
  1111. X
  1112. X    if ((z2.len == rp->one.len) && (z2.v[0] == rp->one.v[0]) &&
  1113. X        (zcmp(z2, rp->one) == 0)) {
  1114. X            zcopy(z1, res);
  1115. X            return;
  1116. X    }
  1117. X
  1118. X    /*
  1119. X     * If the size of the modulus is large, then just do the multiply,
  1120. X     * followed by the two multiplies contained in the REDC routine.
  1121. X     * This will be quicker than directly doing the REDC calculation
  1122. X     * because of the O(N^1.585) speed of the multiplies.  The size
  1123. X     * of the number which this is done is configurable.
  1124. X     */
  1125. X    if (rp->mod.len >= _redc2_) {
  1126. X        zmul(z1, z2, &tmp);
  1127. X        zredcdecode(rp, tmp, res);
  1128. X        zfree(tmp);
  1129. X        return;
  1130. X    }
  1131. X
  1132. X    /*
  1133. X     * The number is small enough to calculate by doing the O(N^2) REDC
  1134. X     * algorithm directly.  This algorithm performs the multiplication and
  1135. X     * the reduction at the same time.  Notice the obscure facts that
  1136. X     * only the lowest word of the inverse value is used, and that
  1137. X     * there is no shifting of the partial products as there is in a
  1138. X     * normal multiply.
  1139. X     */
  1140. X    modlen = rp->mod.len;
  1141. X    Ninv = rp->inv.v[0];
  1142. X
  1143. X    /*
  1144. X     * Allocate the result and clear it.
  1145. X     * The size of the result will be equal to or smaller than
  1146. X     * the modulus size.
  1147. X     */
  1148. X    res->sign = 0;
  1149. X    res->len = modlen;
  1150. X    res->v = alloc(modlen);
  1151. X
  1152. X    hd = res->v;
  1153. X    len = modlen;
  1154. X    while (len--)
  1155. X        *hd++ = 0;
  1156. X
  1157. X    /*
  1158. X     * Do this outermost loop over all the digits of z1.
  1159. X     */
  1160. X    h1 = z1.v;
  1161. X    len = z1.len;
  1162. X    while (len--) {
  1163. X        /*
  1164. X         * Start off with the next digit of z1, the first
  1165. X         * digit of z2, and the first digit of the modulus.
  1166. X         */
  1167. X        mulb = (FULL) *h1++;
  1168. X        h2 = z2.v;
  1169. X        h3 = rp->mod.v;
  1170. X        hd = res->v;
  1171. X        sival1.ivalue = mulb * ((FULL) *h2++) + ((FULL) *hd++);
  1172. X        muln = ((HALF) (sival1.silow * Ninv));
  1173. X        sival2.ivalue = muln * ((FULL) *h3++);
  1174. X        sival3.ivalue = ((FULL) sival1.silow) + ((FULL) sival2.silow);
  1175. X        carry.ivalue = ((FULL) sival1.sihigh) + ((FULL) sival2.sihigh)
  1176. X            + ((FULL) sival3.sihigh);
  1177. X
  1178. X        /*
  1179. X         * Do this innermost loop for each digit of z2, except
  1180. X         * for the first digit which was just done above.
  1181. X         */
  1182. X        len2 = z2.len;
  1183. X        while (--len2 > 0) {
  1184. X            sival1.ivalue = mulb * ((FULL) *h2++);
  1185. X            sival2.ivalue = muln * ((FULL) *h3++);
  1186. X            sival3.ivalue = ((FULL) sival1.silow)
  1187. X                + ((FULL) sival2.silow)
  1188. X                + ((FULL) *hd)
  1189. X                + ((FULL) carry.silow);
  1190. X            carry.ivalue = ((FULL) sival1.sihigh)
  1191. X                + ((FULL) sival2.sihigh)
  1192. X                + ((FULL) sival3.sihigh)
  1193. X                + ((FULL) carry.sihigh);
  1194. X
  1195. X            hd[-1] = sival3.silow;
  1196. X            hd++;
  1197. X        }
  1198. X
  1199. X        /*
  1200. X         * Now continue the loop as necessary so the total number
  1201. X         * of interations is equal to the size of the modulus.
  1202. X         * This acts as if the innermost loop was repeated for
  1203. X         * high digits of z2 that are zero.
  1204. X         */
  1205. X        len2 = modlen - z2.len;
  1206. X        while (len2--) {
  1207. X            sival2.ivalue = muln * ((FULL) *h3++);
  1208. X            sival3.ivalue = ((FULL) sival2.silow)
  1209. X                + ((FULL) *hd)
  1210. X                + ((FULL) carry.silow);
  1211. X            carry.ivalue = ((FULL) sival2.sihigh)
  1212. X                + ((FULL) sival3.sihigh)
  1213. X                + ((FULL) carry.sihigh);
  1214. X
  1215. X            hd[-1] = sival3.silow;
  1216. X            hd++;
  1217. X        }
  1218. X
  1219. X        res->v[modlen - 1] = carry.silow;
  1220. X        topdigit = carry.sihigh;
  1221. X    }
  1222. X
  1223. X    /*
  1224. X     * Now continue the loop as necessary so the total number
  1225. X     * of interations is equal to the size of the modulus.
  1226. X     * This acts as if the outermost loop was repeated for high
  1227. X     * digits of z1 that are zero.
  1228. X     */
  1229. X    len = modlen - z1.len;
  1230. X    while (len--) {
  1231. X        /*
  1232. X         * Start off with the first digit of the modulus.
  1233. X         */
  1234. X        h3 = rp->mod.v;
  1235. X        hd = res->v;
  1236. X        muln = ((HALF) (*hd * Ninv));
  1237. X        sival2.ivalue = muln * ((FULL) *h3++);
  1238. X        sival3.ivalue = ((FULL) *hd++) + ((FULL) sival2.silow);
  1239. X        carry.ivalue = ((FULL) sival2.sihigh) + ((FULL) sival3.sihigh);
  1240. X
  1241. X        /*
  1242. X         * Do this innermost loop for each digit of the modulus,
  1243. X         * except for the first digit which was just done above.
  1244. X         */
  1245. X        len2 = modlen;
  1246. X        while (--len2 > 0) {
  1247. X            sival2.ivalue = muln * ((FULL) *h3++);
  1248. X            sival3.ivalue = ((FULL) sival2.silow)
  1249. X                + ((FULL) *hd)
  1250. X                + ((FULL) carry.silow);
  1251. X            carry.ivalue = ((FULL) sival2.sihigh)
  1252. X                + ((FULL) sival3.sihigh)
  1253. X                + ((FULL) carry.sihigh);
  1254. X
  1255. X            hd[-1] = sival3.silow;
  1256. X            hd++;
  1257. X        }
  1258. X        res->v[modlen - 1] = carry.silow;
  1259. X        topdigit = carry.sihigh;
  1260. X    }
  1261. X
  1262. X    /*
  1263. X     * Determine the true size of the result, taking the top digit of
  1264. X     * the current result into account.  The top digit is not stored in
  1265. X     * the number because it is temporary and would become zero anyway
  1266. X     * after the final subtraction is done.
  1267. X     */
  1268. X    if (topdigit == 0) {
  1269. X        len = modlen;
  1270. X        hd = &res->v[len - 1];
  1271. X        while ((*hd == 0) && (len > 1)) {
  1272. X            hd--;
  1273. X            len--;
  1274. X        }
  1275. X        res->len = len;
  1276. X    }
  1277. X
  1278. X    /*
  1279. X     * Compare the result with the modulus.
  1280. X     * If it is less than the modulus, then the calculation is complete.
  1281. X     */
  1282. X    if ((topdigit == 0) && ((len < modlen)
  1283. X        || (res->v[len - 1] < rp->mod.v[len - 1])
  1284. X        || (zrel(*res, rp->mod) < 0)))
  1285. X            return;
  1286. X
  1287. X    /*
  1288. X     * Do a subtraction to reduce the result to a value less than
  1289. X     * the modulus.  The REDC algorithm guarantees that a single subtract
  1290. X     * is all that is needed.  Ignore any borrowing from the possible
  1291. X     * highest word of the current result because that would affect
  1292. X     * only the top digit value that was not stored and would become
  1293. X     * zero anyway.
  1294. X     */
  1295. X    carry.ivalue = 0;
  1296. X    h1 = rp->mod.v;
  1297. X    hd = res->v;
  1298. X    len = modlen;
  1299. X    while (len--) {
  1300. X        carry.ivalue = BASE1 - ((FULL) *hd) + ((FULL) *h1++)
  1301. X            + ((FULL) carry.silow);
  1302. X        *hd++ = BASE1 - carry.silow;
  1303. X        carry.silow = carry.sihigh;
  1304. X    }
  1305. X
  1306. X    /*
  1307. X     * Now finally recompute the size of the result.
  1308. X     */
  1309. X    len = modlen;
  1310. X    hd = &res->v[len - 1];
  1311. X    while ((*hd == 0) && (len > 1)) {
  1312. X        hd--;
  1313. X        len--;
  1314. X    }
  1315. X    res->len = len;
  1316. X}
  1317. X
  1318. X
  1319. X/*
  1320. X * Square a number in REDC format producing a result also in REDC format.
  1321. X */
  1322. Xvoid
  1323. Xzredcsquare(rp, z1, res)
  1324. X    REDC *rp;        /* REDC information */
  1325. X    ZVALUE z1;        /* REDC number to be squared */
  1326. X    ZVALUE *res;        /* resulting REDC number */
  1327. X{
  1328. X    ZVALUE tmp;
  1329. X
  1330. X    if (zisneg(z1))
  1331. X        math_error("Negative number in zredcsquare");
  1332. X    if (ziszero(z1)) {
  1333. X        *res = _zero_;
  1334. X        return;
  1335. X    }
  1336. X    if ((z1.len == rp->one.len) && (z1.v[0] == rp->one.v[0]) &&
  1337. X        (zcmp(z1, rp->one) == 0)) {
  1338. X            zcopy(z1, res);
  1339. X            return;
  1340. X    }
  1341. X
  1342. X    /*
  1343. X     * If the modulus is small enough, then call the multiply
  1344. X     * routine to produce the result.  Otherwise call the O(N^1.585)
  1345. X     * routines to get the answer.
  1346. X     */
  1347. X    if (rp->mod.len < _redc2_) {
  1348. X        zredcmul(rp, z1, z1, res);
  1349. X        return;
  1350. X    }
  1351. X    zsquare(z1, &tmp);
  1352. X    zredcdecode(rp, tmp, res);
  1353. X    zfree(tmp);
  1354. X}
  1355. X
  1356. X
  1357. X/*
  1358. X * Compute the result of raising a REDC format number to a power.
  1359. X * The result is within the range 0 to the modulus - 1.
  1360. X * This calculates the result by examining the power POWBITS bits at a time,
  1361. X * using a small table of POWNUMS low powers to calculate powers for those bits,
  1362. X * and repeated squaring and multiplying by the partial powers to generate
  1363. X * the complete power.
  1364. X */
  1365. Xvoid
  1366. Xzredcpower(rp, z1, z2, res)
  1367. X    REDC *rp;        /* REDC information */
  1368. X    ZVALUE z1;        /* REDC number to be raised */
  1369. X    ZVALUE z2;        /* normal number to raise number to */
  1370. X    ZVALUE *res;        /* result */
  1371. X{
  1372. X    HALF *hp;        /* pointer to current word of the power */
  1373. X    ZVALUE *pp;        /* pointer to low power table */
  1374. X    ZVALUE ans, temp;    /* calculation values */
  1375. X    ZVALUE modpow;        /* current small power */
  1376. X    ZVALUE lowpowers[POWNUMS];    /* low powers */
  1377. X    int curshift;        /* shift value for word of power */
  1378. X    HALF curhalf;        /* current word of power */
  1379. X    unsigned int curpow;    /* current low power */
  1380. X    unsigned int curbit;    /* current bit of low power */
  1381. X    int i;
  1382. X
  1383. X    if (zisneg(z1))
  1384. X        math_error("Negative number in zredcpower");
  1385. X    if (zisneg(z2))
  1386. X        math_error("Negative power in zredcpower");
  1387. X
  1388. X    /*
  1389. X     * Check for zero or the REDC format for one.
  1390. X     */
  1391. X    if (ziszero(z1) || zisunit(rp->mod)) {
  1392. X        *res = _zero_;
  1393. X        return;
  1394. X    }
  1395. X    if (zcmp(z1, rp->one) == 0) {
  1396. X        zcopy(rp->one, res);
  1397. X        return;
  1398. X    }
  1399. X
  1400. X    /*
  1401. X     * See if the number being raised is the REDC format for -1.
  1402. X     * If so, then the answer is the REDC format for one or minus one.
  1403. X     * To do this check, calculate the REDC format for -1.
  1404. X     */
  1405. X    if (((HALF)(z1.v[0] + rp->one.v[0])) == rp->mod.v[0]) {
  1406. X        zsub(rp->mod, rp->one, &temp);
  1407. X        if (zcmp(z1, temp) == 0) {
  1408. X            if (zisodd(z2)) {
  1409. X                *res = temp;
  1410. X                return;
  1411. X            }
  1412. X            zfree(temp);
  1413. X            zcopy(rp->one, res);
  1414. X            return;
  1415. X        }
  1416. X        zfree(temp);
  1417. X    }
  1418. X
  1419. X    for (pp = &lowpowers[2]; pp < &lowpowers[POWNUMS]; pp++)
  1420. X        pp->len = 0;
  1421. X    zcopy(rp->one, &lowpowers[0]);
  1422. X    zcopy(z1, &lowpowers[1]);
  1423. X    zcopy(rp->one, &ans);
  1424. X
  1425. X    hp = &z2.v[z2.len - 1];
  1426. X    curhalf = *hp;
  1427. X    curshift = BASEB - POWBITS;
  1428. X    while (curshift && ((curhalf >> curshift) == 0))
  1429. X        curshift -= POWBITS;
  1430. X
  1431. X    /*
  1432. X     * Calculate the result by examining the power POWBITS bits at a time,
  1433. X     * and use the table of low powers at each iteration.
  1434. X     */
  1435. X    for (;;) {
  1436. X        curpow = (curhalf >> curshift) & (POWNUMS - 1);
  1437. X        pp = &lowpowers[curpow];
  1438. X
  1439. X        /*
  1440. X         * If the small power is not yet saved in the table, then
  1441. X         * calculate it and remember it in the table for future use.
  1442. X         */
  1443. X        if (pp->len == 0) {
  1444. X            if (curpow & 0x1)
  1445. X                zcopy(z1, &modpow);
  1446. X            else
  1447. X                zcopy(rp->one, &modpow);
  1448. X
  1449. X            for (curbit = 0x2; curbit <= curpow; curbit *= 2) {
  1450. X                pp = &lowpowers[curbit];
  1451. X                if (pp->len == 0)
  1452. X                    zredcsquare(rp, lowpowers[curbit/2],
  1453. X                        pp);
  1454. X                if (curbit & curpow) {
  1455. X                    zredcmul(rp, *pp, modpow, &temp);
  1456. X                    zfree(modpow);
  1457. X                    modpow = temp;
  1458. X                }
  1459. X            }
  1460. X            pp = &lowpowers[curpow];
  1461. X            *pp = modpow;
  1462. X        }
  1463. X
  1464. X        /*
  1465. X         * If the power is nonzero, then accumulate the small power
  1466. X         * into the result.
  1467. X         */
  1468. X        if (curpow) {
  1469. X            zredcmul(rp, ans, *pp, &temp);
  1470. X            zfree(ans);
  1471. X            ans = temp;
  1472. X        }
  1473. X
  1474. X        /*
  1475. X         * Select the next POWBITS bits of the power, if there is
  1476. X         * any more to generate.
  1477. X         */
  1478. X        curshift -= POWBITS;
  1479. X        if (curshift < 0) {
  1480. X            if (hp-- == z2.v)
  1481. X                break;
  1482. X            curhalf = *hp;
  1483. X            curshift = BASEB - POWBITS;
  1484. X        }
  1485. X
  1486. X        /*
  1487. X         * Square the result POWBITS times to make room for the next
  1488. X         * chunk of bits.
  1489. X         */
  1490. X        for (i = 0; i < POWBITS; i++) {
  1491. X            zredcsquare(rp, ans, &temp);
  1492. X            zfree(ans);
  1493. X            ans = temp;
  1494. X        }
  1495. X    }
  1496. X
  1497. X    for (pp = lowpowers; pp < &lowpowers[POWNUMS]; pp++) {
  1498. X        if (pp->len)
  1499. X            freeh(pp->v);
  1500. X    }
  1501. X    *res = ans;
  1502. X}
  1503. X
  1504. X/* END CODE */
  1505. SHAR_EOF
  1506. chmod 0644 calc2.9.0/zmod.c || echo "restore of calc2.9.0/zmod.c fails"
  1507. set `wc -c calc2.9.0/zmod.c`;Sum=$1
  1508. if test "$Sum" != "32540"
  1509. then echo original size 32540, current size $Sum;fi
  1510. echo "x - extracting calc2.9.0/zmul.c (Text)"
  1511. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/zmul.c &&
  1512. X/*
  1513. X * Copyright (c) 1993 David I. Bell
  1514. X * Permission is granted to use, distribute, or modify this source,
  1515. X * provided that this copyright notice remains intact.
  1516. X *
  1517. X * Faster than usual multiplying and squaring routines.
  1518. X * The algorithm used is the reasonably simple one from Knuth, volume 2,
  1519. X * section 4.3.3.  These recursive routines are of speed O(N^1.585)
  1520. X * instead of O(N^2).  The usual multiplication and (almost usual) squaring
  1521. X * algorithms are used for small numbers.  On a 386 with its compiler, the
  1522. X * two algorithms are equal in speed at about 100 decimal digits.
  1523. X */
  1524. X
  1525. X#include "zmath.h"
  1526. X
  1527. X
  1528. XLEN _mul2_ = MUL_ALG2;        /* size of number to use multiply algorithm 2 */
  1529. XLEN _sq2_ = SQ_ALG2;        /* size of number to use square algorithm 2 */
  1530. X
  1531. X
  1532. Xstatic HALF *tempbuf;        /* temporary buffer for multiply and square */
  1533. X
  1534. Xstatic LEN domul MATH_PROTO((HALF *v1, LEN size1, HALF *v2, LEN size2, HALF *ans));
  1535. Xstatic LEN dosquare MATH_PROTO((HALF *vp, LEN size, HALF *ans));
  1536. X
  1537. X
  1538. X/*
  1539. X * Multiply two numbers using the following formula recursively:
  1540. X *    (A*S+B)*(C*S+D) = (S^2+S)*A*C + S*(A-B)*(D-C) + (S+1)*B*D
  1541. X * where S is a power of 2^16, and so multiplies by it are shifts, and
  1542. X * A,B,C,D are the left and right halfs of the numbers to be multiplied.
  1543. X */
  1544. Xvoid
  1545. Xzmul(z1, z2, res)
  1546. X    ZVALUE z1, z2;        /* numbers to multiply */
  1547. X    ZVALUE *res;        /* result of multiplication */
  1548. X{
  1549. X    LEN len;        /* size of array */
  1550. X
  1551. X    if (ziszero(z1) || ziszero(z2)) {
  1552. X        *res = _zero_;
  1553. X        return;
  1554. X    }
  1555. X    if (zisunit(z1)) {
  1556. X        zcopy(z2, res);
  1557. X        res->sign = (z1.sign != z2.sign);
  1558. X        return;
  1559. X    }
  1560. X    if (zisunit(z2)) {
  1561. X        zcopy(z1, res);
  1562. X        res->sign = (z1.sign != z2.sign);
  1563. X        return;
  1564. X    }
  1565. X
  1566. X    /*
  1567. X     * Allocate a temporary buffer for the recursion levels to use.
  1568. X     * An array needs to be allocated large enough for all of the
  1569. X     * temporary results to fit in.  This size is about twice the size
  1570. X     * of the largest original number, since each recursion level uses
  1571. X     * the size of its given number, and whose size is 1/2 the size of
  1572. X     * the previous level.  The sum of the infinite series is 2.
  1573. X     * Add some extra words because of rounding when dividing by 2
  1574. X     * and also because of the extra word that each multiply needs.
  1575. X     */
  1576. X    len = z1.len;
  1577. X    if (len < z2.len)
  1578. X        len = z2.len;
  1579. X    len = 2 * len + 64;
  1580. X    tempbuf = zalloctemp(len);
  1581. X
  1582. X    res->sign = (z1.sign != z2.sign);
  1583. X    res->v = alloc(z1.len + z2.len + 1);
  1584. X    res->len = domul(z1.v, z1.len, z2.v, z2.len, res->v);
  1585. X}
  1586. X
  1587. X
  1588. X/*
  1589. X * Recursive routine to multiply two numbers by splitting them up into
  1590. X * two numbers of half the size, and using the results of multiplying the
  1591. X * subpieces.  The result is placed in the indicated array, which must be
  1592. X * large enough for the result plus one extra word (size1 + size2 + 1).
  1593. X * Returns the actual size of the result with leading zeroes stripped.
  1594. X * This also uses a temporary array which must be twice as large as
  1595. X * one more than the size of the number at the top level recursive call.
  1596. X */
  1597. Xstatic LEN
  1598. Xdomul(v1, size1, v2, size2, ans)
  1599. X    HALF *v1;        /* first number */
  1600. X    LEN size1;        /* size of first number */
  1601. X    HALF *v2;        /* second number */
  1602. X    LEN size2;        /* size of second number */
  1603. X    HALF *ans;        /* location for result */
  1604. X{
  1605. X    LEN shift;        /* amount numbers are shifted by */
  1606. X    LEN sizeA;        /* size of left half of first number */
  1607. X    LEN sizeB;        /* size of right half of first number */
  1608. X    LEN sizeC;        /* size of left half of second number */
  1609. X    LEN sizeD;        /* size of right half of second number */
  1610. X    LEN sizeAB;        /* size of subtraction of A and B */
  1611. X    LEN sizeDC;        /* size of subtraction of D and C */
  1612. X    LEN sizeABDC;        /* size of product of above two results */
  1613. X    LEN subsize;        /* size of difference of halfs */
  1614. X    LEN copysize;        /* size of number left to copy */
  1615. X    LEN sizetotal;        /* total size of product */
  1616. X    LEN len;        /* temporary length */
  1617. X    HALF *baseA;        /* base of left half of first number */
  1618. X    HALF *baseB;        /* base of right half of first number */
  1619. X    HALF *baseC;        /* base of left half of second number */
  1620. X    HALF *baseD;        /* base of right half of second number */
  1621. X    HALF *baseAB;        /* base of result of subtraction of A and B */
  1622. X    HALF *baseDC;        /* base of result of subtraction of D and C */
  1623. X    HALF *baseABDC;        /* base of product of above two results */
  1624. X    HALF *baseAC;        /* base of product of A and C */
  1625. X    HALF *baseBD;        /* base of product of B and D */
  1626. X    FULL carry;        /* carry digit for small multiplications */
  1627. X    FULL carryACBD;        /* carry from addition of A*C and B*D */
  1628. X    FULL digit;        /* single digit multiplying by */
  1629. X    HALF *temp;        /* base for temporary calculations */
  1630. X    BOOL neg;        /* whether imtermediate term is negative */
  1631. X    register HALF *hd, *h1, *h2;    /* for inner loops */
  1632. X    SIUNION sival;        /* for addition of digits */
  1633. X
  1634. X    /*
  1635. X     * Trim the numbers of leading zeroes and initialize the
  1636. X     * estimated size of the result.
  1637. X     */
  1638. X    hd = &v1[size1 - 1];
  1639. X    while ((*hd == 0) && (size1 > 1)) {
  1640. X        hd--;
  1641. X        size1--;
  1642. X    }
  1643. X    hd = &v2[size2 - 1];
  1644. X    while ((*hd == 0) && (size2 > 1)) {
  1645. X        hd--;
  1646. X        size2--;
  1647. X    }
  1648. X    sizetotal = size1 + size2;
  1649. X
  1650. X    /*
  1651. X     * First check for zero answer.
  1652. X     */
  1653. X    if (((size1 == 1) && (*v1 == 0)) || ((size2 == 1) && (*v2 == 0))) {
  1654. X        *ans = 0;
  1655. X        return 1;
  1656. X    }
  1657. X
  1658. X    /*
  1659. X     * Exchange the two numbers if necessary to make the number of
  1660. X     * digits of the first number be greater than or equal to the
  1661. X     * second number.
  1662. X     */
  1663. X    if (size1 < size2) {
  1664. X        len = size1; size1 = size2; size2 = len;
  1665. X        hd = v1; v1 = v2; v2 = hd;
  1666. X    }
  1667. X
  1668. X    /*
  1669. X     * If the smaller number has only a few digits, then calculate
  1670. X     * the result in the normal manner in order to avoid the overhead
  1671. X     * of the recursion for small numbers.  The number of digits where
  1672. X     * the algorithm changes is settable from 2 to maxint.
  1673. X     */
  1674. X    if (size2 < _mul2_) {
  1675. X        /*
  1676. X         * First clear the top part of the result, and then multiply
  1677. X         * by the lowest digit to get the first partial sum.  Later
  1678. X         * products will then add into this result.
  1679. X         */
  1680. X        hd = &ans[size1];
  1681. X        len = size2;
  1682. X        while (len--)
  1683. X            *hd++ = 0;
  1684. X
  1685. X        digit = *v2++;
  1686. X        h1 = v1;
  1687. X        hd = ans;
  1688. X        carry = 0;
  1689. X        len = size1;
  1690. X        while (len >= 4) {    /* expand the loop some */
  1691. X            len -= 4;
  1692. X            sival.ivalue = ((FULL) *h1++) * digit + carry;
  1693. X            *hd++ = sival.silow;
  1694. X            carry = sival.sihigh;
  1695. X            sival.ivalue = ((FULL) *h1++) * digit + carry;
  1696. X            *hd++ = sival.silow;
  1697. X            carry = sival.sihigh;
  1698. X            sival.ivalue = ((FULL) *h1++) * digit + carry;
  1699. X            *hd++ = sival.silow;
  1700. X            carry = sival.sihigh;
  1701. X            sival.ivalue = ((FULL) *h1++) * digit + carry;
  1702. X            *hd++ = sival.silow;
  1703. X            carry = sival.sihigh;
  1704. X        }
  1705. X        while (len--) {
  1706. X            sival.ivalue = ((FULL) *h1++) * digit + carry;
  1707. X            *hd++ = sival.silow;
  1708. X            carry = sival.sihigh;
  1709. X        }
  1710. X        *hd = (HALF)carry;
  1711. X
  1712. X        /*
  1713. X         * Now multiply by the remaining digits of the second number,
  1714. X         * adding each product into the final result.
  1715. X         */
  1716. X        h2 = ans;
  1717. X        while (--size2 > 0) {
  1718. X            digit = *v2++;
  1719. X            h1 = v1;
  1720. X            hd = ++h2;
  1721. X            if (digit == 0)
  1722. X                continue;
  1723. X            carry = 0;
  1724. X            len = size1;
  1725. X            while (len >= 4) {    /* expand the loop some */
  1726. X                len -= 4;
  1727. X                sival.ivalue = ((FULL) *h1++) * digit
  1728. X                    + ((FULL) *hd) + carry;
  1729. X                *hd++ = sival.silow;
  1730. X                carry = sival.sihigh;
  1731. X                sival.ivalue = ((FULL) *h1++) * digit
  1732. X                    + ((FULL) *hd) + carry;
  1733. X                *hd++ = sival.silow;
  1734. X                carry = sival.sihigh;
  1735. X                sival.ivalue = ((FULL) *h1++) * digit
  1736. X                    + ((FULL) *hd) + carry;
  1737. X                *hd++ = sival.silow;
  1738. X                carry = sival.sihigh;
  1739. X                sival.ivalue = ((FULL) *h1++) * digit
  1740. X                    + ((FULL) *hd) + carry;
  1741. X                *hd++ = sival.silow;
  1742. X                carry = sival.sihigh;
  1743. X            }
  1744. X            while (len--) {
  1745. X                sival.ivalue = ((FULL) *h1++) * digit
  1746. X                    + ((FULL) *hd) + carry;
  1747. X                *hd++ = sival.silow;
  1748. X                carry = sival.sihigh;
  1749. X            }
  1750. X            while (carry) {
  1751. X                sival.ivalue = ((FULL) *hd) + carry;
  1752. X                *hd++ = sival.silow;
  1753. X                carry = sival.sihigh;
  1754. X            }
  1755. X        }
  1756. X
  1757. X        /*
  1758. X         * Now return the true size of the number.
  1759. X         */
  1760. X        len = sizetotal;
  1761. X        hd = &ans[len - 1];
  1762. X        while ((*hd == 0) && (len > 1)) {
  1763. X            hd--;
  1764. X            len--;
  1765. X        }
  1766. X        return len;
  1767. X    }
  1768. X
  1769. X    /*
  1770. X     * Need to multiply by a large number.
  1771. X     * Allocate temporary space for calculations, and calculate the
  1772. X     * value for the shift.  The shift value is 1/2 the size of the
  1773. X     * larger (first) number (rounded up).  The amount of temporary
  1774. X     * space needed is twice the size of the shift, plus one more word
  1775. X     * for the multiply to use.
  1776. X     */
  1777. X    shift = (size1 + 1) / 2;
  1778. X    temp = tempbuf;
  1779. X    tempbuf += (2 * shift) + 1;
  1780. X
  1781. X    /*
  1782. X     * Determine the sizes and locations of all the numbers.
  1783. X     * The value of sizeC can be negative, and this is checked later.
  1784. X     * The value of sizeD is limited by the full size of the number.
  1785. X     */
  1786. X    baseA = v1 + shift;
  1787. X    baseB = v1;
  1788. X    baseC = v2 + shift;
  1789. X    baseD = v2;
  1790. X    baseAB = ans;
  1791. X    baseDC = ans + shift;
  1792. X    baseAC = ans + shift * 2;
  1793. X    baseBD = ans;
  1794. X
  1795. X    sizeA = size1 - shift;
  1796. X    sizeC = size2 - shift;
  1797. X
  1798. X    sizeB = shift;
  1799. X    hd = &baseB[shift - 1];
  1800. X    while ((*hd == 0) && (sizeB > 1)) {
  1801. X        hd--;
  1802. X        sizeB--;
  1803. X    }
  1804. X
  1805. X    sizeD = shift;
  1806. X    if (sizeD > size2)
  1807. X        sizeD = size2;
  1808. X    hd = &baseD[sizeD - 1];
  1809. X    while ((*hd == 0) && (sizeD > 1)) {
  1810. X        hd--;
  1811. X        sizeD--;
  1812. X    }
  1813. X
  1814. X    /*
  1815. X     * If the smaller number has a high half of zero, then calculate
  1816. X     * the result by breaking up the first number into two numbers
  1817. X     * and combining the results using the obvious formula:
  1818. X     *    (A*S+B) * D = (A*D)*S + B*D
  1819. X     */
  1820. X    if (sizeC <= 0) {
  1821. X        len = domul(baseB, sizeB, baseD, sizeD, ans);
  1822. X        hd = &ans[len];
  1823. X        len = sizetotal - len;
  1824. X        while (len--)
  1825. X            *hd++ = 0;
  1826. X
  1827. X        /*
  1828. X         * Add the second number into the first number, shifted
  1829. X         * over at the correct position.
  1830. X         */
  1831. X        len = domul(baseA, sizeA, baseD, sizeD, temp);
  1832. X        h1 = temp;
  1833. X        hd = ans + shift;
  1834. X        carry = 0;
  1835. X        while (len--) {
  1836. X            sival.ivalue = ((FULL) *h1++) + ((FULL) *hd) + carry;
  1837. X            *hd++ = sival.silow;
  1838. X            carry = sival.sihigh;
  1839. X        }
  1840. X        while (carry) {
  1841. X            sival.ivalue = ((FULL) *hd) + carry;
  1842. X            *hd++ = sival.silow;
  1843. X            carry = sival.sihigh;
  1844. X        }
  1845. X
  1846. X        /*
  1847. X         * Determine the final size of the number and return it.
  1848. X         */
  1849. X        len = sizetotal;
  1850. X        hd = &ans[len - 1];
  1851. X        while ((*hd == 0) && (len > 1)) {
  1852. X            hd--;
  1853. X            len--;
  1854. X        }
  1855. X        tempbuf = temp;
  1856. X        return len;
  1857. X    }
  1858. X
  1859. X    /*
  1860. X     * Now we know that the high halfs of the numbers are nonzero,
  1861. X     * so we can use the complete formula.
  1862. X     *    (A*S+B)*(C*S+D) = (S^2+S)*A*C + S*(A-B)*(D-C) + (S+1)*B*D.
  1863. X     * The steps are done in the following order:
  1864. X     *    A-B
  1865. X     *    D-C
  1866. X     *    (A-B)*(D-C)
  1867. X     *    S^2*A*C + B*D
  1868. X     *    (S^2+S)*A*C + (S+1)*B*D                (*)
  1869. X     *    (S^2+S)*A*C + S*(A-B)*(D-C) + (S+1)*B*D
  1870. X     *
  1871. X     * Note: step (*) above can produce a result which is larger than
  1872. X     * the final product will be, and this is where the extra word
  1873. X     * needed in the product comes from.  After the final subtraction is
  1874. X     * done, the result fits in the expected size.  Using the extra word
  1875. X     * is easier than suppressing the carries and borrows everywhere.
  1876. X     *
  1877. X     * Begin by forming the product (A-B)*(D-C) into a temporary
  1878. X     * location that we save until the final step.  Do each subtraction
  1879. X     * at positions 0 and S.  Be very careful about the relative sizes
  1880. X     * of the numbers since this result can be negative.  For the first
  1881. X     * step calculate the absolute difference of A and B into a temporary
  1882. X     * location at position 0 of the result.  Negate the sign if A is
  1883. X     * smaller than B.
  1884. X     */
  1885. X    neg = FALSE;
  1886. X    if (sizeA == sizeB) {
  1887. X        len = sizeA;
  1888. X        h1 = &baseA[len - 1];
  1889. X        h2 = &baseB[len - 1];
  1890. X        while ((len > 1) && (*h1 == *h2)) {
  1891. X            len--;
  1892. X            h1--;
  1893. X            h2--;
  1894. X        }
  1895. X    }
  1896. X    if ((sizeA > sizeB) || ((sizeA == sizeB) && (*h1 > *h2)))
  1897. X    {
  1898. X        h1 = baseA;
  1899. X        h2 = baseB;
  1900. X        sizeAB = sizeA;
  1901. X        subsize = sizeB;
  1902. X    } else {
  1903. X        neg = !neg;
  1904. X        h1 = baseB;
  1905. X        h2 = baseA;
  1906. X        sizeAB = sizeB;
  1907. X        subsize = sizeA;
  1908. X    }
  1909. X    copysize = sizeAB - subsize;
  1910. X
  1911. X    hd = baseAB;
  1912. X    carry = 0;
  1913. X    while (subsize--) {
  1914. X        sival.ivalue = BASE1 - ((FULL) *h1++) + ((FULL) *h2++) + carry;
  1915. X        *hd++ = BASE1 - sival.silow;
  1916. X        carry = sival.sihigh;
  1917. X    }
  1918. X    while (copysize--) {
  1919. X        sival.ivalue = (BASE1 - ((FULL) *h1++)) + carry;
  1920. X        *hd++ = BASE1 - sival.silow;
  1921. X        carry = sival.sihigh;
  1922. X    }
  1923. X
  1924. X    hd = &baseAB[sizeAB - 1];
  1925. X    while ((*hd == 0) && (sizeAB > 1)) {
  1926. X        hd--;
  1927. X        sizeAB--;
  1928. X    }
  1929. X
  1930. X    /*
  1931. X     * This completes the calculation of abs(A-B).  For the next step
  1932. X     * calculate the absolute difference of D and C into a temporary
  1933. X     * location at position S of the result.  Negate the sign if C is
  1934. X     * larger than D.
  1935. X     */
  1936. X    if (sizeC == sizeD) {
  1937. X        len = sizeC;
  1938. X        h1 = &baseC[len - 1];
  1939. X        h2 = &baseD[len - 1];
  1940. X        while ((len > 1) && (*h1 == *h2)) {
  1941. X            len--;
  1942. X            h1--;
  1943. X            h2--;
  1944. X        }
  1945. X    }
  1946. X    if ((sizeC > sizeD) || ((sizeC == sizeD) && (*h1 > *h2)))
  1947. X    {
  1948. X        neg = !neg;
  1949. X        h1 = baseC;
  1950. X        h2 = baseD;
  1951. X        sizeDC = sizeC;
  1952. X        subsize = sizeD;
  1953. X    } else {
  1954. X        h1 = baseD;
  1955. X        h2 = baseC;
  1956. X        sizeDC = sizeD;
  1957. X        subsize = sizeC;
  1958. X    }
  1959. X    copysize = sizeDC - subsize;
  1960. X
  1961. X    hd = baseDC;
  1962. X    carry = 0;
  1963. X    while (subsize--) {
  1964. X        sival.ivalue = BASE1 - ((FULL) *h1++) + ((FULL) *h2++) + carry;
  1965. X        *hd++ = BASE1 - sival.silow;
  1966. X        carry = sival.sihigh;
  1967. X    }
  1968. X    while (copysize--) {
  1969. X        sival.ivalue = (BASE1 - ((FULL) *h1++)) + carry;
  1970. X        *hd++ = BASE1 - sival.silow;
  1971. X        carry = sival.sihigh;
  1972. X    }
  1973. X    hd = &baseDC[sizeDC - 1];
  1974. X    while ((*hd == 0) && (sizeDC > 1)) {
  1975. X        hd--;
  1976. X        sizeDC--;
  1977. X    }
  1978. X
  1979. X    /*
  1980. X     * This completes the calculation of abs(D-C).  Now multiply
  1981. X     * together abs(A-B) and abs(D-C) into a temporary location,
  1982. X     * which is preserved until the final steps.
  1983. X     */
  1984. X    baseABDC = temp;
  1985. X    sizeABDC = domul(baseAB, sizeAB, baseDC, sizeDC, baseABDC);
  1986. X
  1987. X    /*
  1988. X     * Now calculate B*D and A*C into one of their two final locations.
  1989. X     * Make sure the high order digits of the products are zeroed since
  1990. X     * this initializes the final result.  Be careful about this zeroing
  1991. X     * since the size of the high order words might be smaller than
  1992. X     * the shift size.  Do B*D first since the multiplies use one more
  1993. X     * word than the size of the product.  Also zero the final extra
  1994. X     * word in the result for possible carries to use.
  1995. X     */
  1996. X    len = domul(baseB, sizeB, baseD, sizeD, baseBD);
  1997. X    hd = &baseBD[len];
  1998. X    len = shift * 2 - len;
  1999. X    while (len--)
  2000. X        *hd++ = 0;
  2001. X
  2002. X    len = domul(baseA, sizeA, baseC, sizeC, baseAC);
  2003. X    hd = &baseAC[len];
  2004. X    len = sizetotal - shift * 2 - len + 1;
  2005. X    while (len--)
  2006. X        *hd++ = 0;
  2007. X
  2008. X    /*
  2009. X     * Now add in A*C and B*D into themselves at the other shifted
  2010. X     * position that they need.  This addition is tricky in order to
  2011. X     * make sure that the two additions cannot interfere with each other.
  2012. X     * Therefore we first add in the top half of B*D and the lower half
  2013. X     * of A*C.  The sources and destinations of these two additions
  2014. X     * overlap, and so the same answer results from the two additions,
  2015. X     * thus only two pointers suffice for both additions.  Keep the
  2016. X     * final carry from these additions for later use since we cannot
  2017. X     * afford to change the top half of A*C yet.
  2018. X     */
  2019. X    h1 = baseBD + shift;
  2020. X    h2 = baseAC;
  2021. X    carryACBD = 0;
  2022. X    len = shift;
  2023. X    while (len--) {
  2024. X        sival.ivalue = ((FULL) *h1) + ((FULL) *h2) + carryACBD;
  2025. X        *h1++ = sival.silow;
  2026. X        *h2++ = sival.silow;
  2027. X        carryACBD = sival.sihigh;
  2028. X    }
  2029. X
  2030. X    /*
  2031. X     * Now add in the bottom half of B*D and the top half of A*C.
  2032. X     * These additions are straightforward, except that A*C should
  2033. X     * be done first because of possible carries from B*D, and the
  2034. X     * top half of A*C might not exist.  Add in one of the carries
  2035. X     * from the previous addition while we are at it.
  2036. X     */
  2037. X    h1 = baseAC + shift;
  2038. X    hd = baseAC;
  2039. X    carry = carryACBD;
  2040. X    len = sizetotal - 3 * shift;
  2041. X    while (len--) {
  2042. X        sival.ivalue = ((FULL) *h1++) + ((FULL) *hd) + carry;
  2043. X        *hd++ = sival.silow;
  2044. X        carry = sival.sihigh;
  2045. X    }
  2046. X    while (carry) {
  2047. X        sival.ivalue = ((FULL) *hd) + carry;
  2048. X        *hd++ = sival.silow;
  2049. X        carry = sival.sihigh;
  2050. X    }
  2051. X
  2052. X    h1 = baseBD;
  2053. X    hd = baseBD + shift;
  2054. X    carry = 0;
  2055. X    len = shift;
  2056. X    while (len--) {
  2057. X        sival.ivalue = ((FULL) *h1++) + ((FULL) *hd) + carry;
  2058. X        *hd++ = sival.silow;
  2059. X        carry = sival.sihigh;
  2060. X    }
  2061. X    while (carry) {
  2062. X        sival.ivalue = ((FULL) *hd) + carry;
  2063. X        *hd++ = sival.silow;
  2064. X        carry = sival.sihigh;
  2065. X    }
  2066. X
  2067. X    /*
  2068. X     * Now finally add in the other delayed carry from the
  2069. X     * above addition.
  2070. X     */
  2071. X    hd = baseAC + shift;
  2072. X    while (carryACBD) {
  2073. X        sival.ivalue = ((FULL) *hd) + carryACBD;
  2074. X        *hd++ = sival.silow;
  2075. X        carryACBD = sival.sihigh;
  2076. X    }
  2077. X
  2078. X    /*
  2079. X     * Now finally add or subtract (A-B)*(D-C) into the final result at
  2080. X     * the correct position (S), according to whether it is positive or
  2081. X     * negative.  When subtracting, the answer cannot go negative.
  2082. X     */
  2083. X    h1 = baseABDC;
  2084. X    hd = ans + shift;
  2085. X    carry = 0;
  2086. X    len = sizeABDC;
  2087. X    if (neg) {
  2088. X        while (len--) {
  2089. X            sival.ivalue = BASE1 - ((FULL) *hd) +
  2090. X                ((FULL) *h1++) + carry;
  2091. X            *hd++ = BASE1 - sival.silow;
  2092. X            carry = sival.sihigh;
  2093. X        }
  2094. X        while (carry) {
  2095. X            sival.ivalue = BASE1 - ((FULL) *hd) + carry;
  2096. X            *hd++ = BASE1 - sival.silow;
  2097. X            carry = sival.sihigh;
  2098. X        }
  2099. X    } else {
  2100. X        while (len--) {
  2101. X            sival.ivalue = ((FULL) *h1++) + ((FULL) *hd) + carry;
  2102. X            *hd++ = sival.silow;
  2103. X            carry = sival.sihigh;
  2104. X        }
  2105. X        while (carry) {
  2106. X            sival.ivalue = ((FULL) *hd) + carry;
  2107. X            *hd++ = sival.silow;
  2108. X            carry = sival.sihigh;
  2109. X        }
  2110. X    }
  2111. X
  2112. X    /*
  2113. X     * Finally determine the size of the final result and return that.
  2114. X     */
  2115. X    len = sizetotal;
  2116. X    hd = &ans[len - 1];
  2117. X    while ((*hd == 0) && (len > 1)) {
  2118. X        hd--;
  2119. X        len--;
  2120. X    }
  2121. X    tempbuf = temp;
  2122. X    return len;
  2123. X}
  2124. X
  2125. X
  2126. X/*
  2127. X * Square a number by using the following formula recursively:
  2128. X *    (A*S+B)^2 = (S^2+S)*A^2 + (S+1)*B^2 - S*(A-B)^2
  2129. X * where S is a power of 2^16, and so multiplies by it are shifts,
  2130. X * and A and B are the left and right halfs of the number to square.
  2131. X */
  2132. Xvoid
  2133. Xzsquare(z, res)
  2134. X    ZVALUE z, *res;
  2135. X{
  2136. X    LEN len;
  2137. X
  2138. X    if (ziszero(z)) {
  2139. X        *res = _zero_;
  2140. X        return;
  2141. X    }
  2142. X    if (zisunit(z)) {
  2143. X        *res = _one_;
  2144. X        return;
  2145. X    }
  2146. X
  2147. X    /*
  2148. X     * Allocate a temporary array if necessary for the recursion to use.
  2149. X     * The array needs to be allocated large enough for all of the
  2150. X     * temporary results to fit in.  This size is about 3 times the
  2151. X     * size of the original number, since each recursion level uses 3/2
  2152. X     * of the size of its given number, and whose size is 1/2 the size
  2153. X     * of the previous level.  The sum of the infinite series is 3.
  2154. X     * Allocate some extra words for rounding up the sizes.
  2155. X     */
  2156. X    len = 3 * z.len + 32;
  2157. X    tempbuf = zalloctemp(len);
  2158. X
  2159. X    res->sign = 0;
  2160. X    res->v = alloc(z.len * 2);
  2161. X    res->len = dosquare(z.v, z.len, res->v);
  2162. X}
  2163. X
  2164. X
  2165. X/*
  2166. X * Recursive routine to square a number by splitting it up into two numbers
  2167. X * of half the size, and using the results of squaring the subpieces.
  2168. X * The result is placed in the indicated array, which must be large
  2169. X * enough for the result (size * 2).  Returns the size of the result.
  2170. X * This uses a temporary array which must be 3 times as large as the
  2171. X * size of the number at the top level recursive call.
  2172. X */
  2173. Xstatic LEN
  2174. Xdosquare(vp, size, ans)
  2175. X    HALF *vp;        /* value to be squared */
  2176. X    LEN size;        /* length of value to square */
  2177. X    HALF *ans;        /* location for result */
  2178. X{
  2179. X    LEN shift;        /* amount numbers are shifted by */
  2180. X    LEN sizeA;        /* size of left half of number to square */
  2181. X    LEN sizeB;        /* size of right half of number to square */
  2182. X    LEN sizeAA;        /* size of square of left half */
  2183. X    LEN sizeBB;        /* size of square of right half */
  2184. X    LEN sizeAABB;        /* size of sum of squares of A and B */
  2185. X    LEN sizeAB;        /* size of difference of A and B */
  2186. X    LEN sizeABAB;        /* size of square of difference of A and B */
  2187. X    LEN subsize;        /* size of difference of halfs */
  2188. X    LEN copysize;        /* size of number left to copy */
  2189. X    LEN sumsize;        /* size of sum */
  2190. X    LEN sizetotal;        /* total size of square */
  2191. X    LEN len;        /* temporary length */
  2192. X    LEN len1;        /* another temporary length */
  2193. X    FULL carry;        /* carry digit for small multiplications */
  2194. X    FULL digit;        /* single digit multiplying by */
  2195. X    HALF *temp;        /* base for temporary calculations */
  2196. X    HALF *baseA;        /* base of left half of number */
  2197. X    HALF *baseB;        /* base of right half of number */
  2198. X    HALF *baseAA;        /* base of square of left half of number */
  2199. X    HALF *baseBB;        /* base of square of right half of number */
  2200. X    HALF *baseAABB;        /* base of sum of squares of A and B */
  2201. X    HALF *baseAB;        /* base of difference of A and B */
  2202. X    HALF *baseABAB;        /* base of square of difference of A and B */
  2203. X    register HALF *hd, *h1, *h2, *h3;    /* for inner loops */
  2204. X    SIUNION sival;        /* for addition of digits */
  2205. X
  2206. X    /*
  2207. X     * First trim the number of leading zeroes.
  2208. SHAR_EOF
  2209. echo "End of part 13"
  2210. echo "File calc2.9.0/zmul.c is continued in part 14"
  2211. echo "14" > s2_seq_.tmp
  2212. exit 0
  2213.