Guest User

Untitled

a guest
Sep 21st, 2018
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.90 KB | None | 0 0
  1.  
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <gmp.h>
  5.  
  6. struct linked_mpz
  7. {
  8.   struct linked_mpz *previous;
  9.   mpz_t x;
  10.   struct linked_mpz *next;
  11. };
  12.  
  13. void
  14. toBinary (mpz_t y, int b, mpz_t * x, int n)
  15. {
  16.   mpz_t base;
  17.   mpz_t *xp;
  18.   mpz_init (base);
  19.   mpz_set_ui (base, b);
  20.  
  21.  
  22.   xp = (mpz_t *) malloc (sizeof (mpz_t) * n);
  23.   for (int i = 0; i < n; i++)
  24.     {
  25.       mpz_init (xp[i]);
  26.       mpz_set (xp[i], x[i]);
  27.     }
  28.  
  29.  
  30.   for (int j = 2; j < n * 2; j += j)
  31.     {
  32.       for (int i = 0; i + j / 2 < n; i += j)
  33.     {
  34.       mpz_mul (xp[i + j / 2], xp[i + j / 2], base);
  35.       mpz_add (xp[i], xp[i], xp[i + j / 2]);
  36.     }
  37.       mpz_mul (base, base, base);
  38.     }
  39.   mpz_set (y, xp[0]);
  40.  
  41.   for (int i = 0; i < n; i++)
  42.     {
  43.       mpz_clear (xp[i]);
  44.     }
  45.   free (xp);
  46.  
  47.   mpz_clear (base);
  48. }
  49.  
  50. int
  51. fromBinary (mpz_t ** y, int b, mpz_t x)
  52. {
  53.   int n;
  54.   struct linked_mpz *powers;
  55.   struct linked_mpz *current_power;
  56.   struct linked_mpz *digits;
  57.   mpz_t *yp;
  58.   powers = (struct linked_mpz *) malloc (sizeof (struct linked_mpz));
  59.   mpz_init (powers->x);
  60.   mpz_set_ui (powers->x, b);
  61.   powers->previous = NULL;
  62.  
  63.   for (current_power = powers;
  64.        mpz_cmp (x, current_power->x) >= 0;
  65.        current_power = current_power->next)
  66.     {
  67.       struct linked_mpz *power =
  68.     (struct linked_mpz *) malloc (sizeof (struct linked_mpz));
  69.       mpz_init (power->x);
  70.       mpz_mul (power->x, current_power->x, current_power->x);
  71.  
  72.       power->previous = current_power;
  73.       power->next = NULL;
  74.       current_power->next = power;
  75.     }
  76.  
  77.   digits = (struct linked_mpz *) malloc (sizeof (struct linked_mpz));
  78.   digits->previous = NULL;
  79.   mpz_set (digits->x, x);
  80.   digits->next = NULL;
  81.   for (current_power = current_power->previous; current_power != NULL;
  82.        current_power = current_power->previous)
  83.     {
  84.       struct linked_mpz *digit = digits;
  85.       mpz_t q;
  86.       mpz_t r;
  87.       mpz_init (q);
  88.       mpz_init (r);
  89.       while (digit != NULL)
  90.     {
  91.       mpz_tdiv_qr (q, r, digit->x, current_power->x);
  92.       mpz_set (digit->x, r);
  93.       if (mpz_cmp_ui (q, 0) > 0)
  94.         {
  95.           struct linked_mpz *next_digit =
  96.         (struct linked_mpz *) malloc (sizeof (struct linked_mpz));
  97.           mpz_init (next_digit->x);
  98.           mpz_set (next_digit->x, q);
  99.           next_digit->previous = digit;
  100.           next_digit->next = digit->next;
  101.           digit->next = next_digit;
  102.           if (next_digit->next != NULL)
  103.         {
  104.           next_digit->next->previous = next_digit;
  105.         }
  106.           digit = next_digit->next;
  107.         }
  108.       else
  109.         {
  110.           digit = digit->next;
  111.         }
  112.  
  113.     }
  114.       mpz_clear (r);
  115.       mpz_clear (q);
  116.     }
  117.  
  118.   n = 0;
  119.   for (struct linked_mpz * digit = digits; digit != NULL; digit = digit->next)
  120.     {
  121.       n++;
  122.     }
  123.  
  124.   yp = malloc (sizeof (mpz_t) * n);
  125.   for (int i = 0; i < n; i++)
  126.     {
  127.       mpz_init (yp[i]);
  128.       mpz_set (yp[i], digits->x);
  129.       mpz_clear (digits->x);
  130.       digits = digits->next;
  131.     }
  132.  
  133.   *y = yp;
  134.  
  135.   while (powers != NULL)
  136.     {
  137.       mpz_clear (powers->x);
  138.       powers = powers->next;
  139.     }
  140.  
  141.  
  142.   return n;
  143. }
  144.  
  145. void
  146. factorial (mpz_t x, int n)
  147. {
  148.   mpz_set_ui (x, 1);
  149.   for (int i = 2; i <= n; i++)
  150.     {
  151.       mpz_mul_ui (x, x, i);
  152.     }
  153. }
  154.  
  155. int
  156. main (int argc, char *argv[])
  157. {
  158.   mpz_t t;
  159.   mpz_t *y;
  160.   mpz_t z;
  161.   int n;
  162.   if (argc <= 1)
  163.     {
  164.       return 0;
  165.     }
  166.   if (atoi (argv[1]) < 1)
  167.     {
  168.       return 0;
  169.     }
  170.  
  171.  
  172.   mpz_init (t);
  173.   mpz_init (z);
  174.   factorial (t, atoi (argv[1]));
  175.   n = fromBinary (&y, 10, t);
  176.  
  177.   for (int i = n - 1; i >= 0; i--)
  178.     {
  179.       gmp_printf ("%Zd", y[i]);
  180.     }
  181.   printf ("\n");
  182.  
  183.   mpz_init (z);
  184.   toBinary (z, 10, y, n);
  185.  
  186.   gmp_printf ("%Zd\n", z);
  187.  
  188.   for (int i = mpz_sizeinbase (z, 2) - 1; i >= 0; i--)
  189.     {
  190.       printf ("%d", mpz_tstbit (z, i));
  191.     }
  192.   printf ("\n");
  193.  
  194.   for (int i = 0; i < n; i++)
  195.     {
  196.       mpz_clear (y[i]);
  197.     }
  198.   free (y);
  199.  
  200.   mpz_clear (t);
  201.   mpz_clear (z);
  202.  
  203.   return 0;
  204. }
Add Comment
Please, Sign In to add comment