📄 t-gcd.c
字号:
/* Test mpz_gcd, mpz_gcdext, mpz_mul, mpz_tdiv_r, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_init_set, mpz_set, mpz_clear.Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2002, 2004 Free SoftwareFoundation, 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 "gmp.h"#include "gmp-impl.h"#include "tests.h"void dump_abort _PROTO ((int, mpz_t, mpz_t));void debug_mp _PROTO ((mpz_t, int));voidcheck_data (void){ static const struct { const char *a; const char *b; const char *want; } data[] = { /* This tickled a bug in gmp 4.1.2 mpn/x86/k6/gcd_finda.asm. */ { "0x3FFC000007FFFFFFFFFF00000000003F83FFFFFFFFFFFFFFF80000000000000001", "0x1FFE0007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC000000000000000000000001", "5" } }; mpz_t a, b, got, want; int i; mpz_init (a); mpz_init (b); mpz_init (got); mpz_init (want); for (i = 0; i < numberof (data); i++) { mpz_set_str_or_abort (a, data[i].a, 0); mpz_set_str_or_abort (b, data[i].b, 0); mpz_set_str_or_abort (want, data[i].want, 0); mpz_gcd (got, a, b); MPZ_CHECK_FORMAT (got); if (mpz_cmp (got, want) != 0) { printf ("mpz_gcd wrong on data[%d]\n", i); printf (" a %s\n", data[i].a); printf (" b %s\n", data[i].b); mpz_trace (" a", a); mpz_trace (" b", b); mpz_trace (" want", want); mpz_trace (" got ", got); abort (); } } mpz_clear (a); mpz_clear (b); mpz_clear (got); mpz_clear (want);}intmain (int argc, char **argv){ mpz_t op1, op2, x; mpz_t gcd, gcd2, s, t; mpz_t temp1, temp2; mp_size_t op1_size, op2_size, x_size; int i; int reps = 2000; gmp_randstate_ptr rands; mpz_t bs; unsigned long bsi, size_range; tests_start (); rands = RANDS; check_data (); mpz_init (bs); if (argc == 2) reps = atoi (argv[1]); mpz_init (op1); mpz_init (op2); mpz_init (x); mpz_init (gcd); mpz_init (gcd2); mpz_init (temp1); mpz_init (temp2); mpz_init (s); mpz_init (t); for (i = 0; i < reps; i++) { mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 12 + 2; /* 0..8191 bit operands */ mpz_urandomb (bs, rands, size_range); op1_size = mpz_get_ui (bs); mpz_rrandomb (op1, rands, op1_size); mpz_urandomb (bs, rands, size_range); op2_size = mpz_get_ui (bs); mpz_rrandomb (op2, rands, op2_size); mpz_urandomb (bs, rands, size_range); x_size = mpz_get_ui (bs); mpz_rrandomb (x, rands, x_size); mpz_urandomb (bs, rands, 2); bsi = mpz_get_ui (bs); if ((bsi & 1) != 0) mpz_neg (op1, op1); if ((bsi & 2) != 0) mpz_neg (op2, op2); /* printf ("%ld %ld\n", SIZ (op1), SIZ (op2)); */ mpz_mul (op1, op1, x); mpz_mul (op2, op2, x); mpz_gcd (gcd, op1, op2); /* We know GCD will be at least X, since we multiplied both operands with it. */ if (mpz_cmp (gcd, x) < 0 && mpz_sgn (op1) != 0 && mpz_sgn (op2) != 0) dump_abort (i, op1, op2); if (mpz_fits_ulong_p (op2)) { mpz_gcd_ui (gcd2, op1, mpz_get_ui (op2)); if (mpz_cmp (gcd, gcd2)) dump_abort (i, op1, op2); } mpz_gcdext (gcd2, s, t, op1, op2); if (mpz_cmp (gcd, gcd2)) dump_abort (i, op1, op2); mpz_gcdext (gcd2, s, NULL, op1, op2); if (mpz_cmp (gcd, gcd2)) dump_abort (i, op1, op2); mpz_mul (temp1, s, op1); mpz_mul (temp2, t, op2); mpz_add (gcd2, temp1, temp2); if (mpz_cmp (gcd, gcd2)) dump_abort (i, op1, op2); } mpz_clear (bs); mpz_clear (op1); mpz_clear (op2); mpz_clear (x); mpz_clear (gcd); mpz_clear (gcd2); mpz_clear (temp1); mpz_clear (temp2); mpz_clear (s); mpz_clear (t); tests_end (); exit (0);}voiddump_abort (int testnr, mpz_t op1, mpz_t op2){ fprintf (stderr, "ERROR in test %d\n", testnr); fprintf (stderr, "op1 = "); debug_mp (op1, -16); fprintf (stderr, "op2 = "); debug_mp (op2, -16); abort();}voiddebug_mp (mpz_t x, int base){ mpz_out_str (stderr, base, x); fputc ('\n', stderr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -