mroot.cpp 984 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. //-----------------------------------------------------------------------------
  2. //
  3. // Bignum root
  4. //
  5. // Returns null pointer if not perfect root.
  6. //
  7. // The sign of the radicand is ignored.
  8. //
  9. //-----------------------------------------------------------------------------
  10. #include "stdafx.h"
  11. #include "defs.h"
  12. unsigned int *
  13. mroot(unsigned int *n, unsigned int index)
  14. {
  15. int i, j, k;
  16. unsigned int m, *x, *y;
  17. if (index == 0)
  18. stop("root index is zero");
  19. // count number of bits
  20. k = 32 * (MLENGTH(n) - 1);
  21. m = n[MLENGTH(n) - 1];
  22. while (m) {
  23. m >>= 1;
  24. k++;
  25. }
  26. if (k == 0)
  27. return mint(0);
  28. // initial guess
  29. k = (k - 1) / index;
  30. j = k / 32 + 1;
  31. x = mnew(j);
  32. MSIGN(x) = 1;
  33. MLENGTH(x) = j;
  34. for (i = 0; i < j; i++)
  35. x[i] = 0;
  36. while (k >= 0) {
  37. mp_set_bit(x, k);
  38. y = mpow(x, index);
  39. switch (mcmp(y, n)) {
  40. case -1:
  41. break;
  42. case 0:
  43. mfree(y);
  44. return x;
  45. case 1:
  46. mp_clr_bit(x, k);
  47. break;
  48. }
  49. mfree(y);
  50. k--;
  51. }
  52. mfree(x);
  53. return 0;
  54. }