factor.cpp 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // factor a polynomial or integer
  2. #include "stdafx.h"
  3. #include "defs.h"
  4. void
  5. eval_factor(void)
  6. {
  7. push(cadr(p1));
  8. eval();
  9. push(caddr(p1));
  10. eval();
  11. p2 = pop();
  12. if (p2 == symbol(NIL))
  13. guess();
  14. else
  15. push(p2);
  16. factor();
  17. // more factoring?
  18. p1 = cdddr(p1);
  19. while (iscons(p1)) {
  20. push(car(p1));
  21. eval();
  22. factor_again();
  23. p1 = cdr(p1);
  24. }
  25. }
  26. void
  27. factor_again(void)
  28. {
  29. int h, n;
  30. save();
  31. p2 = pop();
  32. p1 = pop();
  33. h = tos;
  34. if (car(p1) == symbol(MULTIPLY)) {
  35. p1 = cdr(p1);
  36. while (iscons(p1)) {
  37. push(car(p1));
  38. push(p2);
  39. factor_term();
  40. p1 = cdr(p1);
  41. }
  42. } else {
  43. push(p1);
  44. push(p2);
  45. factor_term();
  46. }
  47. n = tos - h;
  48. if (n > 1)
  49. multiply_all_noexpand(n);
  50. restore();
  51. }
  52. void
  53. factor_term(void)
  54. {
  55. save();
  56. factorpoly();
  57. p1 = pop();
  58. if (car(p1) == symbol(MULTIPLY)) {
  59. p1 = cdr(p1);
  60. while (iscons(p1)) {
  61. push(car(p1));
  62. p1 = cdr(p1);
  63. }
  64. } else
  65. push(p1);
  66. restore();
  67. }
  68. void
  69. factor(void)
  70. {
  71. save();
  72. p2 = pop();
  73. p1 = pop();
  74. if (isinteger(p1)) {
  75. push(p1);
  76. factor_number(); // see pollard.cpp
  77. } else {
  78. push(p1);
  79. push(p2);
  80. factorpoly();
  81. }
  82. restore();
  83. }
  84. // for factoring small integers (2^32 or less)
  85. void
  86. factor_small_number(void)
  87. {
  88. int d, expo, i, n;
  89. save();
  90. n = pop_integer();
  91. if (n == (int) 0x80000000)
  92. stop("number too big to factor");
  93. if (n < 0)
  94. n = -n;
  95. for (i = 0; i < MAXPRIMETAB; i++) {
  96. d = primetab[i];
  97. if (d > n / d)
  98. break;
  99. expo = 0;
  100. while (n % d == 0) {
  101. n /= d;
  102. expo++;
  103. }
  104. if (expo) {
  105. push_integer(d);
  106. push_integer(expo);
  107. }
  108. }
  109. if (n > 1) {
  110. push_integer(n);
  111. push_integer(1);
  112. }
  113. restore();
  114. }