home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1712 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  20.4 KB

  1. From: markb@giga.slc.unisys.com (Mark Baranowski)
  2. Newsgroups: alt.sources
  3. Subject: BN.c: Performing arithmetic on arbitrarily long integers
  4. Message-ID: <703@giga.slc.unisys.com>
  5. Date: 21 Aug 90 21:57:15 GMT
  6.  
  7.  
  8. echo x - README
  9. sed 's/^X//' >README <<'*-*-END-of-README-*-*'
  10. XOverview:
  11. X
  12. X    This library is a collection of routines that allows you to
  13. X    add, subtract, multiply, and divide arbitrarily long integers
  14. X    (BigNums).  This library also contains routines for converting
  15. X    ascii strings to BigNums, converting BigNums to ascii strings,
  16. X    and comparing two BigNums against each other.
  17. X
  18. X
  19. XFeatures:
  20. X
  21. X    Input/output, multiplication, division, addition, subtraction,
  22. X    and comparison (i.e. <, <=, >, >=, !=, ==).
  23. X
  24. X    Arbitrarily long integers are obtainable by adjusting the
  25. X    constant BN_SIZE in the file BN.h to the number of 32-bit
  26. X    chunks desired and then recompiling.  This size may be from 1
  27. X    up to any desired maximum.
  28. X
  29. X    Overflow is detected for multiplication, addition, and
  30. X    subtraction.  The global variable BN_overflow is set to TRUE
  31. X    if an overflow occurs and remains TRUE until reset by the
  32. X    user.  It is up to the user whether or not to ignore
  33. X    BN_overflow.
  34. X
  35. X    The remainder is available immediately following any division
  36. X    via the global variable BN_remainder.  This variable is valid
  37. X    only until the next BigNum operation.
  38. X
  39. X    All arguments are passed by value and the result is returned
  40. X    by value.  Although this slightly increases the overhead, the
  41. X    user interface is simplified.
  42. X
  43. X
  44. XSynopsis:
  45. X
  46. X    #include "BN.h"
  47. X
  48. X
  49. X    /* Remainder following division: */
  50. X    BN BN_remainder;    /* Valid only until next operation */
  51. X
  52. X
  53. X    /* Overflow condition following add, sub, or mult: */
  54. X    Boolean BN_overflow;    /* Valid until reset by the user */
  55. X
  56. X
  57. X    /* Convert an ascii string to a BigNum.
  58. X       User is notified and BN_overflow is set if any overflow occurs. */
  59. X    BN atoBN(str)
  60. X         char *str;
  61. X
  62. X
  63. X    /* Convert a BigNum to an ascii string. */
  64. X    int BNtoa(bignum,str)
  65. X         BN bignum;
  66. X         char *str;
  67. X
  68. X
  69. X    /* Convert a 32 bit integer to a BigNum. */
  70. X    BN itoBN(num)
  71. X         int num;
  72. X
  73. X
  74. X    /* Convert a BigNum to a 32 bit integer.
  75. X       User is warned if any truncation occurs. */
  76. X    int BNtoi(bignum)
  77. X         BN bignum;
  78. X
  79. X
  80. X    /* Multiply two BigNums.
  81. X       BN_overflow is set if any overflow occurs. */
  82. X    BN BN_mult(multiplicand,multiplier)
  83. X         BN multiplicand,multiplier;
  84. X
  85. X
  86. X    /* Divide the dividend by the divisor.
  87. X       The User is notified and program terminated if division by
  88. X       0 occurs.  The global variable BN_remainder contains the
  89. X       remainder of the most recent division. */
  90. X    BN BN_div(dividend,divisor)
  91. X         BN dividend,divisor;
  92. X
  93. X
  94. X    /* Subtract arg2 from arg1.
  95. X       BN_overflow is set if any overflow occurs. */
  96. X    BN BN_sub(arg1,arg2)
  97. X         BN arg1,arg2;
  98. X
  99. X
  100. X    /* Add two BigNums.
  101. X       BN_overflow is set if any overflow occurs. */
  102. X    BN BN_add(arg1,arg2)
  103. X         BN arg1,arg2;
  104. X
  105. X
  106. X    /* Negate a BigNum. */
  107. X    BN BN_neg(arg)
  108. X         BN arg;
  109. X
  110. X
  111. X    /* Test if arg1 is greater than or equal to arg2. */
  112. X    Boolean BN_ge(arg1,arg2)
  113. X         BN arg1,arg2;
  114. X
  115. X
  116. X    /* Test if arg1 is less than or equal to arg2. */
  117. X    Boolean BN_le(arg1,arg2)
  118. X         BN arg1,arg2;
  119. X
  120. X
  121. X    /* Test if arg1 is greater than arg2. */
  122. X    Boolean BN_gt(arg1,arg2)
  123. X         BN arg1,arg2;
  124. X
  125. X
  126. X    /* Test if arg1 is less than arg2. */
  127. X    Boolean BN_lt(arg1,arg2)
  128. X         BN arg1,arg2;
  129. X
  130. X
  131. X    /* Test if arg1 is not equal to arg2. */
  132. X    Boolean BN_ne(arg1,arg2)
  133. X         BN arg1,arg2;
  134. X
  135. X
  136. X    /* Test if arg1 is equal to arg2. */
  137. X    Boolean BN_eq(arg1,arg2)
  138. X         BN arg1,arg2;
  139. X
  140. X
  141. XExample:
  142. X    
  143. X    /**************************/
  144. X    /* Using 32-bit integers: */
  145. X    
  146. X    main()
  147. X    {
  148. X        int i,j,n;
  149. X    
  150. X        j = 10000000000000000;
  151. X    
  152. X        /* Find first factorial greater than j: */
  153. X        i = 1;
  154. X        n = 1;
  155. X        while (i <= j)
  156. X        {
  157. X        i = i * n;
  158. X        n++;
  159. X        }
  160. X        printf("%d\n", i);
  161. X    }
  162. X    
  163. X        
  164. X    /******************/
  165. X    /* Using BigNums: */
  166. X    
  167. X    #include "BN.h"
  168. X    main()
  169. X    {
  170. X        BN i,j,n;
  171. X        char str[11*BN_SIZE];
  172. X    
  173. X        j = atoBN("10000000000000000");
  174. X    
  175. X        /* Find first factorial greater than j: */
  176. X        i = itoBN(1);
  177. X        n = itoBN(1);
  178. X        while (BN_le (i, j))
  179. X        {
  180. X        i = BN_mult(i, n);
  181. X        n = BN_add (n, itoBN(1));
  182. X    
  183. X        /* Check for overflow: */
  184. X        if (BN_overflow)
  185. X        {
  186. X            printf("BigNum overflow\n");
  187. X            exit (1);
  188. X        }
  189. X        }
  190. X    
  191. X        BNtoa(i,str);
  192. X        printf("%s\n", str);
  193. X    }
  194. X
  195. X
  196. X
  197. XTo compile:
  198. X
  199. X    cc yourprogram.c BN.c
  200. X
  201. X
  202. XRanges:
  203. X
  204. X    Different ranges can be obtained by changing the constant
  205. X    BN_SIZE in "BN.h".  The following table gives the maximum
  206. X    power of 10 and the maximum factorial obtainable for a given
  207. X    BN_SIZE:
  208. X
  209. X
  210. X    BN_SIZE        10^N        N!
  211. X    -------        ----        --
  212. X       1         10        12
  213. X       2         19        20
  214. X       5         48        39
  215. X      10         97        67
  216. X      20        193           116
  217. X      50        482           245
  218. *-*-END-of-README-*-*
  219. echo x - BN.c
  220. sed 's/^X//' >BN.c <<'*-*-END-of-BN.c-*-*'
  221. X/******************************************************************************
  222. X  BN.c -- A library for performing arithmetic operations on arbitrarily
  223. X        long integers.
  224. X
  225. X  Author: Mark Baranowski (markb@signus.utah.edu)
  226. X
  227. X  Version: 1.0
  228. X  Date: Aug. 20, 1990
  229. X
  230. X  This program is provided "as is" without any warranty of its
  231. X  correctness or of its fitness for a particular purpose.  You may
  232. X  freely distribute and modify this program as long as this header
  233. X  remains intact.
  234. X
  235. X *****************************************************************************/
  236. X
  237. X#include "BN.h"
  238. X
  239. Xtypedef void Nil;
  240. X#define Local static
  241. X
  242. X/* Globally accessable remainder following division: */
  243. XBN BN_remainder;        /* Valid only until next operation */
  244. X
  245. X/* Globally accessable overflow condition following add, sub, or mult: */
  246. XBoolean BN_overflow;        /* Valid until reset by the user */
  247. X
  248. X/* Locally defined functions: */
  249. XLocal Nil lshift1(/* BN *arg */);
  250. XLocal Nil rshift1(/* BN *arg */);
  251. X
  252. X/* Locally defined BigNum Constants: */
  253. XLocal BN BN_0  = { 0, /* 0, 0, ..., 0 */};
  254. XLocal BN BN_1  = { 1, /* 0, 0, ..., 0 */};
  255. XLocal BN BN_10 = {10, /* 0, 0, ..., 0 */};
  256. X
  257. X#define MASKSIGN(bignum)  (bignum.N[BN_SIZE-1] & 0x80000000)
  258. X
  259. Xextern void exit();
  260. X
  261. X/******************************************************************************
  262. X
  263. X  atoBN -- Convert an ascii string to a BigNum.
  264. X
  265. X  User is notified and BN_overflow is set if any overflow occurs.
  266. X
  267. X *****************************************************************************/
  268. X
  269. XBN atoBN(str)
  270. X     char *str;
  271. X{
  272. X  BN bignum;
  273. X  Boolean negate;
  274. X  Boolean save_overflow;
  275. X
  276. X  /* Make sure we don't confuse a pre-existing overflow for an overflow that
  277. X     might occur here: */
  278. X  save_overflow = BN_overflow;
  279. X  BN_overflow = FALSE;
  280. X
  281. X  /* Build bignum: */
  282. X
  283. X  if (str[0] == '-')
  284. X  {
  285. X    str++;
  286. X    negate = TRUE;
  287. X  }
  288. X  else
  289. X  {
  290. X    negate = FALSE;
  291. X  }
  292. X
  293. X  bignum = BN_0;
  294. X  while (*str)
  295. X  {
  296. X    if (*str < '0' || *str > '9')
  297. X    {
  298. X      (void)printf ("atoBN: non-numeric character in constant\n");
  299. X      exit (1);
  300. X    }
  301. X    bignum = BN_add(BN_mult(BN_10,bignum), itoBN(*str++ - '0'));
  302. X  }
  303. X  if (negate) bignum = BN_neg(bignum);
  304. X
  305. X  /* Notify user of any overflows and restore overflow condition if it
  306. X     existed previously: */
  307. X  if (BN_overflow) (void)printf("atoBN: string overflowed bignum\n");
  308. X  BN_overflow = BN_overflow || save_overflow;
  309. X
  310. X  return (bignum);
  311. X}
  312. X
  313. X
  314. X/******************************************************************************
  315. X
  316. X  BNtoa -- Convert a BigNum to an ascii string.
  317. X
  318. X *****************************************************************************/
  319. X
  320. Xint BNtoa(bignum,str)
  321. X     BN bignum;
  322. X     char *str;
  323. X{
  324. X  register int i,j,k;
  325. X  register char tmp;
  326. X
  327. X  /* If negative then output '-' and change to a positive number: */
  328. X  if (MASKSIGN(bignum))
  329. X  {
  330. X    *str++ = '-';
  331. X    bignum = BN_neg(bignum);
  332. X  }
  333. X
  334. X  /* Strip off numbers in reverse order: */
  335. X  i = 0;
  336. X  do
  337. X  {
  338. X    bignum = BN_div(bignum, BN_10);
  339. X    str[i++] = '0' + BN_remainder.N[0];
  340. X  } while (BN_gt(bignum, BN_0));
  341. X  str[i] = '\0';
  342. X
  343. X  /* Reverse the order of output string: */
  344. X  j = 0;
  345. X  k = i - 1;
  346. X  while (j < k)
  347. X  {
  348. X    tmp = str[j];
  349. X    str[j++] = str[k];
  350. X    str[k--] = tmp;
  351. X  }
  352. X
  353. X  /* Return the string size: */
  354. X  return (i);
  355. X}
  356. X
  357. X
  358. X/******************************************************************************
  359. X
  360. X  itoBN -- Convert a 32 bit integer to a BigNum.
  361. X
  362. X *****************************************************************************/
  363. X
  364. XBN itoBN(num)
  365. X     int num;
  366. X{
  367. X  BN bignum;
  368. X  int i, filler;
  369. X
  370. X  /* Assign num to first 32 bits of bignum and add the appropriate
  371. X     filler for the remaining bits depending on the sign: */
  372. X
  373. X  bignum.N[0] = num;
  374. X  if (num < 0)
  375. X    filler = -1;
  376. X  else
  377. X    filler = 0;
  378. X
  379. X  for (i = 1; i < BN_SIZE; i++)
  380. X    bignum.N[i] = filler;
  381. X
  382. X  return (bignum);
  383. X}
  384. X
  385. X
  386. X/******************************************************************************
  387. X
  388. X  BNtoi -- Convert a BigNum to a 32 bit integer.
  389. X
  390. X  User is warned if any truncation occurs.
  391. X
  392. X *****************************************************************************/
  393. X
  394. Xint BNtoi(bignum)
  395. X     BN bignum;
  396. X{
  397. X# define  BN_abs(bn)  (MASKSIGN(bn) ? BN_neg(bn) : bn)
  398. X
  399. X  if (BN_gt (BN_abs(bignum), itoBN(0x7fffffff)))
  400. X    (void)printf ("BNtoi: integer truncated\n");
  401. X
  402. X  /* Return the lowest 32 bits of a bignum: */
  403. X  return ((int)bignum.N[0]);
  404. X}
  405. X
  406. X
  407. X/******************************************************************************
  408. X
  409. X  BN_mult -- Multiply two BigNums.
  410. X
  411. X  BN_overflow is set if any overflow occurs.
  412. X
  413. X *****************************************************************************/
  414. X
  415. XBN BN_mult(multiplicand,multiplier)
  416. X     BN multiplicand,multiplier;
  417. X{
  418. X  BN result;
  419. X  Boolean s1,s2;
  420. X  register Boolean danger;
  421. X  register int i,j;
  422. X
  423. X  /* Note whether either argument is negative and make sure both of them
  424. X     are positive: */
  425. X  s1 = MASKSIGN(multiplicand);
  426. X  s2 = MASKSIGN(multiplier);
  427. X  if (s1) multiplicand = BN_neg(multiplicand);
  428. X  if (s2) multiplier = BN_neg(multiplier);
  429. X
  430. X  /* Perform multiplication by shifting the multiplicand and performing an
  431. X     addition whenever a '1' appears in the multiplier: */
  432. X  danger = FALSE;
  433. X  result = BN_0;
  434. X  for (i = 0; i < BN_SIZE; i++)
  435. X  {
  436. X    for (j = 0; j < 32; j++)
  437. X    {
  438. X      if (BN_eq (multiplier, BN_0)) break;
  439. X      if (multiplier.N[0] & 1)
  440. X      {
  441. X    /* BN_add also detects certain overflows. */
  442. X    result = BN_add(result,multiplicand);
  443. X    /* Overflow occurs either by addition or by adding the multiplicand
  444. X       after shifting it out of range. */
  445. X    BN_overflow = BN_overflow || danger;
  446. X      }
  447. X      lshift1(&multiplicand);
  448. X      rshift1(&multiplier);
  449. X      danger = danger || (MASKSIGN(multiplicand) ? TRUE : FALSE);
  450. X    }
  451. X  }
  452. X
  453. X  /* Ensure the result has the appropriate sign: */
  454. X  if (s1 != s2) result = BN_neg(result);
  455. X
  456. X  return (result);
  457. X}
  458. X
  459. X
  460. X/******************************************************************************
  461. X
  462. X  BN_div -- Divide the dividend by the divisor.
  463. X
  464. X  The User is notified and program terminated if division by 0 occurs.
  465. X  The global variable BN_remainder contains the remainder of the most
  466. X  recent division.
  467. X
  468. X *****************************************************************************/
  469. X
  470. XBN BN_div(dividend,divisor)
  471. X     BN dividend,divisor;
  472. X{
  473. X  BN result,power;
  474. X  register int nshifts;
  475. X  Boolean s1,s2;
  476. X
  477. X  if (BN_eq(divisor, BN_0))
  478. X  {
  479. X    (void)printf("BN_div: division by 0\n");
  480. X    exit (1);
  481. X  }
  482. X
  483. X  /* Note whether either argument is negative and make sure both of them
  484. X     are positive: */
  485. X  s1 = MASKSIGN(dividend);
  486. X  s2 = MASKSIGN(divisor);
  487. X  if (s1) dividend = BN_neg(dividend);
  488. X  if (s2) divisor = BN_neg(divisor);
  489. X
  490. X  /* Perform division by shifting the divisor up by powers of two until
  491. X     it is greater than the dividend.  Next shift the divisor down in
  492. X     powers of two--each time the dividend can be divided by the divisor
  493. X     tally the current power of two and reduce the dividend accordingly: */
  494. X  power = BN_1;
  495. X  nshifts = 0;
  496. X  while (MASKSIGN(divisor) == 0 && BN_ge(dividend,divisor))
  497. X  {
  498. X    lshift1(&divisor);
  499. X    lshift1(&power);
  500. X    nshifts++;
  501. X  }
  502. X  result = BN_0;
  503. X  while (nshifts > 0)
  504. X  {
  505. X    rshift1(&divisor);
  506. X    rshift1(&power);
  507. X    nshifts--;
  508. X    if (BN_ge(dividend,divisor))
  509. X    {
  510. X      result = BN_add(result,power);
  511. X      dividend = BN_sub(dividend,divisor);
  512. X    }
  513. X  }
  514. X  
  515. X  /* Ensure the result has the appropriate sign and make the remainder
  516. X     globally available: */
  517. X  if (s1 != s2) result = BN_neg(result);
  518. X  BN_remainder = dividend;
  519. X
  520. X  return (result);
  521. X}
  522. X
  523. X
  524. X/******************************************************************************
  525. X
  526. X  BN_sub -- Subtract arg2 from arg1.
  527. X
  528. X  BN_overflow is set if any overflow occurs.
  529. X
  530. X *****************************************************************************/
  531. X
  532. XBN BN_sub(arg1,arg2)
  533. X     BN arg1,arg2;
  534. X{
  535. X  /* Perform subtraction by negating the subtrahend and then adding
  536. X     both numbers: */
  537. X  return (BN_add(arg1,BN_neg(arg2)));
  538. X}
  539. X
  540. X
  541. X/******************************************************************************
  542. X
  543. X  BN_add -- Add two BigNums.
  544. X
  545. X  BN_overflow is set if any overflow occurs.
  546. X
  547. X *****************************************************************************/
  548. X
  549. XBN BN_add(arg1,arg2)
  550. X     BN arg1,arg2;
  551. X{
  552. X  BN result;
  553. X  register int i;
  554. X  register int ssum;
  555. X  register int a1,a2,carry;
  556. X  int criterion;
  557. X
  558. X  /* Perform addition in 32 bit chunks by first striping off the sign
  559. X     bits of each chunk, adding the numbers, manually appending the
  560. X     sign bit, and then generating a carry if necessary: */
  561. X
  562. X  carry = 0;
  563. X  for (i = 0; i < BN_SIZE; i++)
  564. X  {
  565. X    a1 = arg1.N[i] & 0x7fffffff;
  566. X    a2 = arg2.N[i] & 0x7fffffff;
  567. X    result.N[i] = a1 + a2 + carry;
  568. X
  569. X    ssum = 0;
  570. X    if (arg1.N[i] & 0x80000000) ssum++;
  571. X    if (arg2.N[i] & 0x80000000) ssum++;
  572. X    if (result.N[i] & 0x80000000) ssum++;
  573. X
  574. X    if (ssum == 0)
  575. X    {
  576. X      carry = 0;
  577. X    }
  578. X    else if (ssum == 1)
  579. X    {
  580. X      result.N[i] |= 0x80000000;
  581. X      carry = 0;
  582. X    }
  583. X    else if (ssum == 2)
  584. X    {
  585. X      result.N[i] &= 0x7fffffff;
  586. X      carry = 1;
  587. X    }
  588. X    else /* (ssum == 3) */
  589. X    {
  590. X      carry = 1;
  591. X    }
  592. X  }
  593. X
  594. X  /* Check for overflow.  The overflow "criterion" is always an even
  595. X     number unless an overflow occurs: */
  596. X  criterion = ((MASKSIGN(arg1) ? 1 : 0) +
  597. X           (MASKSIGN(arg2) ? 1 : 0) +
  598. X           (MASKSIGN(result) ? 1 : 0) +
  599. X           carry);
  600. X  BN_overflow = BN_overflow || (criterion == 1 || criterion == 3);
  601. X
  602. X  return (result);
  603. X}
  604. X
  605. X
  606. X/******************************************************************************
  607. X
  608. X  BN_neg -- Negate a BigNum.
  609. X
  610. X *****************************************************************************/
  611. X
  612. XBN BN_neg(arg)
  613. X     BN arg;
  614. X{
  615. X  register int i;
  616. X
  617. X  /* Perform negation a la two's complement (i.e. perform a bitwise
  618. X     complement and then add 1): */
  619. X
  620. X  for (i = 0; i < BN_SIZE; i++)
  621. X    arg.N[i] = ~arg.N[i];
  622. X
  623. X  return (BN_add(arg,BN_1));
  624. X}
  625. X
  626. X
  627. X/******************************************************************************
  628. X
  629. X  BN_ge --  Test if arg1 is greater than or equal to arg2.
  630. X
  631. X *****************************************************************************/
  632. X
  633. XBoolean BN_ge(arg1,arg2)
  634. X     BN arg1,arg2;
  635. X{
  636. X  return (!BN_lt(arg1,arg2));
  637. X}
  638. X
  639. X
  640. X/******************************************************************************
  641. X
  642. X  BN_le --  Test if arg1 is less than or equal to arg2.
  643. X
  644. X *****************************************************************************/
  645. X
  646. XBoolean BN_le(arg1,arg2)
  647. X     BN arg1,arg2;
  648. X{
  649. X  return (BN_lt(arg1,arg2) || BN_eq(arg1,arg2));
  650. X}
  651. X
  652. X
  653. X/******************************************************************************
  654. X
  655. X  BN_gt --  Test if arg1 is greater than arg2.
  656. X
  657. X *****************************************************************************/
  658. X
  659. XBoolean BN_gt(arg1,arg2)
  660. X     BN arg1,arg2;
  661. X{
  662. X  return (!BN_lt(arg1,arg2) && !BN_eq(arg1,arg2));
  663. X}
  664. X
  665. X
  666. X/******************************************************************************
  667. X
  668. X  BN_lt --  Test if arg1 is less than arg2.
  669. X
  670. X *****************************************************************************/
  671. X
  672. XBoolean BN_lt(arg1,arg2)
  673. X     BN arg1,arg2;
  674. X{
  675. X  Boolean s1,s2;
  676. X  register int i;
  677. X
  678. X  /* Test if arg1 is less than arg2 by first comparing signs.  If both
  679. X     signs are different, then the rest is easy.  If both signs are the
  680. X     same then begin looking from the high order bits down to the low
  681. X     order bits until a difference is detected: */
  682. X
  683. X  s1 = (MASKSIGN(arg1) ? TRUE : FALSE);
  684. X  s2 = (MASKSIGN(arg2) ? TRUE : FALSE);
  685. X
  686. X  if (s1 && !s2)
  687. X    return (TRUE);
  688. X  else if (!s1 && s2)
  689. X    return (FALSE);
  690. X  else
  691. X    for (i = BN_SIZE-1; i >= 0; i--)
  692. X      if (arg1.N[i] != arg2.N[i])
  693. X      {
  694. X    if (arg1.N[i] < arg2.N[i])
  695. X      return (TRUE);
  696. X    else /* (arg1.N[i] > arg2.N[i]) */
  697. X      return (FALSE);
  698. X      }
  699. X  return (FALSE);
  700. X}
  701. X
  702. X
  703. X/******************************************************************************
  704. X
  705. X  BN_ne --  Test if arg1 is not equal to arg2.
  706. X
  707. X *****************************************************************************/
  708. X
  709. XBoolean BN_ne(arg1,arg2)
  710. X     BN arg1,arg2;
  711. X{
  712. X  return(!BN_eq(arg1,arg2));
  713. X}
  714. X
  715. X
  716. X/******************************************************************************
  717. X
  718. X  BN_eq --  Test if arg1 is equal to arg2.
  719. X
  720. X *****************************************************************************/
  721. X
  722. XBoolean BN_eq(arg1,arg2)
  723. X     BN arg1,arg2;
  724. X{
  725. X  register int i;
  726. X
  727. X  for (i = 0; i < BN_SIZE; i++)
  728. X    if (arg1.N[i] != arg2.N[i]) return (FALSE);
  729. X
  730. X  return (TRUE);
  731. X}
  732. X
  733. X
  734. X/******************************************************************************
  735. X
  736. X  lshift1 -- Perform a logical left shift one bit possition.
  737. X
  738. X *****************************************************************************/
  739. X
  740. XLocal Nil lshift1(arg)
  741. X     register BN *arg;
  742. X{
  743. X  register int i;
  744. X
  745. X  for (i = BN_SIZE - 1; i > 0; i--)
  746. X  {
  747. X    arg->N[i] = arg->N[i] << 1;
  748. X    if (arg->N[i-1] & 0x80000000)
  749. X      arg->N[i] |= 1;
  750. X  }
  751. X
  752. X  arg->N[0] = arg->N[0] << 1;
  753. X
  754. X  return;
  755. X}
  756. X
  757. X
  758. X/******************************************************************************
  759. X
  760. X  rshift1 -- Perform a logical right shift one bit possition.
  761. X
  762. X *****************************************************************************/
  763. X
  764. XLocal Nil rshift1(arg)
  765. X     register BN *arg;
  766. X{
  767. X  register int i;
  768. X
  769. X  for (i = 0; i < BN_SIZE - 1; i++)
  770. X  {
  771. X    arg->N[i] = arg->N[i] >> 1;
  772. X    if (arg->N[i+1] & 1)
  773. X      arg->N[i] |= 0x80000000;
  774. X  }
  775. X
  776. X  arg->N[BN_SIZE-1] = arg->N[BN_SIZE-1] >> 1;
  777. X
  778. X  return;
  779. X}
  780. *-*-END-of-BN.c-*-*
  781. echo x - BN.h
  782. sed 's/^X//' >BN.h <<'*-*-END-of-BN.h-*-*'
  783. X/******************************************************************************
  784. X  BN.h -- A library for performing arithmetic operations on arbitrarily
  785. X        long integers.
  786. X
  787. X  Author: Mark Baranowski (markb@signus.utah.edu)
  788. X
  789. X  Version: 1.0
  790. X  Date: Aug. 20, 1990
  791. X
  792. X  This program is provided "as is" without any warranty of its
  793. X  correctness or of its fitness for a particular purpose.  You may
  794. X  freely distribute and modify this program as long as this header
  795. X  remains intact.
  796. X
  797. X *****************************************************************************/
  798. X
  799. X/* Number of 32 bit chunks used by BigNum--BN_SIZE must be at least 1 and
  800. X   can be any desired maximum: */
  801. X#define BN_SIZE 5
  802. X
  803. X/* BN data structure: */
  804. Xstruct BN
  805. X{
  806. X  unsigned int N[BN_SIZE];
  807. X};
  808. Xtypedef struct BN BN;
  809. X
  810. Xtypedef int Boolean;
  811. X#define TRUE 1
  812. X#define FALSE 0
  813. X
  814. X/* BigNum remainder following division: */
  815. Xextern BN BN_remainder;        /* Valid only until next operation */
  816. X
  817. X/* BigNum overflow condition following add, subtract, or multiply: */
  818. Xextern Boolean BN_overflow;    /* Valid until reset by the user */
  819. X
  820. X/* Globally defined funtions: */
  821. Xextern BN  atoBN (/* char *str */);
  822. Xextern int BNtoa (/* BN bignum, char *str */);
  823. Xextern BN  itoBN (/* int num */);
  824. Xextern int BNtoi (/* BN bignum */);
  825. X
  826. Xextern BN BN_mult(/* BN arg1, BN arg2 */);
  827. Xextern BN BN_div (/* BN arg1, BN arg2 */);
  828. Xextern BN BN_sub (/* BN arg1, BN arg2 */);
  829. Xextern BN BN_add (/* BN arg1, BN arg2 */);
  830. Xextern BN BN_neg (/* BN arg1 */);
  831. X
  832. Xextern Boolean BN_ge(/* BN arg1, BN arg2 */);
  833. Xextern Boolean BN_le(/* BN arg1, BN arg2 */);
  834. Xextern Boolean BN_gt(/* BN arg1, BN arg2 */);
  835. Xextern Boolean BN_lt(/* BN arg1, BN arg2 */);
  836. Xextern Boolean BN_ne(/* BN arg1, BN arg2 */);
  837. Xextern Boolean BN_eq(/* BN arg1, BN arg2 */);
  838. *-*-END-of-BN.h-*-*
  839. exit
  840.  
  841.  
  842. -- 
  843. Internet: markb@slc.unisys.com            uucp: ...!giga!markb
  844.       markb@signus.utah.edu
  845. Brought to you by the Great State of Utah: Home of Gary Gilmore, Syncrete,
  846. Cold Fusion, Mark Hoffman, Sonja Johnson, John Singer, and Sen. Orrin Hatch.
  847.