📄 reuse.c
字号:
/* Test that routines allow reusing a source variable as destination. Test all relevant functions except: mpz_bin_ui mpz_nextprime mpz_mul_si mpz_addmul_ui (should this really allow a+=a*c?)Copyright 1996, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.This file is part of the GNU MP Library.The GNU MP Library is free software; you can redistribute it and/or modifyit under the terms of the GNU Lesser General Public License as published bythe Free Software Foundation; either version 2.1 of the License, or (at youroption) any later version.The GNU MP Library is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITYor FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General PublicLicense for more details.You should have received a copy of the GNU Lesser General Public Licensealong with the GNU MP Library; see the file COPYING.LIB. If not, write tothe Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,MA 02111-1307, USA. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include "gmp.h"#include "gmp-impl.h"#include "tests.h"#if __GMP_LIBGMP_DLL/* FIXME: When linking to a DLL libgmp, mpz_add etc can't be used as initializers for global variables because they're effectively global variables (function pointers) themselves. Perhaps calling a test function successively with mpz_add etc would be better. */intmain (void){ printf ("Test suppressed for windows DLL\n"); exit (0);}#else /* ! DLL_EXPORT */void dump _PROTO ((char *, mpz_t, mpz_t, mpz_t));typedef void (*dss_func) _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr));typedef void (*dsi_func) _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));typedef unsigned long int (*dsi_div_func) _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));typedef unsigned long int (*ddsi_div_func) _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));typedef void (*ddss_div_func) _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));typedef void (*ds_func) _PROTO ((mpz_ptr, mpz_srcptr));voidmpz_xinvert (mpz_ptr r, mpz_srcptr a, mpz_srcptr b){ int res; res = mpz_invert (r, a, b); if (res == 0) mpz_set_ui (r, 0);}dss_func dss_funcs[] ={ mpz_add, mpz_sub, mpz_mul, mpz_cdiv_q, mpz_cdiv_r, mpz_fdiv_q, mpz_fdiv_r, mpz_tdiv_q, mpz_tdiv_r, mpz_xinvert, mpz_gcd, mpz_lcm, mpz_and, mpz_ior, mpz_xor};char *dss_func_names[] ={ "mpz_add", "mpz_sub", "mpz_mul", "mpz_cdiv_q", "mpz_cdiv_r", "mpz_fdiv_q", "mpz_fdiv_r", "mpz_tdiv_q", "mpz_tdiv_r", "mpz_xinvert", "mpz_gcd", "mpz_lcm", "mpz_and", "mpz_ior", "mpz_xor"};char dss_func_division[] = {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0};dsi_func dsi_funcs[] ={ /* Don't change order here without changing the code in main(). */ mpz_add_ui, mpz_mul_ui, mpz_sub_ui, mpz_fdiv_q_2exp, mpz_fdiv_r_2exp, mpz_cdiv_q_2exp, mpz_cdiv_r_2exp, mpz_tdiv_q_2exp, mpz_tdiv_r_2exp, mpz_mul_2exp, mpz_pow_ui};char *dsi_func_names[] ={ "mpz_add_ui", "mpz_mul_ui", "mpz_sub_ui", "mpz_fdiv_q_2exp", "mpz_fdiv_r_2exp", "mpz_cdiv_q_2exp", "mpz_cdiv_r_2exp", "mpz_tdiv_q_2exp", "mpz_tdiv_r_2exp", "mpz_mul_2exp", "mpz_pow_ui"};dsi_div_func dsi_div_funcs[] ={ mpz_cdiv_q_ui, mpz_cdiv_r_ui, mpz_fdiv_q_ui, mpz_fdiv_r_ui, mpz_tdiv_q_ui, mpz_tdiv_r_ui};char *dsi_div_func_names[] ={ "mpz_cdiv_q_ui", "mpz_cdiv_r_ui", "mpz_fdiv_q_ui", "mpz_fdiv_r_ui", "mpz_tdiv_q_ui", "mpz_tdiv_r_ui"};ddsi_div_func ddsi_div_funcs[] ={ mpz_cdiv_qr_ui, mpz_fdiv_qr_ui, mpz_tdiv_qr_ui};char *ddsi_div_func_names[] ={ "mpz_cdiv_qr_ui", "mpz_fdiv_qr_ui", "mpz_tdiv_qr_ui"};ddss_div_func ddss_div_funcs[] ={ mpz_cdiv_qr, mpz_fdiv_qr, mpz_tdiv_qr};char *ddss_div_func_names[] ={ "mpz_cdiv_qr", "mpz_fdiv_qr", "mpz_tdiv_qr"};ds_func ds_funcs[] ={ mpz_abs, mpz_com, mpz_neg, mpz_sqrt};char *ds_func_names[] ={ "mpz_abs", "mpz_com", "mpz_neg", "mpz_sqrt"};/* Really use `defined (__STDC__)' here; we want it to be true for Sun C */#if defined (__STDC__) || defined (__cplusplus)#define FAIL(class,indx,op1,op2,op3) \ do { \ class##_funcs[indx] = 0; \ dump (class##_func_names[indx], op1, op2, op3); \ failures++; \ } while (0)#define FAIL2(fname,op1,op2,op3) \ do { \ dump (#fname, op1, op2, op3); \ failures++; \ } while (0)#else#define FAIL(class,indx,op1,op2,op3) \ do { \ class/**/_funcs[indx] = 0; \ dump (class/**/_func_names[indx], op1, op2, op3); \ failures++; \ } while (0)#define FAIL2(fname,op1,op2,op3) \ do { \ dump ("fname", op1, op2, op3); \ failures++; \ } while (0)#endifintmain (int argc, char **argv){ int i; int pass, reps = 1000; mpz_t in1, in2, in3; unsigned long int in2i; mp_size_t size; mpz_t res1, res2, res3; mpz_t ref1, ref2, ref3; mpz_t t; unsigned long int r1, r2; long failures = 0; gmp_randstate_ptr rands; mpz_t bs; unsigned long bsi, size_range; tests_start (); rands = RANDS; mpz_init (bs); if (argc == 2) reps = atoi (argv[1]); mpz_init (in1); mpz_init (in2); mpz_init (in3); mpz_init (ref1); mpz_init (ref2); mpz_init (ref3); mpz_init (res1); mpz_init (res2); mpz_init (res3); mpz_init (t); for (pass = 1; pass <= reps; pass++) { mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 10 + 2; mpz_urandomb (bs, rands, size_range); size = mpz_get_ui (bs); mpz_rrandomb (in1, rands, size); mpz_urandomb (bs, rands, size_range); size = mpz_get_ui (bs); mpz_rrandomb (in2, rands, size); mpz_urandomb (bs, rands, size_range); size = mpz_get_ui (bs); mpz_rrandomb (in3, rands, size); mpz_urandomb (bs, rands, 3); bsi = mpz_get_ui (bs); if ((bsi & 1) != 0) mpz_neg (in1, in1); if ((bsi & 1) != 0) mpz_neg (in2, in2); if ((bsi & 1) != 0) mpz_neg (in3, in3); for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++) { if (dss_funcs[i] == 0) continue; if (dss_func_division[i] && mpz_sgn (in2) == 0) continue; (dss_funcs[i]) (ref1, in1, in2); mpz_set (res1, in1); (dss_funcs[i]) (res1, res1, in2); if (mpz_cmp (ref1, res1) != 0) FAIL (dss, i, in1, in2, NULL); mpz_set (res1, in2); (dss_funcs[i]) (res1, in1, res1); if (mpz_cmp (ref1, res1) != 0) FAIL (dss, i, in1, in2, NULL); } for (i = 0; i < sizeof (ddss_div_funcs) / sizeof (ddss_div_func); i++) { if (ddss_div_funcs[i] == 0) continue; if (mpz_sgn (in2) == 0) continue; (ddss_div_funcs[i]) (ref1, ref2, in1, in2); mpz_set (res1, in1); (ddss_div_funcs[i]) (res1, res2, res1, in2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) FAIL (ddss_div, i, in1, in2, NULL); mpz_set (res2, in1); (ddss_div_funcs[i]) (res1, res2, res2, in2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) FAIL (ddss_div, i, in1, in2, NULL); mpz_set (res1, in2); (ddss_div_funcs[i]) (res1, res2, in1, res1); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) FAIL (ddss_div, i, in1, in2, NULL); mpz_set (res2, in2); (ddss_div_funcs[i]) (res1, res2, in1, res2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) FAIL (ddss_div, i, in1, in2, NULL); } for (i = 0; i < sizeof (ds_funcs) / sizeof (ds_func); i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -