madd.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // Bignum addition and subtraction
  2. #include "stdafx.h"
  3. #include "defs.h"
  4. static unsigned int *addf(unsigned int *, unsigned int *);
  5. static unsigned int *subf(unsigned int *, unsigned int *);
  6. static int ucmp(unsigned int *, unsigned int *);
  7. unsigned int *
  8. madd(unsigned int *a, unsigned int *b)
  9. {
  10. if (MSIGN(a) == MSIGN(b))
  11. return addf(a, b); // same sign, add together
  12. else
  13. return subf(a, b); // opposite sign, find difference
  14. }
  15. unsigned int *
  16. msub(unsigned int *a, unsigned int *b)
  17. {
  18. if (MSIGN(a) == MSIGN(b))
  19. return subf(a, b); // same sign, find difference
  20. else
  21. return addf(a, b); // opposite sign, add together
  22. }
  23. static unsigned int *
  24. addf(unsigned int *a, unsigned int *b)
  25. {
  26. int i, sign;
  27. unsigned int c, *x;
  28. sign = MSIGN(a);
  29. if (MLENGTH(a) < MLENGTH(b)) {
  30. x = a;
  31. a = b;
  32. b = x;
  33. }
  34. x = mnew(MLENGTH(a) + 1);
  35. c = 0;
  36. for (i = 0; i < MLENGTH(b); i++) {
  37. x[i] = a[i] + b[i] + c;
  38. if (c)
  39. if (a[i] >= x[i])
  40. c = 1;
  41. else
  42. c = 0;
  43. else
  44. if (a[i] > x[i])
  45. c = 1;
  46. else
  47. c = 0;
  48. }
  49. for (i = MLENGTH(b); i < MLENGTH(a); i++) {
  50. x[i] = a[i] + c;
  51. if (a[i] > x[i])
  52. c = 1;
  53. else
  54. c = 0;
  55. }
  56. x[MLENGTH(a)] = c;
  57. for (i = MLENGTH(a); i > 0; i--)
  58. if (x[i])
  59. break;
  60. MLENGTH(x) = i + 1;
  61. MSIGN(x) = sign;
  62. return x;
  63. }
  64. static unsigned int *
  65. subf(unsigned int *a, unsigned int *b)
  66. {
  67. int i, sign = 0;
  68. unsigned int c, *x;
  69. switch (ucmp(a, b)) {
  70. case 0:
  71. return mint(0);
  72. case 1:
  73. sign = MSIGN(a); /* |a| > |b| */
  74. break;
  75. case -1:
  76. sign = -MSIGN(a); /* |a| < |b| */
  77. x = a;
  78. a = b;
  79. b = x;
  80. break;
  81. }
  82. x = mnew(MLENGTH(a));
  83. c = 0;
  84. for (i = 0; i < MLENGTH(b); i++) {
  85. x[i] = a[i] - b[i] - c;
  86. if (c)
  87. if (a[i] <= x[i])
  88. c = 1;
  89. else
  90. c = 0;
  91. else
  92. if (a[i] < x[i])
  93. c = 1;
  94. else
  95. c = 0;
  96. }
  97. for (i = MLENGTH(b); i < MLENGTH(a); i++) {
  98. x[i] = a[i] - c;
  99. if (a[i] < x[i])
  100. c = 1;
  101. else
  102. c = 0;
  103. }
  104. for (i = MLENGTH(a) - 1; i > 0; i--)
  105. if (x[i])
  106. break;
  107. MLENGTH(x) = i + 1;
  108. MSIGN(x) = sign;
  109. return x;
  110. }
  111. // unsigned compare
  112. static int
  113. ucmp(unsigned int *a, unsigned int *b)
  114. {
  115. int i;
  116. if (MLENGTH(a) < MLENGTH(b))
  117. return -1;
  118. if (MLENGTH(a) > MLENGTH(b))
  119. return 1;
  120. for (i = MLENGTH(a) - 1; i > 0; i--)
  121. if (a[i] != b[i])
  122. break;
  123. if (a[i] < b[i])
  124. return -1;
  125. if (a[i] > b[i])
  126. return 1;
  127. return 0;
  128. }