mpz_perfect_power_p corrections and new test program
This commit is contained in:
parent
0c01599cab
commit
c9dd7aea90
@ -3,6 +3,8 @@
|
||||
|
||||
Copyright 1998, 1999, 2000, 2001, 2005 Free Software Foundation, Inc.
|
||||
|
||||
Copyright 2008 Jason Moxham
|
||||
|
||||
This file is part of the GNU MP Library.
|
||||
|
||||
The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
@ -81,8 +83,8 @@ mpz_perfect_power_p (mpz_srcptr u)
|
||||
if (n2 == 1)
|
||||
return 0; /* 2 divides exactly once. */
|
||||
|
||||
if (n2 != 0 && (n2 & 1) == 0 && usize < 0)
|
||||
return 0; /* 2 has even multiplicity with negative U */
|
||||
if (n2 > 1 && POW2_P(n2) && usize < 0)
|
||||
return 0; /* 2 has power of two multiplicity with negative U */
|
||||
|
||||
TMP_MARK;
|
||||
|
||||
@ -117,10 +119,10 @@ mpz_perfect_power_p (mpz_srcptr u)
|
||||
n++;
|
||||
}
|
||||
|
||||
if ((n & 1) == 0 && usize < 0)
|
||||
if ( POW2_P(n) && usize < 0)
|
||||
{
|
||||
TMP_FREE;
|
||||
return 0; /* even multiplicity with negative U, reject */
|
||||
return 0; /* power of two multiplicity with negative U, reject */
|
||||
}
|
||||
|
||||
n2 = gcd (n2, n);
|
||||
@ -133,6 +135,7 @@ mpz_perfect_power_p (mpz_srcptr u)
|
||||
if (mpz_cmpabs_ui (u2, 1) == 0)
|
||||
{
|
||||
TMP_FREE;
|
||||
if(usize<0 && POW2_P(n2))return 0;/* factoring completed; not consistent power */
|
||||
return 1; /* factoring completed; consistent power */
|
||||
}
|
||||
|
||||
@ -161,7 +164,7 @@ mpz_perfect_power_p (mpz_srcptr u)
|
||||
TMP_FREE;
|
||||
return 1;
|
||||
}
|
||||
if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0)
|
||||
if (mpz_cmpabs_ui (q, SMALLEST_OMITTED_PRIME) < 0)
|
||||
{
|
||||
TMP_FREE;
|
||||
return 0;
|
||||
@ -173,7 +176,7 @@ mpz_perfect_power_p (mpz_srcptr u)
|
||||
unsigned long int nth;
|
||||
/* We found some factors above. We just need to consider values of n
|
||||
that divides n2. */
|
||||
for (nth = 2; nth <= n2; nth++)
|
||||
for (nth = usize < 0 ? 3 : 2; nth <= n2; nth++)
|
||||
{
|
||||
if (! isprime (nth))
|
||||
continue;
|
||||
@ -189,7 +192,7 @@ mpz_perfect_power_p (mpz_srcptr u)
|
||||
TMP_FREE;
|
||||
return 1;
|
||||
}
|
||||
if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0)
|
||||
if (mpz_cmpabs_ui (q, SMALLEST_OMITTED_PRIME) < 0)
|
||||
{
|
||||
TMP_FREE;
|
||||
return 0;
|
||||
@ -201,6 +204,7 @@ mpz_perfect_power_p (mpz_srcptr u)
|
||||
}
|
||||
|
||||
n2prime:
|
||||
if(n2==2 && usize<0){TMP_FREE;return 0;}
|
||||
exact = mpz_root (NULL, u2, n2);
|
||||
TMP_FREE;
|
||||
return exact;
|
||||
|
@ -3,6 +3,8 @@
|
||||
# Copyright 1996, 1997, 1999, 2000, 2001, 2002, 2003 Free Software
|
||||
# Foundation, Inc.
|
||||
#
|
||||
# Copyright 2008 Jason Moxham
|
||||
#
|
||||
# This file is part of the GNU MP Library.
|
||||
#
|
||||
# The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
@ -32,7 +34,7 @@ check_PROGRAMS = t-addsub t-cmp t-mul t-mul_i t-tdiv t-tdiv_ui t-fdiv \
|
||||
t-fac_ui t-fib_ui t-lucnum_ui t-scan t-fits \
|
||||
t-divis t-divis_2exp t-cong t-cong_2exp t-sizeinbase t-set_str \
|
||||
t-aorsmul t-cmp_d t-cmp_si t-hamdist t-oddeven t-popcount t-set_f \
|
||||
t-io_raw t-import t-export t-pprime_p
|
||||
t-io_raw t-import t-export t-pprime_p t-perfpow
|
||||
|
||||
TESTS = $(check_PROGRAMS)
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
||||
# Copyright 1996, 1997, 1999, 2000, 2001, 2002, 2003 Free Software
|
||||
# Foundation, Inc.
|
||||
#
|
||||
# Copyright 2008 Jason Moxham
|
||||
#
|
||||
# This file is part of the GNU MP Library.
|
||||
#
|
||||
# The GNU MP Library is free software; you can redistribute it and/or modify
|
||||
@ -73,7 +75,8 @@ check_PROGRAMS = t-addsub$(EXEEXT) t-cmp$(EXEEXT) t-mul$(EXEEXT) \
|
||||
t-set_str$(EXEEXT) t-aorsmul$(EXEEXT) t-cmp_d$(EXEEXT) \
|
||||
t-cmp_si$(EXEEXT) t-hamdist$(EXEEXT) t-oddeven$(EXEEXT) \
|
||||
t-popcount$(EXEEXT) t-set_f$(EXEEXT) t-io_raw$(EXEEXT) \
|
||||
t-import$(EXEEXT) t-export$(EXEEXT) t-pprime_p$(EXEEXT)
|
||||
t-import$(EXEEXT) t-export$(EXEEXT) t-pprime_p$(EXEEXT) \
|
||||
t-perfpow$(EXEEXT)
|
||||
subdir = tests/mpz
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
@ -284,6 +287,11 @@ t_oddeven_OBJECTS = t-oddeven$U.$(OBJEXT)
|
||||
t_oddeven_LDADD = $(LDADD)
|
||||
t_oddeven_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
|
||||
$(top_builddir)/libgmp.la
|
||||
t_perfpow_SOURCES = t-perfpow.c
|
||||
t_perfpow_OBJECTS = t-perfpow$U.$(OBJEXT)
|
||||
t_perfpow_LDADD = $(LDADD)
|
||||
t_perfpow_DEPENDENCIES = $(top_builddir)/tests/libtests.la \
|
||||
$(top_builddir)/libgmp.la
|
||||
t_perfsqr_SOURCES = t-perfsqr.c
|
||||
t_perfsqr_OBJECTS = t-perfsqr$U.$(OBJEXT)
|
||||
t_perfsqr_LDADD = $(LDADD)
|
||||
@ -382,10 +390,10 @@ SOURCES = bit.c convert.c dive.c dive_ui.c io.c logic.c reuse.c \
|
||||
t-fib_ui.c t-fits.c t-gcd.c t-gcd_ui.c t-get_d.c \
|
||||
t-get_d_2exp.c t-get_si.c t-hamdist.c t-import.c t-inp_str.c \
|
||||
t-io_raw.c t-jac.c t-lcm.c t-lucnum_ui.c t-mul.c t-mul_i.c \
|
||||
t-oddeven.c t-perfsqr.c t-popcount.c t-pow.c t-powm.c \
|
||||
t-powm_ui.c t-pprime_p.c t-root.c t-scan.c t-set_d.c t-set_f.c \
|
||||
t-set_si.c t-set_str.c t-sizeinbase.c t-sqrtrem.c t-tdiv.c \
|
||||
t-tdiv_ui.c
|
||||
t-oddeven.c t-perfpow.c t-perfsqr.c t-popcount.c t-pow.c \
|
||||
t-powm.c t-powm_ui.c t-pprime_p.c t-root.c t-scan.c t-set_d.c \
|
||||
t-set_f.c t-set_si.c t-set_str.c t-sizeinbase.c t-sqrtrem.c \
|
||||
t-tdiv.c t-tdiv_ui.c
|
||||
DIST_SOURCES = bit.c convert.c dive.c dive_ui.c io.c logic.c reuse.c \
|
||||
t-addsub.c t-aorsmul.c t-bin.c t-cdiv_ui.c t-cmp.c t-cmp_d.c \
|
||||
t-cmp_si.c t-cong.c t-cong_2exp.c t-div_2exp.c t-divis.c \
|
||||
@ -393,10 +401,10 @@ DIST_SOURCES = bit.c convert.c dive.c dive_ui.c io.c logic.c reuse.c \
|
||||
t-fib_ui.c t-fits.c t-gcd.c t-gcd_ui.c t-get_d.c \
|
||||
t-get_d_2exp.c t-get_si.c t-hamdist.c t-import.c t-inp_str.c \
|
||||
t-io_raw.c t-jac.c t-lcm.c t-lucnum_ui.c t-mul.c t-mul_i.c \
|
||||
t-oddeven.c t-perfsqr.c t-popcount.c t-pow.c t-powm.c \
|
||||
t-powm_ui.c t-pprime_p.c t-root.c t-scan.c t-set_d.c t-set_f.c \
|
||||
t-set_si.c t-set_str.c t-sizeinbase.c t-sqrtrem.c t-tdiv.c \
|
||||
t-tdiv_ui.c
|
||||
t-oddeven.c t-perfpow.c t-perfsqr.c t-popcount.c t-pow.c \
|
||||
t-powm.c t-powm_ui.c t-pprime_p.c t-root.c t-scan.c t-set_d.c \
|
||||
t-set_f.c t-set_si.c t-set_str.c t-sizeinbase.c t-sqrtrem.c \
|
||||
t-tdiv.c t-tdiv_ui.c
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
@ -717,6 +725,9 @@ t-mul_i$(EXEEXT): $(t_mul_i_OBJECTS) $(t_mul_i_DEPENDENCIES)
|
||||
t-oddeven$(EXEEXT): $(t_oddeven_OBJECTS) $(t_oddeven_DEPENDENCIES)
|
||||
@rm -f t-oddeven$(EXEEXT)
|
||||
$(LINK) $(t_oddeven_LDFLAGS) $(t_oddeven_OBJECTS) $(t_oddeven_LDADD) $(LIBS)
|
||||
t-perfpow$(EXEEXT): $(t_perfpow_OBJECTS) $(t_perfpow_DEPENDENCIES)
|
||||
@rm -f t-perfpow$(EXEEXT)
|
||||
$(LINK) $(t_perfpow_LDFLAGS) $(t_perfpow_OBJECTS) $(t_perfpow_LDADD) $(LIBS)
|
||||
t-perfsqr$(EXEEXT): $(t_perfsqr_OBJECTS) $(t_perfsqr_DEPENDENCIES)
|
||||
@rm -f t-perfsqr$(EXEEXT)
|
||||
$(LINK) $(t_perfsqr_LDFLAGS) $(t_perfsqr_OBJECTS) $(t_perfsqr_LDADD) $(LIBS)
|
||||
@ -865,6 +876,8 @@ t-mul_i_.c: t-mul_i.c $(ANSI2KNR)
|
||||
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/t-mul_i.c; then echo $(srcdir)/t-mul_i.c; else echo t-mul_i.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
|
||||
t-oddeven_.c: t-oddeven.c $(ANSI2KNR)
|
||||
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/t-oddeven.c; then echo $(srcdir)/t-oddeven.c; else echo t-oddeven.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
|
||||
t-perfpow_.c: t-perfpow.c $(ANSI2KNR)
|
||||
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/t-perfpow.c; then echo $(srcdir)/t-perfpow.c; else echo t-perfpow.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
|
||||
t-perfsqr_.c: t-perfsqr.c $(ANSI2KNR)
|
||||
$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/t-perfsqr.c; then echo $(srcdir)/t-perfsqr.c; else echo t-perfsqr.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
|
||||
t-popcount_.c: t-popcount.c $(ANSI2KNR)
|
||||
@ -916,15 +929,16 @@ t-hamdist_.lo t-import_.$(OBJEXT) t-import_.lo t-inp_str_.$(OBJEXT) \
|
||||
t-inp_str_.lo t-io_raw_.$(OBJEXT) t-io_raw_.lo t-jac_.$(OBJEXT) \
|
||||
t-jac_.lo t-lcm_.$(OBJEXT) t-lcm_.lo t-lucnum_ui_.$(OBJEXT) \
|
||||
t-lucnum_ui_.lo t-mul_.$(OBJEXT) t-mul_.lo t-mul_i_.$(OBJEXT) \
|
||||
t-mul_i_.lo t-oddeven_.$(OBJEXT) t-oddeven_.lo t-perfsqr_.$(OBJEXT) \
|
||||
t-perfsqr_.lo t-popcount_.$(OBJEXT) t-popcount_.lo t-pow_.$(OBJEXT) \
|
||||
t-pow_.lo t-powm_.$(OBJEXT) t-powm_.lo t-powm_ui_.$(OBJEXT) \
|
||||
t-powm_ui_.lo t-pprime_p_.$(OBJEXT) t-pprime_p_.lo t-root_.$(OBJEXT) \
|
||||
t-root_.lo t-scan_.$(OBJEXT) t-scan_.lo t-set_d_.$(OBJEXT) t-set_d_.lo \
|
||||
t-set_f_.$(OBJEXT) t-set_f_.lo t-set_si_.$(OBJEXT) t-set_si_.lo \
|
||||
t-set_str_.$(OBJEXT) t-set_str_.lo t-sizeinbase_.$(OBJEXT) \
|
||||
t-sizeinbase_.lo t-sqrtrem_.$(OBJEXT) t-sqrtrem_.lo t-tdiv_.$(OBJEXT) \
|
||||
t-tdiv_.lo t-tdiv_ui_.$(OBJEXT) t-tdiv_ui_.lo : $(ANSI2KNR)
|
||||
t-mul_i_.lo t-oddeven_.$(OBJEXT) t-oddeven_.lo t-perfpow_.$(OBJEXT) \
|
||||
t-perfpow_.lo t-perfsqr_.$(OBJEXT) t-perfsqr_.lo t-popcount_.$(OBJEXT) \
|
||||
t-popcount_.lo t-pow_.$(OBJEXT) t-pow_.lo t-powm_.$(OBJEXT) t-powm_.lo \
|
||||
t-powm_ui_.$(OBJEXT) t-powm_ui_.lo t-pprime_p_.$(OBJEXT) \
|
||||
t-pprime_p_.lo t-root_.$(OBJEXT) t-root_.lo t-scan_.$(OBJEXT) \
|
||||
t-scan_.lo t-set_d_.$(OBJEXT) t-set_d_.lo t-set_f_.$(OBJEXT) \
|
||||
t-set_f_.lo t-set_si_.$(OBJEXT) t-set_si_.lo t-set_str_.$(OBJEXT) \
|
||||
t-set_str_.lo t-sizeinbase_.$(OBJEXT) t-sizeinbase_.lo \
|
||||
t-sqrtrem_.$(OBJEXT) t-sqrtrem_.lo t-tdiv_.$(OBJEXT) t-tdiv_.lo \
|
||||
t-tdiv_ui_.$(OBJEXT) t-tdiv_ui_.lo : $(ANSI2KNR)
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
134
tests/mpz/t-perfpow.c
Normal file
134
tests/mpz/t-perfpow.c
Normal file
@ -0,0 +1,134 @@
|
||||
/* Exercise mpz_perfect_power_p
|
||||
|
||||
Copyright 2008 Jason Moxham
|
||||
|
||||
This file is part of the MPIR Library.
|
||||
|
||||
The MPIR Library is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or (at
|
||||
your option) any later version.
|
||||
|
||||
The MPIR Library is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with the MPIR Library; see the file COPYING.LIB. If not, write
|
||||
to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "gmp.h"
|
||||
#include "gmp-impl.h"
|
||||
#include "tests.h"
|
||||
|
||||
int
|
||||
perfpow_ref (mpz_t x)
|
||||
{
|
||||
mpz_t y, q, r;
|
||||
unsigned long i;
|
||||
int ret = 0;
|
||||
|
||||
if (mpz_cmp_ui (x, 0) == 0 || mpz_cmp_ui (x, 1) == 0
|
||||
|| mpz_cmp_si (x, -1) == 0)
|
||||
return 1;
|
||||
mpz_init_set (y, x);
|
||||
mpz_init (q);
|
||||
mpz_init (r);
|
||||
mpz_abs (y, y);
|
||||
for (i = 2;; i++)
|
||||
{
|
||||
mpz_root (q, y, i);
|
||||
mpz_pow_ui (r, q, i);
|
||||
if (mpz_cmp (r, y) == 0 && (i % 2 == 1 || SIZ (x) > 0))
|
||||
{
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
if (mpz_cmp_ui (q, 1) <= 0)
|
||||
break;
|
||||
}
|
||||
mpz_clear (y);
|
||||
mpz_clear (q);
|
||||
mpz_clear (r);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int i, r1, r2, j, a, b, c, d;
|
||||
mpz_t x, m;
|
||||
tests_start ();
|
||||
|
||||
mpz_init (x);
|
||||
mpz_init (m);
|
||||
/* check small values */
|
||||
for (i = -10000; i < 10000; i++)
|
||||
{
|
||||
mpz_set_si (x, i);
|
||||
r1 = mpz_perfect_power_p (x);
|
||||
r2 = perfpow_ref (x);
|
||||
if (r1 != r2)
|
||||
{
|
||||
printf ("mpz_perfect_power_p wrong on %d got %d want %d\n", i, r1,
|
||||
r2);
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
/* check (-1)^i.2^a.3^b.5^c.x^d where x is big */
|
||||
/* 1.0.0.0.5 picked up one error
|
||||
1.10.6.0.0 picked up another error
|
||||
want a good selection of powers to try all possibilitys
|
||||
*/
|
||||
for (i = 1; i <= 2; i++)
|
||||
{
|
||||
for (d = 0; d < 10; d++)
|
||||
{
|
||||
for (a = 0; a < 11; a++)
|
||||
{
|
||||
for (b = 0; b < 11; b++)
|
||||
{
|
||||
for (c = 0; c < 11; c++)
|
||||
{
|
||||
mpz_set_ui (x, 1);
|
||||
mpz_set_si (m, -1);
|
||||
for (j = 0; j < i; j++)
|
||||
mpz_mul (x, x, m);
|
||||
mpz_set_ui (m, 2);
|
||||
for (j = 0; j < a; j++)
|
||||
mpz_mul (x, x, m);
|
||||
mpz_set_ui (m, 3);
|
||||
for (j = 0; j < b; j++)
|
||||
mpz_mul (x, x, m);
|
||||
mpz_set_ui (m, 5);
|
||||
for (j = 0; j < c; j++)
|
||||
mpz_mul (x, x, m);
|
||||
mpz_set_ui (m, 117039007);
|
||||
for (j = 0; j < d; j++)
|
||||
mpz_mul (x, x, m);
|
||||
r1 = mpz_perfect_power_p (x);
|
||||
r2 = perfpow_ref (x);
|
||||
if (r1 != r2)
|
||||
{
|
||||
printf
|
||||
("mpz_perfect_power_p wrong on %d.%d.%d.%d.%d got %d want %d\n",
|
||||
i, a, b, c, d, r1, r2);
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mpz_clear (x);
|
||||
mpz_clear (m);
|
||||
tests_end ();
|
||||
exit (0);
|
||||
}
|
Loading…
Reference in New Issue
Block a user