quickfactor.cpp 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. //-----------------------------------------------------------------------------
  2. //
  3. // Factor small numerical powers
  4. //
  5. // Input: tos-2 Base (positive integer < 2^31 - 1)
  6. //
  7. // tos-1 Exponent
  8. //
  9. // Output: Expr on stack
  10. //
  11. //-----------------------------------------------------------------------------
  12. #include "stdafx.h"
  13. #include "defs.h"
  14. #define BASE p1
  15. #define EXPO p2
  16. static void quickpower(void);
  17. void
  18. quickfactor(void)
  19. {
  20. int h, i, n;
  21. U **s;
  22. save();
  23. EXPO = pop();
  24. BASE = pop();
  25. h = tos;
  26. push(BASE);
  27. factor_small_number();
  28. n = tos - h;
  29. s = stack + h;
  30. for (i = 0; i < n; i += 2) {
  31. push(s[i]); // factored base
  32. push(s[i + 1]); // factored exponent
  33. push(EXPO);
  34. multiply();
  35. quickpower();
  36. }
  37. // stack has n results from factor_number_raw()
  38. // on top of that are all the expressions from quickpower()
  39. // multiply the quickpower() results
  40. multiply_all(tos - h - n);
  41. p1 = pop();
  42. tos = h;
  43. push(p1);
  44. restore();
  45. }
  46. // BASE is a prime number so power is simpler
  47. static void
  48. quickpower(void)
  49. {
  50. int expo;
  51. save();
  52. EXPO = pop();
  53. BASE = pop();
  54. push(EXPO);
  55. bignum_truncate();
  56. p3 = pop();
  57. push(EXPO);
  58. push(p3);
  59. subtract();
  60. p4 = pop();
  61. // fractional part of EXPO
  62. if (!iszero(p4)) {
  63. push_symbol(POWER);
  64. push(BASE);
  65. push(p4);
  66. list(3);
  67. }
  68. push(p3);
  69. expo = pop_integer();
  70. if (expo == (int) 0x80000000) {
  71. push_symbol(POWER);
  72. push(BASE);
  73. push(p3);
  74. list(3);
  75. restore();
  76. return;
  77. }
  78. if (expo == 0) {
  79. restore();
  80. return;
  81. }
  82. push(BASE);
  83. bignum_power_number(expo);
  84. restore();
  85. }