reuse.c
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:18k
源码类别:

数学计算

开发平台:

Unix_Linux

  1. /* Test that routines allow reusing a source variable as destination.
  2.    Test all relevant functions except:
  3. mpz_bin_ui
  4. mpz_nextprime
  5. mpz_mul_si
  6. mpz_addmul_ui (should this really allow a+=a*c?)
  7. Copyright 1996, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc.
  8. This file is part of the GNU MP Library.
  9. The GNU MP Library is free software; you can redistribute it and/or modify
  10. it under the terms of the GNU Lesser General Public License as published by
  11. the Free Software Foundation; either version 3 of the License, or (at your
  12. option) any later version.
  13. The GNU MP Library is distributed in the hope that it will be useful, but
  14. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  15. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  16. License for more details.
  17. You should have received a copy of the GNU Lesser General Public License
  18. along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include "gmp.h"
  23. #include "gmp-impl.h"
  24. #include "tests.h"
  25. #if __GMP_LIBGMP_DLL
  26. /* FIXME: When linking to a DLL libgmp, mpz_add etc can't be used as
  27.    initializers for global variables because they're effectively global
  28.    variables (function pointers) themselves.  Perhaps calling a test
  29.    function successively with mpz_add etc would be better.  */
  30. int
  31. main (void)
  32. {
  33.   printf ("Test suppressed for windows DLLn");
  34.   exit (0);
  35. }
  36. #else /* ! DLL_EXPORT */
  37. void dump __GMP_PROTO ((char *, mpz_t, mpz_t, mpz_t));
  38. typedef void (*dss_func) __GMP_PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));
  39. typedef void (*dsi_func) __GMP_PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
  40. typedef unsigned long int (*dsi_div_func) __GMP_PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
  41. typedef unsigned long int (*ddsi_div_func) __GMP_PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));
  42. typedef void (*ddss_div_func) __GMP_PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
  43. typedef void (*ds_func) __GMP_PROTO ((mpz_ptr, mpz_srcptr));
  44. void
  45. mpz_xinvert (mpz_ptr r, mpz_srcptr a, mpz_srcptr b)
  46. {
  47.   int res;
  48.   res = mpz_invert (r, a, b);
  49.   if (res == 0)
  50.     mpz_set_ui (r, 0);
  51. }
  52. dss_func dss_funcs[] =
  53. {
  54.   mpz_add, mpz_sub, mpz_mul,
  55.   mpz_cdiv_q, mpz_cdiv_r, mpz_fdiv_q, mpz_fdiv_r, mpz_tdiv_q, mpz_tdiv_r,
  56.   mpz_xinvert,
  57.   mpz_gcd, mpz_lcm, mpz_and, mpz_ior, mpz_xor
  58. };
  59. char *dss_func_names[] =
  60. {
  61.   "mpz_add", "mpz_sub", "mpz_mul",
  62.   "mpz_cdiv_q", "mpz_cdiv_r", "mpz_fdiv_q", "mpz_fdiv_r", "mpz_tdiv_q", "mpz_tdiv_r",
  63.   "mpz_xinvert",
  64.   "mpz_gcd", "mpz_lcm", "mpz_and", "mpz_ior", "mpz_xor"
  65. };
  66. char dss_func_division[] = {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};
  67. dsi_func dsi_funcs[] =
  68. {
  69.   /* Don't change order here without changing the code in main(). */
  70.   mpz_add_ui, mpz_mul_ui, mpz_sub_ui,
  71.   mpz_fdiv_q_2exp, mpz_fdiv_r_2exp,
  72.   mpz_cdiv_q_2exp, mpz_cdiv_r_2exp,
  73.   mpz_tdiv_q_2exp, mpz_tdiv_r_2exp,
  74.   mpz_mul_2exp,
  75.   mpz_pow_ui
  76. };
  77. char *dsi_func_names[] =
  78. {
  79.   "mpz_add_ui", "mpz_mul_ui", "mpz_sub_ui",
  80.   "mpz_fdiv_q_2exp", "mpz_fdiv_r_2exp",
  81.   "mpz_cdiv_q_2exp", "mpz_cdiv_r_2exp",
  82.   "mpz_tdiv_q_2exp", "mpz_tdiv_r_2exp",
  83.   "mpz_mul_2exp",
  84.   "mpz_pow_ui"
  85. };
  86. dsi_div_func dsi_div_funcs[] =
  87. {
  88.   mpz_cdiv_q_ui, mpz_cdiv_r_ui,
  89.   mpz_fdiv_q_ui, mpz_fdiv_r_ui,
  90.   mpz_tdiv_q_ui, mpz_tdiv_r_ui
  91. };
  92. char *dsi_div_func_names[] =
  93. {
  94.   "mpz_cdiv_q_ui", "mpz_cdiv_r_ui",
  95.   "mpz_fdiv_q_ui", "mpz_fdiv_r_ui",
  96.   "mpz_tdiv_q_ui", "mpz_tdiv_r_ui"
  97. };
  98. ddsi_div_func ddsi_div_funcs[] =
  99. {
  100.   mpz_cdiv_qr_ui,
  101.   mpz_fdiv_qr_ui,
  102.   mpz_tdiv_qr_ui
  103. };
  104. char *ddsi_div_func_names[] =
  105. {
  106.   "mpz_cdiv_qr_ui",
  107.   "mpz_fdiv_qr_ui",
  108.   "mpz_tdiv_qr_ui"
  109. };
  110. ddss_div_func ddss_div_funcs[] =
  111. {
  112.   mpz_cdiv_qr,
  113.   mpz_fdiv_qr,
  114.   mpz_tdiv_qr
  115. };
  116. char *ddss_div_func_names[] =
  117. {
  118.   "mpz_cdiv_qr",
  119.   "mpz_fdiv_qr",
  120.   "mpz_tdiv_qr"
  121. };
  122. ds_func ds_funcs[] =
  123. {
  124.   mpz_abs, mpz_com, mpz_neg, mpz_sqrt
  125. };
  126. char *ds_func_names[] =
  127. {
  128.   "mpz_abs", "mpz_com", "mpz_neg", "mpz_sqrt"
  129. };
  130. /* Really use `defined (__STDC__)' here; we want it to be true for Sun C */
  131. #if defined (__STDC__) || defined (__cplusplus)
  132. #define FAIL(class,indx,op1,op2,op3) 
  133.   do {
  134.   class##_funcs[indx] = 0;
  135.   dump (class##_func_names[indx], op1, op2, op3);
  136.   failures++;
  137.   } while (0)
  138. #define FAIL2(fname,op1,op2,op3) 
  139.   do {
  140.   dump (#fname, op1, op2, op3);
  141.   failures++;
  142.   } while (0)
  143. #else
  144. #define FAIL(class,indx,op1,op2,op3) 
  145.   do {
  146.   class/**/_funcs[indx] = 0;
  147.   dump (class/**/_func_names[indx], op1, op2, op3);
  148.   failures++;
  149.   } while (0)
  150. #define FAIL2(fname,op1,op2,op3) 
  151.   do {
  152.   dump ("fname", op1, op2, op3);
  153.   failures++;
  154.   } while (0)
  155. #endif
  156. int
  157. main (int argc, char **argv)
  158. {
  159.   int i;
  160.   int pass, reps = 100;
  161.   mpz_t in1, in2, in3;
  162.   unsigned long int in2i;
  163.   mp_size_t size;
  164.   mpz_t res1, res2, res3;
  165.   mpz_t ref1, ref2, ref3;
  166.   mpz_t t;
  167.   unsigned long int r1, r2;
  168.   long failures = 0;
  169.   gmp_randstate_ptr rands;
  170.   mpz_t bs;
  171.   unsigned long bsi, size_range;
  172.   tests_start ();
  173.   TESTS_REPS (reps, argv, argc);
  174.   rands = RANDS;
  175.   mpz_init (bs);
  176.   mpz_init (in1);
  177.   mpz_init (in2);
  178.   mpz_init (in3);
  179.   mpz_init (ref1);
  180.   mpz_init (ref2);
  181.   mpz_init (ref3);
  182.   mpz_init (res1);
  183.   mpz_init (res2);
  184.   mpz_init (res3);
  185.   mpz_init (t);
  186.   for (pass = 1; pass <= reps; pass++)
  187.     {
  188.       mpz_urandomb (bs, rands, 32);
  189.       size_range = mpz_get_ui (bs) % 17 + 2;
  190.       mpz_urandomb (bs, rands, size_range);
  191.       size = mpz_get_ui (bs);
  192.       mpz_rrandomb (in1, rands, size);
  193.       mpz_urandomb (bs, rands, size_range);
  194.       size = mpz_get_ui (bs);
  195.       mpz_rrandomb (in2, rands, size);
  196.       mpz_urandomb (bs, rands, size_range);
  197.       size = mpz_get_ui (bs);
  198.       mpz_rrandomb (in3, rands, size);
  199.       mpz_urandomb (bs, rands, 3);
  200.       bsi = mpz_get_ui (bs);
  201.       if ((bsi & 1) != 0)
  202. mpz_neg (in1, in1);
  203.       if ((bsi & 1) != 0)
  204. mpz_neg (in2, in2);
  205.       if ((bsi & 1) != 0)
  206. mpz_neg (in3, in3);
  207.       for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++)
  208. {
  209.   if (dss_funcs[i] == 0)
  210.     continue;
  211.   if (dss_func_division[i] && mpz_sgn (in2) == 0)
  212.     continue;
  213.   (dss_funcs[i]) (ref1, in1, in2);
  214.   MPZ_CHECK_FORMAT (ref1);
  215.   mpz_set (res1, in1);
  216.   (dss_funcs[i]) (res1, res1, in2);
  217.   MPZ_CHECK_FORMAT (res1);
  218.   if (mpz_cmp (ref1, res1) != 0)
  219.     FAIL (dss, i, in1, in2, NULL);
  220.   mpz_set (res1, in2);
  221.   (dss_funcs[i]) (res1, in1, res1);
  222.   MPZ_CHECK_FORMAT (res1);
  223.   if (mpz_cmp (ref1, res1) != 0)
  224.     FAIL (dss, i, in1, in2, NULL);
  225. }
  226.       for (i = 0; i < sizeof (ddss_div_funcs) / sizeof (ddss_div_func); i++)
  227. {
  228.   if (ddss_div_funcs[i] == 0)
  229.     continue;
  230.   if (mpz_sgn (in2) == 0)
  231.     continue;
  232.   (ddss_div_funcs[i]) (ref1, ref2, in1, in2);
  233.   MPZ_CHECK_FORMAT (ref1);
  234.   MPZ_CHECK_FORMAT (ref2);
  235.   mpz_set (res1, in1);
  236.   (ddss_div_funcs[i]) (res1, res2, res1, in2);
  237.   MPZ_CHECK_FORMAT (res1);
  238.   MPZ_CHECK_FORMAT (res2);
  239.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
  240.     FAIL (ddss_div, i, in1, in2, NULL);
  241.   mpz_set (res2, in1);
  242.   (ddss_div_funcs[i]) (res1, res2, res2, in2);
  243.   MPZ_CHECK_FORMAT (res1);
  244.   MPZ_CHECK_FORMAT (res2);
  245.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
  246.     FAIL (ddss_div, i, in1, in2, NULL);
  247.   mpz_set (res1, in2);
  248.   (ddss_div_funcs[i]) (res1, res2, in1, res1);
  249.   MPZ_CHECK_FORMAT (res1);
  250.   MPZ_CHECK_FORMAT (res2);
  251.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
  252.     FAIL (ddss_div, i, in1, in2, NULL);
  253.   mpz_set (res2, in2);
  254.   (ddss_div_funcs[i]) (res1, res2, in1, res2);
  255.   MPZ_CHECK_FORMAT (res1);
  256.   MPZ_CHECK_FORMAT (res2);
  257.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
  258.     FAIL (ddss_div, i, in1, in2, NULL);
  259. }
  260.       for (i = 0; i < sizeof (ds_funcs) / sizeof (ds_func); i++)
  261. {
  262.   if (ds_funcs[i] == 0)
  263.     continue;
  264.   if (strcmp (ds_func_names[i], "mpz_sqrt") == 0
  265.       && mpz_sgn (in1) < 0)
  266.     continue;
  267.   (ds_funcs[i]) (ref1, in1);
  268.   MPZ_CHECK_FORMAT (ref1);
  269.   mpz_set (res1, in1);
  270.   (ds_funcs[i]) (res1, res1);
  271.   MPZ_CHECK_FORMAT (res1);
  272.   if (mpz_cmp (ref1, res1) != 0)
  273.     FAIL (ds, i, in1, in2, NULL);
  274. }
  275.       in2i = mpz_get_ui (in2);
  276.       for (i = 0; i < sizeof (dsi_funcs) / sizeof (dsi_func); i++)
  277. {
  278.   if (dsi_funcs[i] == 0)
  279.     continue;
  280.   if (strcmp (dsi_func_names[i], "mpz_fdiv_q_2exp") == 0)
  281.     /* Limit exponent to something reasonable for the division
  282.        functions.  Without this, we'd  normally shift things off
  283.        the end and just generate the trivial values 1, 0, -1.  */
  284.     in2i %= 0x1000;
  285.   if (strcmp (dsi_func_names[i], "mpz_mul_2exp") == 0)
  286.     /* Limit exponent more for mpz_mul_2exp to save time.  */
  287.     in2i %= 0x100;
  288.   if (strcmp (dsi_func_names[i], "mpz_pow_ui") == 0)
  289.     /* Limit exponent yet more for mpz_pow_ui to save time.  */
  290.     in2i %= 0x10;
  291.   (dsi_funcs[i]) (ref1, in1, in2i);
  292.   MPZ_CHECK_FORMAT (ref1);
  293.   mpz_set (res1, in1);
  294.   (dsi_funcs[i]) (res1, res1, in2i);
  295.   MPZ_CHECK_FORMAT (res1);
  296.   if (mpz_cmp (ref1, res1) != 0)
  297.     FAIL (dsi, i, in1, in2, NULL);
  298. }
  299.       if (in2i != 0)   /* Don't divide by 0.  */
  300. {
  301.   for (i = 0; i < sizeof (dsi_div_funcs) / sizeof (dsi_div_funcs); i++)
  302.     {
  303.       r1 = (dsi_div_funcs[i]) (ref1, in1, in2i);
  304.       MPZ_CHECK_FORMAT (ref1);
  305.       mpz_set (res1, in1);
  306.       r2 = (dsi_div_funcs[i]) (res1, res1, in2i);
  307.       MPZ_CHECK_FORMAT (res1);
  308.       if (mpz_cmp (ref1, res1) != 0 || r1 != r2)
  309. FAIL (dsi_div, i, in1, in2, NULL);
  310.     }
  311.   for (i = 0; i < sizeof (ddsi_div_funcs) / sizeof (ddsi_div_funcs); i++)
  312.     {
  313.       r1 = (ddsi_div_funcs[i]) (ref1, ref2, in1, in2i);
  314.       MPZ_CHECK_FORMAT (ref1);
  315.       mpz_set (res1, in1);
  316.       r2 = (ddsi_div_funcs[i]) (res1, res2, res1, in2i);
  317.       MPZ_CHECK_FORMAT (res1);
  318.       if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
  319. FAIL (ddsi_div, i, in1, in2, NULL);
  320.       mpz_set (res2, in1);
  321.       (ddsi_div_funcs[i]) (res1, res2, res2, in2i);
  322.       MPZ_CHECK_FORMAT (res1);
  323.       if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2)
  324. FAIL (ddsi_div, i, in1, in2, NULL);
  325.     }
  326. }
  327.       if (mpz_sgn (in1) >= 0)
  328. {
  329.   mpz_sqrtrem (ref1, ref2, in1);
  330.   MPZ_CHECK_FORMAT (ref1);
  331.   MPZ_CHECK_FORMAT (ref2);
  332.   mpz_set (res1, in1);
  333.   mpz_sqrtrem (res1, res2, res1);
  334.   MPZ_CHECK_FORMAT (res1);
  335.   MPZ_CHECK_FORMAT (res2);
  336.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
  337.     FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
  338.   mpz_set (res2, in1);
  339.   mpz_sqrtrem (res1, res2, res2);
  340.   MPZ_CHECK_FORMAT (res1);
  341.   MPZ_CHECK_FORMAT (res2);
  342.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
  343.     FAIL2 (mpz_sqrtrem, in1, NULL, NULL);
  344. }
  345.       if (mpz_sgn (in1) >= 0)
  346. {
  347.   mpz_root (ref1, in1, in2i % 0x1000 + 1);
  348.   MPZ_CHECK_FORMAT (ref1);
  349.   mpz_set (res1, in1);
  350.   mpz_root (res1, res1, in2i % 0x1000 + 1);
  351.   MPZ_CHECK_FORMAT (res1);
  352.   if (mpz_cmp (ref1, res1) != 0)
  353.     FAIL2 (mpz_root, in1, in2, NULL);
  354. }
  355.       if (mpz_sgn (in1) >= 0)
  356. {
  357.   mpz_rootrem (ref1, ref2, in1, in2i % 0x1000 + 1);
  358.   MPZ_CHECK_FORMAT (ref1);
  359.   MPZ_CHECK_FORMAT (ref2);
  360.   mpz_set (res1, in1);
  361.   mpz_rootrem (res1, res2, res1, in2i % 0x1000 + 1);
  362.   MPZ_CHECK_FORMAT (res1);
  363.   MPZ_CHECK_FORMAT (res2);
  364.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
  365.     FAIL2 (mpz_rootrem, in1, in2, NULL);
  366.   mpz_set (res2, in1);
  367.   mpz_rootrem (res1, res2, res2, in2i % 0x1000 + 1);
  368.   MPZ_CHECK_FORMAT (res1);
  369.   MPZ_CHECK_FORMAT (res2);
  370.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0)
  371.     FAIL2 (mpz_rootrem, in1, in2, NULL);
  372. }
  373.       if (pass < reps / 2) /* run fewer tests since gcdext lots of time */
  374. {
  375.   mpz_gcdext (ref1, ref2, ref3, in1, in2);
  376.   MPZ_CHECK_FORMAT (ref1);
  377.   MPZ_CHECK_FORMAT (ref2);
  378.   MPZ_CHECK_FORMAT (ref3);
  379.   mpz_set (res1, in1);
  380.   mpz_gcdext (res1, res2, res3, res1, in2);
  381.   MPZ_CHECK_FORMAT (res1);
  382.   MPZ_CHECK_FORMAT (res2);
  383.   MPZ_CHECK_FORMAT (res3);
  384.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
  385.       || mpz_cmp (ref3, res3) != 0)
  386.     FAIL2 (mpz_gcdext, in1, in2, NULL);
  387.   mpz_set (res2, in1);
  388.   mpz_gcdext (res1, res2, res3, res2, in2);
  389.   MPZ_CHECK_FORMAT (res1);
  390.   MPZ_CHECK_FORMAT (res2);
  391.   MPZ_CHECK_FORMAT (res3);
  392.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
  393.       || mpz_cmp (ref3, res3) != 0)
  394.     FAIL2 (mpz_gcdext, in1, in2, NULL);
  395.   mpz_set (res3, in1);
  396.   mpz_gcdext (res1, res2, res3, res3, in2);
  397.   MPZ_CHECK_FORMAT (res1);
  398.   MPZ_CHECK_FORMAT (res2);
  399.   MPZ_CHECK_FORMAT (res3);
  400.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
  401.       || mpz_cmp (ref3, res3) != 0)
  402.     FAIL2 (mpz_gcdext, in1, in2, NULL);
  403.   mpz_set (res1, in2);
  404.   mpz_gcdext (res1, res2, res3, in1, res1);
  405.   MPZ_CHECK_FORMAT (res1);
  406.   MPZ_CHECK_FORMAT (res2);
  407.   MPZ_CHECK_FORMAT (res3);
  408.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
  409.       || mpz_cmp (ref3, res3) != 0)
  410.     FAIL2 (mpz_gcdext, in1, in2, NULL);
  411.   mpz_set (res2, in2);
  412.   mpz_gcdext (res1, res2, res3, in1, res2);
  413.   MPZ_CHECK_FORMAT (res1);
  414.   MPZ_CHECK_FORMAT (res2);
  415.   MPZ_CHECK_FORMAT (res3);
  416.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
  417.       || mpz_cmp (ref3, res3) != 0)
  418.     FAIL2 (mpz_gcdext, in1, in2, NULL);
  419.   mpz_set (res3, in2);
  420.   mpz_gcdext (res1, res2, res3, in1, res3);
  421.   MPZ_CHECK_FORMAT (res1);
  422.   MPZ_CHECK_FORMAT (res2);
  423.   MPZ_CHECK_FORMAT (res3);
  424.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
  425.       || mpz_cmp (ref3, res3) != 0)
  426.     FAIL2 (mpz_gcdext, in1, in2, NULL);
  427.   mpz_set (res1, in1);
  428.   mpz_gcdext (res1, res2, NULL, res1, in2);
  429.   MPZ_CHECK_FORMAT (res1);
  430.   MPZ_CHECK_FORMAT (res2);
  431.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
  432.       || mpz_cmp (ref3, res3) != 0)
  433.     FAIL2 (mpz_gcdext, in1, in2, NULL);
  434.   mpz_set (res2, in1);
  435.   mpz_gcdext (res1, res2, NULL, res2, in2);
  436.   MPZ_CHECK_FORMAT (res1);
  437.   MPZ_CHECK_FORMAT (res2);
  438.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
  439.       || mpz_cmp (ref3, res3) != 0)
  440.     FAIL2 (mpz_gcdext, in1, in2, NULL);
  441.   mpz_set (res1, in2);
  442.   mpz_gcdext (res1, res2, NULL, in1, res1);
  443.   MPZ_CHECK_FORMAT (res1);
  444.   MPZ_CHECK_FORMAT (res2);
  445.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
  446.       || mpz_cmp (ref3, res3) != 0)
  447.     FAIL2 (mpz_gcdext, in1, in2, NULL);
  448.   mpz_set (res2, in2);
  449.   mpz_gcdext (res1, res2, NULL, in1, res2);
  450.   MPZ_CHECK_FORMAT (res1);
  451.   MPZ_CHECK_FORMAT (res2);
  452.   if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0
  453.       || mpz_cmp (ref3, res3) != 0)
  454.     FAIL2 (mpz_gcdext, in1, in2, NULL);
  455. }
  456.       /* Don't run mpz_powm for huge exponents or when undefined.  */
  457.       if (mpz_sizeinbase (in2, 2) < 250 && mpz_sgn (in3) != 0
  458.   && (mpz_sgn (in2) >= 0 || mpz_invert (t, in1, in3)))
  459. {
  460.   mpz_powm (ref1, in1, in2, in3);
  461.   MPZ_CHECK_FORMAT (ref1);
  462.   mpz_set (res1, in1);
  463.   mpz_powm (res1, res1, in2, in3);
  464.   MPZ_CHECK_FORMAT (res1);
  465.   if (mpz_cmp (ref1, res1) != 0)
  466.     FAIL2 (mpz_powm, in1, in2, in3);
  467.   mpz_set (res1, in2);
  468.   mpz_powm (res1, in1, res1, in3);
  469.   MPZ_CHECK_FORMAT (res1);
  470.   if (mpz_cmp (ref1, res1) != 0)
  471.     FAIL2 (mpz_powm, in1, in2, in3);
  472.   mpz_set (res1, in3);
  473.   mpz_powm (res1, in1, in2, res1);
  474.   MPZ_CHECK_FORMAT (res1);
  475.   if (mpz_cmp (ref1, res1) != 0)
  476.     FAIL2 (mpz_powm, in1, in2, in3);
  477. }
  478.       /* Don't run mpz_powm_ui when undefined.  */
  479.       if (mpz_sgn (in3) != 0)
  480. {
  481.   mpz_powm_ui (ref1, in1, in2i, in3);
  482.   MPZ_CHECK_FORMAT (ref1);
  483.   mpz_set (res1, in1);
  484.   mpz_powm_ui (res1, res1, in2i, in3);
  485.   MPZ_CHECK_FORMAT (res1);
  486.   if (mpz_cmp (ref1, res1) != 0)
  487.     FAIL2 (mpz_powm_ui, in1, in2, in3);
  488.   mpz_set (res1, in3);
  489.   mpz_powm_ui (res1, in1, in2i, res1);
  490.   MPZ_CHECK_FORMAT (res1);
  491.   if (mpz_cmp (ref1, res1) != 0)
  492.     FAIL2 (mpz_powm_ui, in1, in2, in3);
  493. }
  494.       {
  495. r1 = mpz_gcd_ui (ref1, in1, in2i);
  496. MPZ_CHECK_FORMAT (ref1);
  497. mpz_set (res1, in1);
  498. r2 = mpz_gcd_ui (res1, res1, in2i);
  499. MPZ_CHECK_FORMAT (res1);
  500. if (mpz_cmp (ref1, res1) != 0)
  501.   FAIL2 (mpz_gcd_ui, in1, in2, NULL);
  502.       }
  503.       if (mpz_cmp_ui (in2, 1L) > 0 && mpz_sgn (in1) != 0)
  504. {
  505.   /* Test mpz_remove */
  506.   mpz_remove (ref1, in1, in2);
  507.   MPZ_CHECK_FORMAT (ref1);
  508.   mpz_set (res1, in1);
  509.   mpz_remove (res1, res1, in2);
  510.   MPZ_CHECK_FORMAT (res1);
  511.   if (mpz_cmp (ref1, res1) != 0)
  512.     FAIL2 (mpz_remove, in1, in2, NULL);
  513.   mpz_set (res1, in2);
  514.   mpz_remove (res1, in1, res1);
  515.   MPZ_CHECK_FORMAT (res1);
  516.   if (mpz_cmp (ref1, res1) != 0)
  517.     FAIL2 (mpz_remove, in1, in2, NULL);
  518. }
  519.       if (mpz_sgn (in2) != 0)
  520. {
  521.   /* Test mpz_divexact */
  522.   mpz_mul (t, in1, in2);
  523.   mpz_divexact (ref1, t, in2);
  524.   MPZ_CHECK_FORMAT (ref1);
  525.   mpz_set (res1, t);
  526.   mpz_divexact (res1, res1, in2);
  527.   MPZ_CHECK_FORMAT (res1);
  528.   if (mpz_cmp (ref1, res1) != 0)
  529.     FAIL2 (mpz_divexact, t, in2, NULL);
  530.   mpz_set (res1, in2);
  531.   mpz_divexact (res1, t, res1);
  532.   MPZ_CHECK_FORMAT (res1);
  533.   if (mpz_cmp (ref1, res1) != 0)
  534.     FAIL2 (mpz_divexact, t, in2, NULL);
  535. }
  536.       if (mpz_sgn (in2) > 0)
  537. {
  538.   /* Test mpz_divexact_gcd, same as mpz_divexact */
  539.   mpz_mul (t, in1, in2);
  540.   mpz_divexact_gcd (ref1, t, in2);
  541.   MPZ_CHECK_FORMAT (ref1);
  542.   mpz_set (res1, t);
  543.   mpz_divexact_gcd (res1, res1, in2);
  544.   MPZ_CHECK_FORMAT (res1);
  545.   if (mpz_cmp (ref1, res1) != 0)
  546.     FAIL2 (mpz_divexact_gcd, t, in2, NULL);
  547.   mpz_set (res1, in2);
  548.   mpz_divexact_gcd (res1, t, res1);
  549.   MPZ_CHECK_FORMAT (res1);
  550.   if (mpz_cmp (ref1, res1) != 0)
  551.     FAIL2 (mpz_divexact_gcd, t, in2, NULL);
  552. }
  553.     }
  554.   if (failures != 0)
  555.     {
  556.       fprintf (stderr, "mpz/reuse: %ld error%sn", failures, "s" + (failures == 1));
  557.       exit (1);
  558.     }
  559.   mpz_clear (bs);
  560.   mpz_clear (in1);
  561.   mpz_clear (in2);
  562.   mpz_clear (in3);
  563.   mpz_clear (ref1);
  564.   mpz_clear (ref2);
  565.   mpz_clear (ref3);
  566.   mpz_clear (res1);
  567.   mpz_clear (res2);
  568.   mpz_clear (res3);
  569.   mpz_clear (t);
  570.   tests_end ();
  571.   exit (0);
  572. }
  573. void
  574. dump (char *name, mpz_t in1, mpz_t in2, mpz_t in3)
  575. {
  576.   printf ("failure in %s (", name);
  577.   mpz_out_str (stdout, -16, in1);
  578.   if (in2 != NULL)
  579.     {
  580.       printf (" ");
  581.       mpz_out_str (stdout, -16, in2);
  582.     }
  583.   if (in3 != NULL)
  584.     {
  585.       printf (" ");
  586.       mpz_out_str (stdout, -16, in3);
  587.     }
  588.   printf (")n");
  589. }
  590. #endif /* ! DLL_EXPORT */