diff options
author | Pedro Alvarez <pedro.alvarez@codethink.co.uk> | 2014-12-22 00:55:04 +0000 |
---|---|---|
committer | Pedro Alvarez <pedro.alvarez@codethink.co.uk> | 2014-12-22 00:56:42 +0000 |
commit | 54eea31d0053620bab65153ab39d61e5575aaf1b (patch) | |
tree | 5f97c96dffdb6b27df36795689abfb9086011585 /gmp/tests/rand | |
parent | c16297b7cfb0c1708f1d84b5d0f90be0844d07ce (diff) | |
download | gcc-tarball-54eea31d0053620bab65153ab39d61e5575aaf1b.tar.gz |
Add gmp, mpc and mpfr sourcesbaserock/pedroalvarez/4.9.1
Diffstat (limited to 'gmp/tests/rand')
-rw-r--r-- | gmp/tests/rand/Makefile.am | 89 | ||||
-rw-r--r-- | gmp/tests/rand/Makefile.in | 801 | ||||
-rw-r--r-- | gmp/tests/rand/findlc.c | 252 | ||||
-rw-r--r-- | gmp/tests/rand/gen.c | 481 | ||||
-rw-r--r-- | gmp/tests/rand/gmpstat.h | 75 | ||||
-rw-r--r-- | gmp/tests/rand/spect.c | 137 | ||||
-rw-r--r-- | gmp/tests/rand/stat.c | 407 | ||||
-rw-r--r-- | gmp/tests/rand/statlib.c | 837 | ||||
-rw-r--r-- | gmp/tests/rand/t-iset.c | 68 | ||||
-rw-r--r-- | gmp/tests/rand/t-lc2exp.c | 217 | ||||
-rw-r--r-- | gmp/tests/rand/t-mt.c | 83 | ||||
-rw-r--r-- | gmp/tests/rand/t-rand.c | 290 | ||||
-rw-r--r-- | gmp/tests/rand/t-urbui.c | 65 | ||||
-rw-r--r-- | gmp/tests/rand/t-urmui.c | 75 | ||||
-rw-r--r-- | gmp/tests/rand/t-urndmm.c | 159 | ||||
-rw-r--r-- | gmp/tests/rand/zdiv_round.c | 44 |
16 files changed, 4080 insertions, 0 deletions
diff --git a/gmp/tests/rand/Makefile.am b/gmp/tests/rand/Makefile.am new file mode 100644 index 0000000000..ed585b7edc --- /dev/null +++ b/gmp/tests/rand/Makefile.am @@ -0,0 +1,89 @@ +## Process this file with automake to generate Makefile.in + +# Copyright 2000-2003 Free Software Foundation, Inc. +# +# This file is part of the GNU MP Library test suite. +# +# The GNU MP Library test suite is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the License, +# or (at your option) any later version. +# +# The GNU MP Library test suite 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 General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. + + +INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests +LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la + +check_PROGRAMS = t-iset t-lc2exp t-mt t-rand t-urbui t-urmui t-urndmm +TESTS = $(check_PROGRAMS) + +EXTRA_PROGRAMS = findlc gen gen.static spect stat +gen_static_SOURCES = gen.c +gen_static_LDFLAGS = -static +findlc_LDADD = libstat.la +spect_LDADD = libstat.la +stat_LDADD = libstat.la + +EXTRA_LTLIBRARIES = libstat.la +libstat_la_SOURCES = gmpstat.h statlib.c zdiv_round.c +libstat_la_LIBADD = $(top_builddir)/libgmp.la $(LIBM) + +CLEANFILES = $(EXTRA_PROGRAMS) $(EXTRA_LTLIBRARIES) + +allprogs: $(EXTRA_PROGRAMS) + +$(top_builddir)/tests/libtests.la: + cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la + +manual-test: gen$(EXEEXT) stat$(EXEEXT) + @(echo -n '16i: '; ./gen -f mpz_urandomb -z 16 1000 \ + | ./stat -i 0xffff | grep '^[0-9]') + @(echo -n '32i: '; ./gen -f mpz_urandomb -z 32 1000 \ + | ./stat -i 0xffffffff | grep '^[0-9]') + @(echo -n '33i: '; ./gen -f mpz_urandomb -z 33 1000 \ + | ./stat -i 0x1ffffffff | grep '^[0-9]') + @(echo -n '64i: '; ./gen -f mpz_urandomb -z 64 1000 \ + | ./stat -i 0xffffffffffffffff | grep '^[0-9]') + @(echo -n '128i: '; ./gen -f mpz_urandomb -z 128 1000 \ + | ./stat -i 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF | grep '^[0-9]') + + @(echo -n '16f: '; ./gen -f mpf_urandomb -z 16 1000 \ + | ./stat | grep '^[0-9]') + @(echo -n '32f: '; ./gen -f mpf_urandomb -z 32 1000 \ + | ./stat | grep '^[0-9]') + @(echo -n '33f: '; ./gen -f mpf_urandomb -z 33 1000 \ + | ./stat | grep '^[0-9]') + @(echo -n '64f: '; ./gen -f mpf_urandomb -z 64 1000 \ + | ./stat | grep '^[0-9]') + @(echo -n '128f: '; ./gen -f mpf_urandomb -z 128 1000 \ + | ./stat | grep '^[0-9]') + +manual-bigtest: gen$(EXEEXT) stat$(EXEEXT) + @(echo '16i: '; ./gen -f mpz_urandomb -z 16 50000 \ + | ./stat -2 1000 -i 0xffff | grep '^K[mp]') + @(echo '32i: '; ./gen -f mpz_urandomb -z 32 50000 \ + | ./stat -2 1000 -i 0xffffffff | grep '^K[mp]') + @(echo '33i: '; ./gen -f mpz_urandomb -z 33 50000 \ + | ./stat -2 1000 -i 0x1ffffffff | grep '^K[mp]') + @(echo '64i: '; ./gen -f mpz_urandomb -z 64 50000 \ + | ./stat -2 1000 -i 0xffffffffffffffff | grep '^K[mp]') + @(echo '128i: '; ./gen -f mpz_urandomb -z 128 50000 \ + | ./stat -2 1000 -i 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF | grep '^K[mp]') + + @(echo '16f: '; ./gen -f mpf_urandomb -z 16 50000 \ + | ./stat -2 1000 | grep '^K[mp]') + @(echo '32f: '; ./gen -f mpf_urandomb -z 32 50000 \ + | ./stat -2 1000 | grep '^K[mp]') + @(echo '33f: '; ./gen -f mpf_urandomb -z 33 50000 \ + | ./stat -2 1000 | grep '^K[mp]') + @(echo '64f: '; ./gen -f mpf_urandomb -z 64 50000 \ + | ./stat -2 1000 | grep '^K[mp]') + @(echo '128f: '; ./gen -f mpf_urandomb -z 128 50000 \ + | ./stat -2 1000 | grep '^K[mp]') diff --git a/gmp/tests/rand/Makefile.in b/gmp/tests/rand/Makefile.in new file mode 100644 index 0000000000..b902bc5586 --- /dev/null +++ b/gmp/tests/rand/Makefile.in @@ -0,0 +1,801 @@ +# Makefile.in generated by automake 1.11.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright 2000-2003 Free Software Foundation, Inc. +# +# This file is part of the GNU MP Library test suite. +# +# The GNU MP Library test suite is free software; you can redistribute it +# and/or modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 3 of the License, +# or (at your option) any later version. +# +# The GNU MP Library test suite 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 General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +check_PROGRAMS = t-iset$(EXEEXT) t-lc2exp$(EXEEXT) t-mt$(EXEEXT) \ + t-rand$(EXEEXT) t-urbui$(EXEEXT) t-urmui$(EXEEXT) \ + t-urndmm$(EXEEXT) +EXTRA_PROGRAMS = findlc$(EXEEXT) gen$(EXEEXT) gen.static$(EXEEXT) \ + spect$(EXEEXT) stat$(EXEEXT) +subdir = tests/rand +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__DEPENDENCIES_1 = +libstat_la_DEPENDENCIES = $(top_builddir)/libgmp.la \ + $(am__DEPENDENCIES_1) +am_libstat_la_OBJECTS = statlib.lo zdiv_round.lo +libstat_la_OBJECTS = $(am_libstat_la_OBJECTS) +findlc_SOURCES = findlc.c +findlc_OBJECTS = findlc.$(OBJEXT) +findlc_DEPENDENCIES = libstat.la +gen_SOURCES = gen.c +gen_OBJECTS = gen.$(OBJEXT) +gen_LDADD = $(LDADD) +gen_DEPENDENCIES = $(top_builddir)/tests/libtests.la \ + $(top_builddir)/libgmp.la +am_gen_static_OBJECTS = gen.$(OBJEXT) +gen_static_OBJECTS = $(am_gen_static_OBJECTS) +gen_static_LDADD = $(LDADD) +gen_static_DEPENDENCIES = $(top_builddir)/tests/libtests.la \ + $(top_builddir)/libgmp.la +gen_static_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(gen_static_LDFLAGS) $(LDFLAGS) -o $@ +spect_SOURCES = spect.c +spect_OBJECTS = spect.$(OBJEXT) +spect_DEPENDENCIES = libstat.la +stat_SOURCES = stat.c +stat_OBJECTS = stat.$(OBJEXT) +stat_DEPENDENCIES = libstat.la +t_iset_SOURCES = t-iset.c +t_iset_OBJECTS = t-iset.$(OBJEXT) +t_iset_LDADD = $(LDADD) +t_iset_DEPENDENCIES = $(top_builddir)/tests/libtests.la \ + $(top_builddir)/libgmp.la +t_lc2exp_SOURCES = t-lc2exp.c +t_lc2exp_OBJECTS = t-lc2exp.$(OBJEXT) +t_lc2exp_LDADD = $(LDADD) +t_lc2exp_DEPENDENCIES = $(top_builddir)/tests/libtests.la \ + $(top_builddir)/libgmp.la +t_mt_SOURCES = t-mt.c +t_mt_OBJECTS = t-mt.$(OBJEXT) +t_mt_LDADD = $(LDADD) +t_mt_DEPENDENCIES = $(top_builddir)/tests/libtests.la \ + $(top_builddir)/libgmp.la +t_rand_SOURCES = t-rand.c +t_rand_OBJECTS = t-rand.$(OBJEXT) +t_rand_LDADD = $(LDADD) +t_rand_DEPENDENCIES = $(top_builddir)/tests/libtests.la \ + $(top_builddir)/libgmp.la +t_urbui_SOURCES = t-urbui.c +t_urbui_OBJECTS = t-urbui.$(OBJEXT) +t_urbui_LDADD = $(LDADD) +t_urbui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \ + $(top_builddir)/libgmp.la +t_urmui_SOURCES = t-urmui.c +t_urmui_OBJECTS = t-urmui.$(OBJEXT) +t_urmui_LDADD = $(LDADD) +t_urmui_DEPENDENCIES = $(top_builddir)/tests/libtests.la \ + $(top_builddir)/libgmp.la +t_urndmm_SOURCES = t-urndmm.c +t_urndmm_OBJECTS = t-urndmm.$(OBJEXT) +t_urndmm_LDADD = $(LDADD) +t_urndmm_DEPENDENCIES = $(top_builddir)/tests/libtests.la \ + $(top_builddir)/libgmp.la +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = +am__depfiles_maybe = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = $(libstat_la_SOURCES) findlc.c gen.c $(gen_static_SOURCES) \ + spect.c stat.c t-iset.c t-lc2exp.c t-mt.c t-rand.c t-urbui.c \ + t-urmui.c t-urndmm.c +DIST_SOURCES = $(libstat_la_SOURCES) findlc.c gen.c \ + $(gen_static_SOURCES) spect.c stat.c t-iset.c t-lc2exp.c \ + t-mt.c t-rand.c t-urbui.c t-urmui.c t-urndmm.c +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +ETAGS = etags +CTAGS = ctags +am__tty_colors = \ +red=; grn=; lgn=; blu=; std= +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ABI = @ABI@ +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +ASMFLAGS = @ASMFLAGS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CALLING_CONVENTIONS_OBJS = @CALLING_CONVENTIONS_OBJS@ +CC = @CC@ +CCAS = @CCAS@ +CC_FOR_BUILD = @CC_FOR_BUILD@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPP_FOR_BUILD = @CPP_FOR_BUILD@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFN_LONG_LONG_LIMB = @DEFN_LONG_LONG_LIMB@ +DEFS = @DEFS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +EXEEXT_FOR_BUILD = @EXEEXT_FOR_BUILD@ +FGREP = @FGREP@ +GMP_LDFLAGS = @GMP_LDFLAGS@ +GMP_LIMB_BITS = @GMP_LIMB_BITS@ +GMP_NAIL_BITS = @GMP_NAIL_BITS@ +GREP = @GREP@ +HAVE_CLOCK_01 = @HAVE_CLOCK_01@ +HAVE_CPUTIME_01 = @HAVE_CPUTIME_01@ +HAVE_GETRUSAGE_01 = @HAVE_GETRUSAGE_01@ +HAVE_GETTIMEOFDAY_01 = @HAVE_GETTIMEOFDAY_01@ +HAVE_HOST_CPU_FAMILY_power = @HAVE_HOST_CPU_FAMILY_power@ +HAVE_HOST_CPU_FAMILY_powerpc = @HAVE_HOST_CPU_FAMILY_powerpc@ +HAVE_SIGACTION_01 = @HAVE_SIGACTION_01@ +HAVE_SIGALTSTACK_01 = @HAVE_SIGALTSTACK_01@ +HAVE_SIGSTACK_01 = @HAVE_SIGSTACK_01@ +HAVE_STACK_T_01 = @HAVE_STACK_T_01@ +HAVE_SYS_RESOURCE_H_01 = @HAVE_SYS_RESOURCE_H_01@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBCURSES = @LIBCURSES@ +LIBGMPXX_LDFLAGS = @LIBGMPXX_LDFLAGS@ +LIBGMP_DLL = @LIBGMP_DLL@ +LIBGMP_LDFLAGS = @LIBGMP_LDFLAGS@ +LIBM = @LIBM@ +LIBM_FOR_BUILD = @LIBM_FOR_BUILD@ +LIBOBJS = @LIBOBJS@ +LIBREADLINE = @LIBREADLINE@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +M4 = @M4@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SPEED_CYCLECOUNTER_OBJ = @SPEED_CYCLECOUNTER_OBJ@ +STRIP = @STRIP@ +TAL_OBJECT = @TAL_OBJECT@ +TUNE_LIBS = @TUNE_LIBS@ +TUNE_SQR_OBJ = @TUNE_SQR_OBJ@ +U_FOR_BUILD = @U_FOR_BUILD@ +VERSION = @VERSION@ +WITH_READLINE_01 = @WITH_READLINE_01@ +YACC = @YACC@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__leading_dot = @am__leading_dot@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +gmp_srclinks = @gmp_srclinks@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +mpn_objects = @mpn_objects@ +mpn_objs_in_libgmp = @mpn_objs_in_libgmp@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests +LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la +TESTS = $(check_PROGRAMS) +gen_static_SOURCES = gen.c +gen_static_LDFLAGS = -static +findlc_LDADD = libstat.la +spect_LDADD = libstat.la +stat_LDADD = libstat.la +EXTRA_LTLIBRARIES = libstat.la +libstat_la_SOURCES = gmpstat.h statlib.c zdiv_round.c +libstat_la_LIBADD = $(top_builddir)/libgmp.la $(LIBM) +CLEANFILES = $(EXTRA_PROGRAMS) $(EXTRA_LTLIBRARIES) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu --ignore-deps tests/rand/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu --ignore-deps tests/rand/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +libstat.la: $(libstat_la_OBJECTS) $(libstat_la_DEPENDENCIES) $(EXTRA_libstat_la_DEPENDENCIES) + $(LINK) $(libstat_la_OBJECTS) $(libstat_la_LIBADD) $(LIBS) + +clean-checkPROGRAMS: + @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +findlc$(EXEEXT): $(findlc_OBJECTS) $(findlc_DEPENDENCIES) $(EXTRA_findlc_DEPENDENCIES) + @rm -f findlc$(EXEEXT) + $(LINK) $(findlc_OBJECTS) $(findlc_LDADD) $(LIBS) +gen$(EXEEXT): $(gen_OBJECTS) $(gen_DEPENDENCIES) $(EXTRA_gen_DEPENDENCIES) + @rm -f gen$(EXEEXT) + $(LINK) $(gen_OBJECTS) $(gen_LDADD) $(LIBS) +gen.static$(EXEEXT): $(gen_static_OBJECTS) $(gen_static_DEPENDENCIES) $(EXTRA_gen_static_DEPENDENCIES) + @rm -f gen.static$(EXEEXT) + $(gen_static_LINK) $(gen_static_OBJECTS) $(gen_static_LDADD) $(LIBS) +spect$(EXEEXT): $(spect_OBJECTS) $(spect_DEPENDENCIES) $(EXTRA_spect_DEPENDENCIES) + @rm -f spect$(EXEEXT) + $(LINK) $(spect_OBJECTS) $(spect_LDADD) $(LIBS) +stat$(EXEEXT): $(stat_OBJECTS) $(stat_DEPENDENCIES) $(EXTRA_stat_DEPENDENCIES) + @rm -f stat$(EXEEXT) + $(LINK) $(stat_OBJECTS) $(stat_LDADD) $(LIBS) +t-iset$(EXEEXT): $(t_iset_OBJECTS) $(t_iset_DEPENDENCIES) $(EXTRA_t_iset_DEPENDENCIES) + @rm -f t-iset$(EXEEXT) + $(LINK) $(t_iset_OBJECTS) $(t_iset_LDADD) $(LIBS) +t-lc2exp$(EXEEXT): $(t_lc2exp_OBJECTS) $(t_lc2exp_DEPENDENCIES) $(EXTRA_t_lc2exp_DEPENDENCIES) + @rm -f t-lc2exp$(EXEEXT) + $(LINK) $(t_lc2exp_OBJECTS) $(t_lc2exp_LDADD) $(LIBS) +t-mt$(EXEEXT): $(t_mt_OBJECTS) $(t_mt_DEPENDENCIES) $(EXTRA_t_mt_DEPENDENCIES) + @rm -f t-mt$(EXEEXT) + $(LINK) $(t_mt_OBJECTS) $(t_mt_LDADD) $(LIBS) +t-rand$(EXEEXT): $(t_rand_OBJECTS) $(t_rand_DEPENDENCIES) $(EXTRA_t_rand_DEPENDENCIES) + @rm -f t-rand$(EXEEXT) + $(LINK) $(t_rand_OBJECTS) $(t_rand_LDADD) $(LIBS) +t-urbui$(EXEEXT): $(t_urbui_OBJECTS) $(t_urbui_DEPENDENCIES) $(EXTRA_t_urbui_DEPENDENCIES) + @rm -f t-urbui$(EXEEXT) + $(LINK) $(t_urbui_OBJECTS) $(t_urbui_LDADD) $(LIBS) +t-urmui$(EXEEXT): $(t_urmui_OBJECTS) $(t_urmui_DEPENDENCIES) $(EXTRA_t_urmui_DEPENDENCIES) + @rm -f t-urmui$(EXEEXT) + $(LINK) $(t_urmui_OBJECTS) $(t_urmui_LDADD) $(LIBS) +t-urndmm$(EXEEXT): $(t_urndmm_OBJECTS) $(t_urndmm_DEPENDENCIES) $(EXTRA_t_urndmm_DEPENDENCIES) + @rm -f t-urndmm$(EXEEXT) + $(LINK) $(t_urndmm_OBJECTS) $(t_urndmm_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +.c.o: + $(COMPILE) -c $< + +.c.obj: + $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: + $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-checkPROGRAMS clean-generic clean-libtool \ + mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am + + +allprogs: $(EXTRA_PROGRAMS) + +$(top_builddir)/tests/libtests.la: + cd $(top_builddir)/tests; $(MAKE) $(AM_MAKEFLAGS) libtests.la + +manual-test: gen$(EXEEXT) stat$(EXEEXT) + @(echo -n '16i: '; ./gen -f mpz_urandomb -z 16 1000 \ + | ./stat -i 0xffff | grep '^[0-9]') + @(echo -n '32i: '; ./gen -f mpz_urandomb -z 32 1000 \ + | ./stat -i 0xffffffff | grep '^[0-9]') + @(echo -n '33i: '; ./gen -f mpz_urandomb -z 33 1000 \ + | ./stat -i 0x1ffffffff | grep '^[0-9]') + @(echo -n '64i: '; ./gen -f mpz_urandomb -z 64 1000 \ + | ./stat -i 0xffffffffffffffff | grep '^[0-9]') + @(echo -n '128i: '; ./gen -f mpz_urandomb -z 128 1000 \ + | ./stat -i 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF | grep '^[0-9]') + + @(echo -n '16f: '; ./gen -f mpf_urandomb -z 16 1000 \ + | ./stat | grep '^[0-9]') + @(echo -n '32f: '; ./gen -f mpf_urandomb -z 32 1000 \ + | ./stat | grep '^[0-9]') + @(echo -n '33f: '; ./gen -f mpf_urandomb -z 33 1000 \ + | ./stat | grep '^[0-9]') + @(echo -n '64f: '; ./gen -f mpf_urandomb -z 64 1000 \ + | ./stat | grep '^[0-9]') + @(echo -n '128f: '; ./gen -f mpf_urandomb -z 128 1000 \ + | ./stat | grep '^[0-9]') + +manual-bigtest: gen$(EXEEXT) stat$(EXEEXT) + @(echo '16i: '; ./gen -f mpz_urandomb -z 16 50000 \ + | ./stat -2 1000 -i 0xffff | grep '^K[mp]') + @(echo '32i: '; ./gen -f mpz_urandomb -z 32 50000 \ + | ./stat -2 1000 -i 0xffffffff | grep '^K[mp]') + @(echo '33i: '; ./gen -f mpz_urandomb -z 33 50000 \ + | ./stat -2 1000 -i 0x1ffffffff | grep '^K[mp]') + @(echo '64i: '; ./gen -f mpz_urandomb -z 64 50000 \ + | ./stat -2 1000 -i 0xffffffffffffffff | grep '^K[mp]') + @(echo '128i: '; ./gen -f mpz_urandomb -z 128 50000 \ + | ./stat -2 1000 -i 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF | grep '^K[mp]') + + @(echo '16f: '; ./gen -f mpf_urandomb -z 16 50000 \ + | ./stat -2 1000 | grep '^K[mp]') + @(echo '32f: '; ./gen -f mpf_urandomb -z 32 50000 \ + | ./stat -2 1000 | grep '^K[mp]') + @(echo '33f: '; ./gen -f mpf_urandomb -z 33 50000 \ + | ./stat -2 1000 | grep '^K[mp]') + @(echo '64f: '; ./gen -f mpf_urandomb -z 64 50000 \ + | ./stat -2 1000 | grep '^K[mp]') + @(echo '128f: '; ./gen -f mpf_urandomb -z 128 50000 \ + | ./stat -2 1000 | grep '^K[mp]') + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/gmp/tests/rand/findlc.c b/gmp/tests/rand/findlc.c new file mode 100644 index 0000000000..2406c3b645 --- /dev/null +++ b/gmp/tests/rand/findlc.c @@ -0,0 +1,252 @@ +/* +Copyright 2000 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <signal.h> +#include <math.h> +#include "gmp.h" +#include "gmpstat.h" + +#define RCSID(msg) \ +static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } + +RCSID("$Id$"); + +int g_debug = 0; + +static mpz_t a; + +static void +sh_status (int sig) +{ + printf ("sh_status: signal %d caught. dumping status.\n", sig); + + printf (" a = "); + mpz_out_str (stdout, 10, a); + printf ("\n"); + fflush (stdout); + + if (SIGSEGV == sig) /* remove SEGV handler */ + signal (SIGSEGV, SIG_DFL); +} + +/* Input is a modulus (m). We shall find multiplier (a) and adder (c) + conforming to the rules found in the first comment block in file + mpz/urandom.c. + + Then run a spectral test on the generator and discard any + multipliers not passing. */ + +/* TODO: + + . find a better algorithm than a+=8; bigger jumps perhaps? + +*/ + +void +mpz_true_random (mpz_t s, unsigned long int nbits) +{ +#if __FreeBSD__ + FILE *fs; + char c[1]; + int i; + + mpz_set_ui (s, 0); + for (i = 0; i < nbits; i += 8) + { + for (;;) + { + int nread; + fs = fopen ("/dev/random", "r"); + nread = fread (c, 1, 1, fs); + fclose (fs); + if (nread != 0) + break; + sleep (1); + } + mpz_mul_2exp (s, s, 8); + mpz_add_ui (s, s, ((unsigned long int) c[0]) & 0xff); + printf ("%d random bits\n", i + 8); + } + if (nbits % 8 != 0) + mpz_mod_2exp (s, s, nbits); +#endif +} + +int +main (int argc, char *argv[]) +{ + const char usage[] = "usage: findlc [-dv] m2exp [low_merit [high_merit]]\n"; + int f; + int v_lose, m_lose, v_best, m_best; + int c; + int debug = 1; + int cnt_high_merit; + mpz_t m; + unsigned long int m2exp; +#define DIMS 6 /* dimensions run in spectral test */ + mpf_t v[DIMS-1]; /* spectral test result (there's no v + for 1st dimension */ + mpf_t f_merit, low_merit, high_merit; + mpz_t acc, minus8; + mpz_t min, max; + mpz_t s; + + + mpz_init (m); + mpz_init (a); + for (f = 0; f < DIMS-1; f++) + mpf_init (v[f]); + mpf_init (f_merit); + mpf_init_set_d (low_merit, .1); + mpf_init_set_d (high_merit, .1); + + while ((c = getopt (argc, argv, "a:di:hv")) != -1) + switch (c) + { + case 'd': /* debug */ + g_debug++; + break; + + case 'v': /* print version */ + puts (rcsid[1]); + exit (0); + + case 'h': + case '?': + default: + fputs (usage, stderr); + exit (1); + } + + argc -= optind; + argv += optind; + + if (argc < 1) + { + fputs (usage, stderr); + exit (1); + } + + /* Install signal handler. */ + if (SIG_ERR == signal (SIGSEGV, sh_status)) + { + perror ("signal (SIGSEGV)"); + exit (1); + } + if (SIG_ERR == signal (SIGHUP, sh_status)) + { + perror ("signal (SIGHUP)"); + exit (1); + } + + printf ("findlc: version: %s\n", rcsid[1]); + m2exp = atol (argv[0]); + mpz_init_set_ui (m, 1); + mpz_mul_2exp (m, m, m2exp); + printf ("m = 0x"); + mpz_out_str (stdout, 16, m); + puts (""); + + if (argc > 1) /* have low_merit */ + mpf_set_str (low_merit, argv[1], 0); + if (argc > 2) /* have high_merit */ + mpf_set_str (high_merit, argv[2], 0); + + if (debug) + { + fprintf (stderr, "low_merit = "); + mpf_out_str (stderr, 10, 2, low_merit); + fprintf (stderr, "; high_merit = "); + mpf_out_str (stderr, 10, 2, high_merit); + fputs ("\n", stderr); + } + + mpz_init (minus8); + mpz_set_si (minus8, -8L); + mpz_init_set_ui (acc, 0); + mpz_init (s); + mpz_init_set_d (min, 0.01 * pow (2.0, (double) m2exp)); + mpz_init_set_d (max, 0.99 * pow (2.0, (double) m2exp)); + + mpz_true_random (s, m2exp); /* Start. */ + mpz_setbit (s, 0); /* Make it odd. */ + + v_best = m_best = 2*(DIMS-1); + for (;;) + { + mpz_add (acc, acc, s); + mpz_mod_2exp (acc, acc, m2exp); +#if later + mpz_and_si (a, acc, -8L); +#else + mpz_and (a, acc, minus8); +#endif + mpz_add_ui (a, a, 5); + if (mpz_cmp (a, min) <= 0 || mpz_cmp (a, max) >= 0) + continue; + + spectral_test (v, DIMS, a, m); + for (f = 0, v_lose = m_lose = 0, cnt_high_merit = DIMS-1; + f < DIMS-1; f++) + { + merit (f_merit, f + 2, v[f], m); + + if (mpf_cmp_ui (v[f], 1 << (30 / (f + 2) + (f == 2))) < 0) + v_lose++; + + if (mpf_cmp (f_merit, low_merit) < 0) + m_lose++; + + if (mpf_cmp (f_merit, high_merit) >= 0) + cnt_high_merit--; + } + + if (0 == v_lose && 0 == m_lose) + { + mpz_out_str (stdout, 10, a); puts (""); fflush (stdout); + if (0 == cnt_high_merit) + break; /* leave loop */ + } + if (v_lose < v_best) + { + v_best = v_lose; + printf ("best (v_lose=%d; m_lose=%d): ", v_lose, m_lose); + mpz_out_str (stdout, 10, a); puts (""); fflush (stdout); + } + if (m_lose < m_best) + { + m_best = m_lose; + printf ("best (v_lose=%d; m_lose=%d): ", v_lose, m_lose); + mpz_out_str (stdout, 10, a); puts (""); fflush (stdout); + } + } + + mpz_clear (m); + mpz_clear (a); + for (f = 0; f < DIMS-1; f++) + mpf_clear (v[f]); + mpf_clear (f_merit); + mpf_clear (low_merit); + mpf_clear (high_merit); + + printf ("done.\n"); + return 0; +} diff --git a/gmp/tests/rand/gen.c b/gmp/tests/rand/gen.c new file mode 100644 index 0000000000..65401e3751 --- /dev/null +++ b/gmp/tests/rand/gen.c @@ -0,0 +1,481 @@ +/* gen.c -- Generate pseudorandom numbers. + +Copyright 1999, 2000, 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +/* Examples: + + $ gen 10 +10 integers 0 <= X < 2^32 generated by mpz_urandomb() + + $ gen -f mpf_urandomb 10 +10 real numbers 0 <= X < 1 + + $ gen -z 127 10 +10 integers 0 <= X < 2^127 + + $ gen -f mpf_urandomb -x .9,1 10 +10 real numbers 0 <= X < .9 + + $ gen -s 1 10 +10 integers, sequence seeded with 1 + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <limits.h> +#include <errno.h> +#include <time.h> +#include <string.h> + +#if !HAVE_DECL_OPTARG +extern char *optarg; +extern int optind, opterr; +#endif + +#include "gmp.h" +#include "gmp-impl.h" + +int main (argc, argv) + int argc; + char *argv[]; +{ + const char usage[] = + "usage: gen [-bhpq] [-a n] [-c a,c,m2exp] [-C a,c,m] [-f func] [-g alg] [-m n] [-s n] " \ + "[-x f,t] [-z n] [n]\n" \ + " n number of random numbers to generate\n" \ + " -a n ASCII output in radix n (default, with n=10)\n" \ + " -b binary output\n" \ + " -c a,c,m2exp use supplied LC scheme\n" \ + " -f func random function, one of\n" \ + " mpz_urandomb (default), mpz_urandomm, mpf_urandomb, rand, random\n" \ + " -g alg algorithm, one of mt (default), lc\n" \ + " -h print this text and exit\n" \ + " -m n maximum size of generated number plus 1 (0<= X < n) for mpz_urandomm\n" \ + " -p print used seed on stderr\n" \ + " -q quiet, no output\n" \ + " -s n initial seed (default: output from time(3))\n" \ + " -x f,t exclude all numbers f <= x <= t\n" \ + " -z n size in bits of generated numbers (0<= X <2^n) (default 32)\n" \ + ""; + + unsigned long int f; + unsigned long int n = 0; + unsigned long int seed; + unsigned long int m2exp = 0; + unsigned int size = 32; + int seed_from_user = 0; + int ascout = 1, binout = 0, printseed = 0; + int output_radix = 10; + int lc_scheme_from_user = 0; + int quiet_flag = 0; + mpz_t z_seed; + mpz_t z1; + mpf_t f1; + gmp_randstate_t rstate; + int c, i; + double drand; + long lrand; + int do_exclude = 0; + mpf_t f_xf, f_xt; /* numbers to exclude from sequence */ + char *str_xf, *str_xt; /* numbers to exclude from sequence */ + char *str_a, *str_adder, *str_m; + mpz_t z_a, z_m, z_mmax; + unsigned long int ul_adder; + + enum + { + RFUNC_mpz_urandomb = 0, + RFUNC_mpz_urandomm, + RFUNC_mpf_urandomb, + RFUNC_rand, + RFUNC_random, + } rfunc = RFUNC_mpz_urandomb; + char *rfunc_str[] = { "mpz_urandomb", "mpz_urandomm", "mpf_urandomb", + "rand", "random" }; + enum + { + RNG_MT = 0, + RNG_LC + }; + gmp_randalg_t ralg = RNG_MT; + /* Texts for the algorithms. The index of each must match the + corresponding algorithm in the enum above. */ + char *ralg_str[] = { "mt", "lc" }; + + mpf_init (f_xf); + mpf_init (f_xt); + mpf_init (f1); + mpz_init (z1); + mpz_init (z_seed); + mpz_init_set_ui (z_mmax, 0); + + + while ((c = getopt (argc, argv, "a:bc:f:g:hm:n:pqs:z:x:")) != -1) + switch (c) + { + case 'a': + ascout = 1; + binout = 0; + output_radix = atoi (optarg); + break; + + case 'b': + ascout = 0; + binout = 1; + break; + + case 'c': /* User supplied LC scheme: a,c,m2exp */ + if (NULL == (str_a = strtok (optarg, ",")) + || NULL == (str_adder = strtok (NULL, ",")) + || NULL == (str_m = strtok (NULL, ","))) + { + fprintf (stderr, "gen: bad LC scheme parameters: %s\n", optarg); + exit (1); + } +#ifdef HAVE_STRTOUL + ul_adder = strtoul (str_adder, NULL, 0); +#elif HAVE_STRTOL + ul_adder = (unsigned long int) strtol (str_adder, NULL, 0); +#else + ul_adder = (unsigned long int) atoi (str_adder); +#endif + + if (mpz_init_set_str (z_a, str_a, 0)) + { + fprintf (stderr, "gen: bad LC scheme parameter `a': %s\n", str_a); + exit (1); + } + if (ULONG_MAX == ul_adder) + { + fprintf (stderr, "gen: bad LC scheme parameter `c': %s\n", + str_adder); + exit (1); + } + m2exp = atol (str_m); + + lc_scheme_from_user = 1; + break; + + + case 'f': + rfunc = -1; + for (f = 0; f < sizeof (rfunc_str) / sizeof (*rfunc_str); f++) + if (!strcmp (optarg, rfunc_str[f])) + { + rfunc = f; + break; + } + if (rfunc == -1) + { + fputs (usage, stderr); + exit (1); + } + break; + + case 'g': /* algorithm */ + ralg = -1; + for (f = 0; f < sizeof (ralg_str) / sizeof (*ralg_str); f++) + if (!strcmp (optarg, ralg_str[f])) + { + ralg = f; + break; + } + if (ralg == -1) + { + fputs (usage, stderr); + exit (1); + } + break; + + case 'm': /* max for mpz_urandomm() */ + if (mpz_set_str (z_mmax, optarg, 0)) + { + fprintf (stderr, "gen: bad max value: %s\n", optarg); + exit (1); + } + break; + + case 'p': /* print seed on stderr */ + printseed = 1; + break; + + case 'q': /* quiet */ + quiet_flag = 1; + break; + + case 's': /* user provided seed */ + if (mpz_set_str (z_seed, optarg, 0)) + { + fprintf (stderr, "gen: bad seed argument %s\n", optarg); + exit (1); + } + seed_from_user = 1; + break; + + case 'z': + size = atoi (optarg); + if (size < 1) + { + fprintf (stderr, "gen: bad size argument (-z %u)\n", size); + exit (1); + } + break; + + case 'x': /* Exclude. from,to */ + str_xf = optarg; + str_xt = strchr (optarg, ','); + if (NULL == str_xt) + { + fprintf (stderr, "gen: bad exclusion parameters: %s\n", optarg); + exit (1); + } + *str_xt++ = '\0'; + do_exclude = 1; + break; + + case 'h': + case '?': + default: + fputs (usage, stderr); + exit (1); + } + argc -= optind; + argv += optind; + + if (! seed_from_user) + mpz_set_ui (z_seed, (unsigned long int) time (NULL)); + seed = mpz_get_ui (z_seed); + if (printseed) + { + fprintf (stderr, "gen: seed used: "); + mpz_out_str (stderr, output_radix, z_seed); + fprintf (stderr, "\n"); + } + + mpf_set_prec (f1, size); + + /* init random state and plant seed */ + switch (rfunc) + { + case RFUNC_mpf_urandomb: +#if 0 + /* Don't init a too small generator. */ + size = PREC (f1) * GMP_LIMB_BITS; + /* Fall through. */ +#endif + case RFUNC_mpz_urandomb: + case RFUNC_mpz_urandomm: + switch (ralg) + { + case RNG_MT: + gmp_randinit_mt (rstate); + break; + + case RNG_LC: + if (! lc_scheme_from_user) + gmp_randinit_lc_2exp_size (rstate, MIN (128, size)); + else + gmp_randinit_lc_2exp (rstate, z_a, ul_adder, m2exp); + break; + + default: + fprintf (stderr, "gen: unsupported algorithm\n"); + exit (1); + } + + gmp_randseed (rstate, z_seed); + break; + + case RFUNC_rand: + srand (seed); + break; + + case RFUNC_random: +#ifdef __FreeBSD__ /* FIXME */ + if (seed_from_user) + srandom (seed); + else + srandomdev (); +#else + fprintf (stderr, "gen: unsupported algorithm\n"); +#endif + break; + + default: + fprintf (stderr, "gen: random function not implemented\n"); + exit (1); + } + + /* set up excludes */ + if (do_exclude) + switch (rfunc) + { + case RFUNC_mpf_urandomb: + + if (mpf_set_str (f_xf, str_xf, 10) || + mpf_set_str (f_xt, str_xt, 10)) + { + fprintf (stderr, "gen: bad exclusion-from (\"%s\") " \ + "or exclusion-to (\"%s\") string. no exclusion done.\n", + str_xf, str_xt); + do_exclude = 0; + } + break; + + default: + fprintf (stderr, "gen: exclusion not implemented for chosen " \ + "randomization function. all numbers included in sequence.\n"); + } + + /* generate and print */ + if (argc > 0) + { +#if HAVE_STRTOUL + n = strtoul (argv[0], (char **) NULL, 10); +#elif HAVE_STRTOL + n = (unsigned long int) strtol (argv[0], (char **) NULL, 10); +#else + n = (unsigned long int) atoi (argv[0]); +#endif + } + + for (f = 0; n == 0 || f < n; f++) + { + switch (rfunc) + { + case RFUNC_mpz_urandomb: + mpz_urandomb (z1, rstate, size); + if (quiet_flag) + break; + if (binout) + { + /*fwrite ((unsigned int *) z1->_mp_d, 4, 1, stdout);*/ + fprintf (stderr, "gen: binary output for mpz_urandom* is broken\n"); + exit (1); + } + else + { + mpz_out_str (stdout, output_radix, z1); + puts (""); + } + break; + + case RFUNC_mpz_urandomm: + mpz_urandomm (z1, rstate, z_mmax); + if (quiet_flag) + break; + if (binout) + { + /*fwrite ((unsigned int *) z1->_mp_d, 4, 1, stdout);*/ + fprintf (stderr, "gen: binary output for mpz_urandom* is broken\n"); + exit (1); + } + else + { + mpz_out_str (stdout, output_radix, z1); + puts (""); + } + break; + + case RFUNC_mpf_urandomb: + mpf_urandomb (f1, rstate, size); + if (do_exclude) + if (mpf_cmp (f1, f_xf) >= 0 && mpf_cmp (f1, f_xt) <= 0) + break; + if (quiet_flag) + break; + if (binout) + { + fprintf (stderr, "gen: binary output for floating point numbers "\ + "not implemented\n"); + exit (1); + } + else + { + mpf_out_str (stdout, output_radix, 0, f1); + puts (""); + } + break; + + case RFUNC_rand: + i = rand (); +#ifdef FLOAT_OUTPUT + if (i) + drand = (double) i / (double) RAND_MAX; + else + drand = 0.0; + if (quiet_flag) + break; + if (binout) + fwrite (&drand, sizeof (drand), 1, stdout); + else + printf ("%e\n", drand); +#else + if (quiet_flag) + break; + if (binout) + fwrite (&i, sizeof (i), 1, stdout); + else + printf ("%d\n", i); +#endif + break; + + case RFUNC_random: + lrand = random (); + if (lrand) + drand = (double) lrand / (double) 0x7fffffff; + else + drand = 0; + if (quiet_flag) + break; + if (binout) + fwrite (&drand, sizeof (drand), 1, stdout); + else + printf ("%e\n", drand); + break; + + default: + fprintf (stderr, "gen: random function not implemented\n"); + exit (1); + } + + } + + /* clean up */ + switch (rfunc) + { + case RFUNC_mpz_urandomb: + case RFUNC_mpf_urandomb: + gmp_randclear (rstate); + break; + default: + break; + } + mpf_clear (f1); + mpf_clear (f_xf); + mpf_clear (f_xt); + mpz_clear (z1); + mpz_clear (z_seed); + + return 0; +} + +static void *debug_dummyz = mpz_dump; +static void *debug_dummyf = mpf_dump; diff --git a/gmp/tests/rand/gmpstat.h b/gmp/tests/rand/gmpstat.h new file mode 100644 index 0000000000..99c5cca195 --- /dev/null +++ b/gmp/tests/rand/gmpstat.h @@ -0,0 +1,75 @@ +/* gmpstat.h */ + +/* +Copyright 1999 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +/* This file requires the following header files: gmp.h */ + +#ifndef __GMPSTAT_H__ +#define __GMPSTAT_H__ + +/* Global debug flag. FIXME: Remove. */ +extern int g_debug; +#define DEBUG_1 0 +#define DEBUG_2 1 + +/* Max number of dimensions in spectral test. FIXME: Makw dynamic. */ +#define GMP_SPECT_MAXT 10 + +void +mpf_freqt (mpf_t Kp, + mpf_t Km, + mpf_t X[], + const unsigned long int n); +unsigned long int +mpz_freqt (mpf_t V, + mpz_t X[], + unsigned int imax, + const unsigned long int n); + +/* Low level functions. */ +void +ks (mpf_t Kp, + mpf_t Km, + mpf_t X[], + void (P) (mpf_t, mpf_t), + const unsigned long int n); + +void +ks_table (mpf_t p, mpf_t val, const unsigned int n); + +void +x2_table (double t[], + unsigned int v); + +void +spectral_test (mpf_t rop[], unsigned int T, mpz_t a, mpz_t m); +void +vz_dot (mpz_t rop, mpz_t V1[], mpz_t V2[], unsigned int n); +void +f_floor (mpf_t rop, mpf_t op); + +void +merit (mpf_t rop, unsigned int t, mpf_t v, mpz_t m); +double +merit_u (unsigned int t, mpf_t v, mpz_t m); + +/* From separate source files: */ +void zdiv_round (mpz_t rop, mpz_t n, mpz_t d); + +#endif /* !__GMPSTAT_H__ */ diff --git a/gmp/tests/rand/spect.c b/gmp/tests/rand/spect.c new file mode 100644 index 0000000000..596ff3a9c4 --- /dev/null +++ b/gmp/tests/rand/spect.c @@ -0,0 +1,137 @@ +/* spect.c -- the spectral test */ + +/* +Copyright 1999 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +/* T is upper dimension. Z_A is the LC multiplier, which is + relatively prime to Z_M, the LC modulus. The result is put in + rop[] with v[t] in rop[t-2]. */ + +/* BUGS: Due to lazy allocation scheme, maximum T is hard coded to MAXT. */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <math.h> +#include "gmp.h" + +#include "gmpstat.h" + +int g_debug = 0; + +int +main (int argc, char *argv[]) +{ + const char usage[] = "usage: spect [-d] a m n\n"; + int c; + unsigned int n; + mpz_t a, m; + mpf_t res[GMP_SPECT_MAXT], res_min[GMP_SPECT_MAXT], f_tmp; + int f; + + + mpz_init (a); + mpz_init (m); + for (f = 0; f < GMP_SPECT_MAXT; f++) + { + mpf_init (res[f]); + mpf_init (res_min[f]); + } + mpf_init (f_tmp); + mpf_set_ui (res_min[0], 32768); /* 2^15 */ + mpf_set_ui (res_min[1], 1024); /* 2^10 */ + mpf_set_ui (res_min[2], 256); /* 2^8 */ + mpf_set_ui (res_min[3], 64); /* 2^6 */ + mpf_set_ui (res_min[4], 32); /* 2^5 */ + + while ((c = getopt (argc, argv, "dh")) != -1) + switch (c) + { + case 'd': /* debug */ + g_debug++; + break; + case 'h': + default: + fputs (usage, stderr); + exit (1); + } + argc -= optind; + argv += optind; + + if (argc < 3) + { + fputs (usage, stderr); + exit (1); + } + + mpz_set_str (a, argv[0], 0); + mpz_set_str (m, argv[1], 0); + n = (unsigned int) atoi (argv[2]); + if (n + 1 > GMP_SPECT_MAXT) + n = GMP_SPECT_MAXT + 1; + + spectral_test (res, n, a, m); + + for (f = 0; f < n - 1; f++) + { + /* print v */ + printf ("%d: v = ", f + 2); + mpf_out_str (stdout, 10, 4, res[f]); + +#ifdef PRINT_RAISED_BY_TWO_AS_WELL + printf (" (^2 = "); + mpf_mul (f_tmp, res[f], res[f]); + mpf_out_str (stdout, 10, 4, f_tmp); + printf (")"); +#endif /* PRINT_RAISED_BY_TWO_AS_WELL */ + + /* print merit */ + printf (" m = "); + merit (f_tmp, f + 2, res[f], m); + mpf_out_str (stdout, 10, 4, f_tmp); + + if (mpf_cmp (res[f], res_min[f]) < 0) + printf ("\t*** v too low ***"); + if (mpf_get_d (f_tmp) < .1) + printf ("\t*** merit too low ***"); + + puts (""); + } + + mpz_clear (a); + mpz_clear (m); + for (f = 0; f < GMP_SPECT_MAXT; f++) + { + mpf_clear (res[f]); + mpf_clear (res_min[f]); + } + mpf_clear (f_tmp); + + return 0; +} + + +void +debug_foo() +{ + if (0) + { + mpz_dump (0); + mpf_dump (0); + } +} diff --git a/gmp/tests/rand/stat.c b/gmp/tests/rand/stat.c new file mode 100644 index 0000000000..1285ccfb9f --- /dev/null +++ b/gmp/tests/rand/stat.c @@ -0,0 +1,407 @@ +/* stat.c -- statistical tests of random number sequences. */ + +/* +Copyright 1999, 2000 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +/* Examples: + + $ gen 1000 | stat +Test 1000 real numbers. + + $ gen 30000 | stat -2 1000 +Test 1000 real numbers 30 times and then test the 30 results in a +``second level''. + + $ gen -f mpz_urandomb 1000 | stat -i 0xffffffff +Test 1000 integers 0 <= X <= 2^32-1. + + $ gen -f mpz_urandomb -z 34 1000 | stat -i 0x3ffffffff +Test 1000 integers 0 <= X <= 2^34-1. + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <math.h> +#include "gmp.h" +#include "gmpstat.h" + +#if !HAVE_DECL_OPTARG +extern char *optarg; +extern int optind, opterr; +#endif + +#define FVECSIZ (100000L) + +int g_debug = 0; + +static void +print_ks_results (mpf_t f_p, mpf_t f_p_prob, + mpf_t f_m, mpf_t f_m_prob, + FILE *fp) +{ + double p, pp, m, mp; + + p = mpf_get_d (f_p); + m = mpf_get_d (f_m); + pp = mpf_get_d (f_p_prob); + mp = mpf_get_d (f_m_prob); + + fprintf (fp, "%.4f (%.0f%%)\t", p, pp * 100.0); + fprintf (fp, "%.4f (%.0f%%)\n", m, mp * 100.0); +} + +static void +print_x2_table (unsigned int v, FILE *fp) +{ + double t[7]; + int f; + + + fprintf (fp, "Chi-square table for v=%u\n", v); + fprintf (fp, "1%%\t5%%\t25%%\t50%%\t75%%\t95%%\t99%%\n"); + x2_table (t, v); + for (f = 0; f < 7; f++) + fprintf (fp, "%.2f\t", t[f]); + fputs ("\n", fp); +} + + + +/* Pks () -- Distribution function for KS results with a big n (like 1000 + or so): F(x) = 1 - pow(e, -2*x^2) [Knuth, vol 2, p.51]. */ +/* gnuplot: plot [0:1] Pks(x), Pks(x) = 1-exp(-2*x**2) */ + +static void +Pks (mpf_t p, mpf_t x) +{ + double dt; /* temp double */ + + mpf_set (p, x); + mpf_mul (p, p, p); /* p = x^2 */ + mpf_mul_ui (p, p, 2); /* p = 2*x^2 */ + mpf_neg (p, p); /* p = -2*x^2 */ + /* No pow() in gmp. Use doubles. */ + /* FIXME: Use exp()? */ + dt = pow (M_E, mpf_get_d (p)); + mpf_set_d (p, dt); + mpf_ui_sub (p, 1, p); +} + +/* f_freq() -- frequency test on real numbers 0<=f<1*/ +static void +f_freq (const unsigned l1runs, const unsigned l2runs, + mpf_t fvec[], const unsigned long n) +{ + unsigned f; + mpf_t f_p, f_p_prob; + mpf_t f_m, f_m_prob; + mpf_t *l1res; /* level 1 result array */ + + mpf_init (f_p); mpf_init (f_m); + mpf_init (f_p_prob); mpf_init (f_m_prob); + + + /* Allocate space for 1st level results. */ + l1res = (mpf_t *) malloc (l2runs * 2 * sizeof (mpf_t)); + if (NULL == l1res) + { + fprintf (stderr, "stat: malloc failure\n"); + exit (1); + } + + printf ("\nEquidistribution/Frequency test on real numbers (0<=X<1):\n"); + printf ("\tKp\t\tKm\n"); + + for (f = 0; f < l2runs; f++) + { + /* f_printvec (fvec, n); */ + mpf_freqt (f_p, f_m, fvec + f * n, n); + + /* what's the probability of getting these results? */ + ks_table (f_p_prob, f_p, n); + ks_table (f_m_prob, f_m, n); + + if (l1runs == 0) + { + /*printf ("%u:\t", f + 1);*/ + print_ks_results (f_p, f_p_prob, f_m, f_m_prob, stdout); + } + else + { + /* save result */ + mpf_init_set (l1res[f], f_p); + mpf_init_set (l1res[f + l2runs], f_m); + } + } + + /* Now, apply the KS test on the results from the 1st level rounds + with the distribution + F(x) = 1 - pow(e, -2*x^2) [Knuth, vol 2, p.51] */ + + if (l1runs != 0) + { + /*printf ("-------------------------------------\n");*/ + + /* The Kp's. */ + ks (f_p, f_m, l1res, Pks, l2runs); + ks_table (f_p_prob, f_p, l2runs); + ks_table (f_m_prob, f_m, l2runs); + printf ("Kp:\t"); + print_ks_results (f_p, f_p_prob, f_m, f_m_prob, stdout); + + /* The Km's. */ + ks (f_p, f_m, l1res + l2runs, Pks, l2runs); + ks_table (f_p_prob, f_p, l2runs); + ks_table (f_m_prob, f_m, l2runs); + printf ("Km:\t"); + print_ks_results (f_p, f_p_prob, f_m, f_m_prob, stdout); + } + + mpf_clear (f_p); mpf_clear (f_m); + mpf_clear (f_p_prob); mpf_clear (f_m_prob); + free (l1res); +} + +/* z_freq(l1runs, l2runs, zvec, n, max) -- frequency test on integers + 0<=z<=MAX */ +static void +z_freq (const unsigned l1runs, + const unsigned l2runs, + mpz_t zvec[], + const unsigned long n, + unsigned int max) +{ + mpf_t V; /* result */ + double d_V; /* result as a double */ + + mpf_init (V); + + + printf ("\nEquidistribution/Frequency test on integers (0<=X<=%u):\n", max); + print_x2_table (max, stdout); + + mpz_freqt (V, zvec, max, n); + + d_V = mpf_get_d (V); + printf ("V = %.2f (n = %lu)\n", d_V, n); + + mpf_clear (V); +} + +unsigned int stat_debug = 0; + +int +main (argc, argv) + int argc; + char *argv[]; +{ + const char usage[] = + "usage: stat [-d] [-2 runs] [-i max | -r max] [file]\n" \ + " file filename\n" \ + " -2 runs perform 2-level test with RUNS runs on 1st level\n" \ + " -d increase debugging level\n" \ + " -i max input is integers 0 <= Z <= MAX\n" \ + " -r max input is real numbers 0 <= R < 1 and use MAX as\n" \ + " maximum value when converting real numbers to integers\n" \ + ""; + + mpf_t fvec[FVECSIZ]; + mpz_t zvec[FVECSIZ]; + unsigned long int f, n, vecentries; + char *filen; + FILE *fp; + int c; + int omitoutput = 0; + int realinput = -1; /* 1: input is real numbers 0<=R<1; + 0: input is integers 0 <= Z <= MAX. */ + long l1runs = 0, /* 1st level runs */ + l2runs = 1; /* 2nd level runs */ + mpf_t f_temp; + mpz_t z_imax; /* max value when converting between + real number and integer. */ + mpf_t f_imax_plus1; /* f_imax + 1 stored in an mpf_t for + convenience */ + mpf_t f_imax_minus1; /* f_imax - 1 stored in an mpf_t for + convenience */ + + + mpf_init (f_temp); + mpz_init_set_ui (z_imax, 0x7fffffff); + mpf_init (f_imax_plus1); + mpf_init (f_imax_minus1); + + while ((c = getopt (argc, argv, "d2:i:r:")) != -1) + switch (c) + { + case '2': + l1runs = atol (optarg); + l2runs = -1; /* set later on */ + break; + case 'd': /* increase debug level */ + stat_debug++; + break; + case 'i': + if (1 == realinput) + { + fputs ("stat: options -i and -r are mutually exclusive\n", stderr); + exit (1); + } + if (mpz_set_str (z_imax, optarg, 0)) + { + fprintf (stderr, "stat: bad max value %s\n", optarg); + exit (1); + } + realinput = 0; + break; + case 'r': + if (0 == realinput) + { + fputs ("stat: options -i and -r are mutually exclusive\n", stderr); + exit (1); + } + if (mpz_set_str (z_imax, optarg, 0)) + { + fprintf (stderr, "stat: bad max value %s\n", optarg); + exit (1); + } + realinput = 1; + break; + case 'o': + omitoutput = atoi (optarg); + break; + case '?': + default: + fputs (usage, stderr); + exit (1); + } + argc -= optind; + argv += optind; + + if (argc < 1) + fp = stdin; + else + filen = argv[0]; + + if (fp != stdin) + if (NULL == (fp = fopen (filen, "r"))) + { + perror (filen); + exit (1); + } + + if (-1 == realinput) + realinput = 1; /* default is real numbers */ + + /* read file and fill appropriate vec */ + if (1 == realinput) /* real input */ + { + for (f = 0; f < FVECSIZ ; f++) + { + mpf_init (fvec[f]); + if (!mpf_inp_str (fvec[f], fp, 10)) + break; + } + } + else /* integer input */ + { + for (f = 0; f < FVECSIZ ; f++) + { + mpz_init (zvec[f]); + if (!mpz_inp_str (zvec[f], fp, 10)) + break; + } + } + vecentries = n = f; /* number of entries read */ + fclose (fp); + + if (FVECSIZ == f) + fprintf (stderr, "stat: warning: discarding input due to lazy allocation "\ + "of only %ld entries. sorry.\n", FVECSIZ); + + printf ("Got %lu numbers.\n", n); + + /* convert and fill the other vec */ + /* since fvec[] contains 0<=f<1 and we want ivec[] to contain + 0<=z<=imax and we are truncating all fractions when + converting float to int, we have to add 1 to imax.*/ + mpf_set_z (f_imax_plus1, z_imax); + mpf_add_ui (f_imax_plus1, f_imax_plus1, 1); + if (1 == realinput) /* fill zvec[] */ + { + for (f = 0; f < n; f++) + { + mpf_mul (f_temp, fvec[f], f_imax_plus1); + mpz_init (zvec[f]); + mpz_set_f (zvec[f], f_temp); /* truncating fraction */ + if (stat_debug > 1) + { + mpz_out_str (stderr, 10, zvec[f]); + fputs ("\n", stderr); + } + } + } + else /* integer input; fill fvec[] */ + { + /* mpf_set_z (f_imax_minus1, z_imax); + mpf_sub_ui (f_imax_minus1, f_imax_minus1, 1);*/ + for (f = 0; f < n; f++) + { + mpf_init (fvec[f]); + mpf_set_z (fvec[f], zvec[f]); + mpf_div (fvec[f], fvec[f], f_imax_plus1); + if (stat_debug > 1) + { + mpf_out_str (stderr, 10, 0, fvec[f]); + fputs ("\n", stderr); + } + } + } + + /* 2 levels? */ + if (1 != l2runs) + { + l2runs = n / l1runs; + printf ("Doing %ld second level rounds "\ + "with %ld entries in each round", l2runs, l1runs); + if (n % l1runs) + printf (" (discarding %ld entr%s)", n % l1runs, + n % l1runs == 1 ? "y" : "ies"); + puts ("."); + n = l1runs; + } + +#ifndef DONT_FFREQ + f_freq (l1runs, l2runs, fvec, n); +#endif +#ifdef DO_ZFREQ + z_freq (l1runs, l2runs, zvec, n, mpz_get_ui (z_imax)); +#endif + + mpf_clear (f_temp); mpz_clear (z_imax); + mpf_clear (f_imax_plus1); + mpf_clear (f_imax_minus1); + for (f = 0; f < vecentries; f++) + { + mpf_clear (fvec[f]); + mpz_clear (zvec[f]); + } + + return 0; +} diff --git a/gmp/tests/rand/statlib.c b/gmp/tests/rand/statlib.c new file mode 100644 index 0000000000..7cecd6dee2 --- /dev/null +++ b/gmp/tests/rand/statlib.c @@ -0,0 +1,837 @@ +/* statlib.c -- Statistical functions for testing the randomness of + number sequences. */ + +/* +Copyright 1999, 2000 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +/* The theories for these functions are taken from D. Knuth's "The Art +of Computer Programming: Volume 2, Seminumerical Algorithms", Third +Edition, Addison Wesley, 1998. */ + +/* Implementation notes. + +The Kolmogorov-Smirnov test. + +Eq. (13) in Knuth, p. 50, says that if X1, X2, ..., Xn are independent +observations arranged into ascending order + + Kp = sqr(n) * max(j/n - F(Xj)) for all 1<=j<=n + Km = sqr(n) * max(F(Xj) - (j-1)/n)) for all 1<=j<=n + +where F(x) = Pr(X <= x) = probability that (X <= x), which for a +uniformly distributed random real number between zero and one is +exactly the number itself (x). + + +The answer to exercise 23 gives the following implementation, which +doesn't need the observations to be sorted in ascending order: + +for (k = 0; k < m; k++) + a[k] = 1.0 + b[k] = 0.0 + c[k] = 0 + +for (each observation Xj) + Y = F(Xj) + k = floor (m * Y) + a[k] = min (a[k], Y) + b[k] = max (b[k], Y) + c[k] += 1 + + j = 0 + rp = rm = 0 + for (k = 0; k < m; k++) + if (c[k] > 0) + rm = max (rm, a[k] - j/n) + j += c[k] + rp = max (rp, j/n - b[k]) + +Kp = sqr (n) * rp +Km = sqr (n) * rm + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + +#include "gmp.h" +#include "gmpstat.h" + +/* ks (Kp, Km, X, P, n) -- Perform a Kolmogorov-Smirnov test on the N + real numbers between zero and one in vector X. P is the + distribution function, called for each entry in X, which should + calculate the probability of X being greater than or equal to any + number in the sequence. (For a uniformly distributed sequence of + real numbers between zero and one, this is simply equal to X.) The + result is put in Kp and Km. */ + +void +ks (mpf_t Kp, + mpf_t Km, + mpf_t X[], + void (P) (mpf_t, mpf_t), + unsigned long int n) +{ + mpf_t Kt; /* temp */ + mpf_t f_x; + mpf_t f_j; /* j */ + mpf_t f_jnq; /* j/n or (j-1)/n */ + unsigned long int j; + + /* Sort the vector in ascending order. */ + qsort (X, n, sizeof (__mpf_struct), mpf_cmp); + + /* K-S test. */ + /* Kp = sqr(n) * max(j/n - F(Xj)) for all 1<=j<=n + Km = sqr(n) * max(F(Xj) - (j-1)/n)) for all 1<=j<=n + */ + + mpf_init (Kt); mpf_init (f_x); mpf_init (f_j); mpf_init (f_jnq); + mpf_set_ui (Kp, 0); mpf_set_ui (Km, 0); + for (j = 1; j <= n; j++) + { + P (f_x, X[j-1]); + mpf_set_ui (f_j, j); + + mpf_div_ui (f_jnq, f_j, n); + mpf_sub (Kt, f_jnq, f_x); + if (mpf_cmp (Kt, Kp) > 0) + mpf_set (Kp, Kt); + if (g_debug > DEBUG_2) + { + printf ("j=%lu ", j); + printf ("P()="); mpf_out_str (stdout, 10, 2, f_x); printf ("\t"); + + printf ("jnq="); mpf_out_str (stdout, 10, 2, f_jnq); printf (" "); + printf ("diff="); mpf_out_str (stdout, 10, 2, Kt); printf (" "); + printf ("Kp="); mpf_out_str (stdout, 10, 2, Kp); printf ("\t"); + } + mpf_sub_ui (f_j, f_j, 1); + mpf_div_ui (f_jnq, f_j, n); + mpf_sub (Kt, f_x, f_jnq); + if (mpf_cmp (Kt, Km) > 0) + mpf_set (Km, Kt); + + if (g_debug > DEBUG_2) + { + printf ("jnq="); mpf_out_str (stdout, 10, 2, f_jnq); printf (" "); + printf ("diff="); mpf_out_str (stdout, 10, 2, Kt); printf (" "); + printf ("Km="); mpf_out_str (stdout, 10, 2, Km); printf (" "); + printf ("\n"); + } + } + mpf_sqrt_ui (Kt, n); + mpf_mul (Kp, Kp, Kt); + mpf_mul (Km, Km, Kt); + + mpf_clear (Kt); mpf_clear (f_x); mpf_clear (f_j); mpf_clear (f_jnq); +} + +/* ks_table(val, n) -- calculate probability for Kp/Km less than or + equal to VAL with N observations. See [Knuth section 3.3.1] */ + +void +ks_table (mpf_t p, mpf_t val, const unsigned int n) +{ + /* We use Eq. (27), Knuth p.58, skipping O(1/n) for simplicity. + This shortcut will result in too high probabilities, especially + when n is small. + + Pr(Kp(n) <= s) = 1 - pow(e, -2*s^2) * (1 - 2/3*s/sqrt(n) + O(1/n)) */ + + /* We have 's' in variable VAL and store the result in P. */ + + mpf_t t1, t2; + + mpf_init (t1); mpf_init (t2); + + /* t1 = 1 - 2/3 * s/sqrt(n) */ + mpf_sqrt_ui (t1, n); + mpf_div (t1, val, t1); + mpf_mul_ui (t1, t1, 2); + mpf_div_ui (t1, t1, 3); + mpf_ui_sub (t1, 1, t1); + + /* t2 = pow(e, -2*s^2) */ +#ifndef OLDGMP + mpf_pow_ui (t2, val, 2); /* t2 = s^2 */ + mpf_set_d (t2, exp (-(2.0 * mpf_get_d (t2)))); +#else + /* hmmm, gmp doesn't have pow() for floats. use doubles. */ + mpf_set_d (t2, pow (M_E, -(2 * pow (mpf_get_d (val), 2)))); +#endif + + /* p = 1 - t1 * t2 */ + mpf_mul (t1, t1, t2); + mpf_ui_sub (p, 1, t1); + + mpf_clear (t1); mpf_clear (t2); +} + +static double x2_table_X[][7] = { + { -2.33, -1.64, -.674, 0.0, 0.674, 1.64, 2.33 }, /* x */ + { 5.4289, 2.6896, .454276, 0.0, .454276, 2.6896, 5.4289} /* x^2 */ +}; + +#define _2D3 ((double) .6666666666) + +/* x2_table (t, v, n) -- return chi-square table row for V in T[]. */ +void +x2_table (double t[], + unsigned int v) +{ + int f; + + + /* FIXME: Do a table lookup for v <= 30 since the following formula + [Knuth, vol 2, 3.3.1] is only good for v > 30. */ + + /* value = v + sqrt(2*v) * X[p] + (2/3) * X[p]^2 - 2/3 + O(1/sqrt(t) */ + /* NOTE: The O() term is ignored for simplicity. */ + + for (f = 0; f < 7; f++) + t[f] = + v + + sqrt (2 * v) * x2_table_X[0][f] + + _2D3 * x2_table_X[1][f] - _2D3; +} + + +/* P(p, x) -- Distribution function. Calculate the probability of X +being greater than or equal to any number in the sequence. For a +random real number between zero and one given by a uniformly +distributed random number generator, this is simply equal to X. */ + +static void +P (mpf_t p, mpf_t x) +{ + mpf_set (p, x); +} + +/* mpf_freqt() -- Frequency test using KS on N real numbers between zero + and one. See [Knuth vol 2, p.61]. */ +void +mpf_freqt (mpf_t Kp, + mpf_t Km, + mpf_t X[], + const unsigned long int n) +{ + ks (Kp, Km, X, P, n); +} + + +/* The Chi-square test. Eq. (8) in Knuth vol. 2 says that if Y[] + holds the observations and p[] is the probability for.. (to be + continued!) + + V = 1/n * sum((s=1 to k) Y[s]^2 / p[s]) - n */ + +void +x2 (mpf_t V, /* result */ + unsigned long int X[], /* data */ + unsigned int k, /* #of categories */ + void (P) (mpf_t, unsigned long int, void *), /* probability func */ + void *x, /* extra user data passed to P() */ + unsigned long int n) /* #of samples */ +{ + unsigned int f; + mpf_t f_t, f_t2; /* temp floats */ + + mpf_init (f_t); mpf_init (f_t2); + + + mpf_set_ui (V, 0); + for (f = 0; f < k; f++) + { + if (g_debug > DEBUG_2) + fprintf (stderr, "%u: P()=", f); + mpf_set_ui (f_t, X[f]); + mpf_mul (f_t, f_t, f_t); /* f_t = X[f]^2 */ + P (f_t2, f, x); /* f_t2 = Pr(f) */ + if (g_debug > DEBUG_2) + mpf_out_str (stderr, 10, 2, f_t2); + mpf_div (f_t, f_t, f_t2); + mpf_add (V, V, f_t); + if (g_debug > DEBUG_2) + { + fprintf (stderr, "\tV="); + mpf_out_str (stderr, 10, 2, V); + fprintf (stderr, "\t"); + } + } + if (g_debug > DEBUG_2) + fprintf (stderr, "\n"); + mpf_div_ui (V, V, n); + mpf_sub_ui (V, V, n); + + mpf_clear (f_t); mpf_clear (f_t2); +} + +/* Pzf(p, s, x) -- Probability for category S in mpz_freqt(). It's + 1/d for all S. X is a pointer to an unsigned int holding 'd'. */ +static void +Pzf (mpf_t p, unsigned long int s, void *x) +{ + mpf_set_ui (p, 1); + mpf_div_ui (p, p, *((unsigned int *) x)); +} + +/* mpz_freqt(V, X, imax, n) -- Frequency test on integers. [Knuth, + vol 2, 3.3.2]. Keep IMAX low on this one, since we loop from 0 to + IMAX. 128 or 256 could be nice. + + X[] must not contain numbers outside the range 0 <= X <= IMAX. + + Return value is number of observations actually used, after + discarding entries out of range. + + Since X[] contains integers between zero and IMAX, inclusive, we + have IMAX+1 categories. + + Note that N should be at least 5*IMAX. Result is put in V and can + be compared to output from x2_table (v=IMAX). */ + +unsigned long int +mpz_freqt (mpf_t V, + mpz_t X[], + unsigned int imax, + const unsigned long int n) +{ + unsigned long int *v; /* result */ + unsigned int f; + unsigned int d; /* number of categories = imax+1 */ + unsigned int uitemp; + unsigned long int usedn; + + + d = imax + 1; + + v = (unsigned long int *) calloc (imax + 1, sizeof (unsigned long int)); + if (NULL == v) + { + fprintf (stderr, "mpz_freqt(): out of memory\n"); + exit (1); + } + + /* count */ + usedn = n; /* actual number of observations */ + for (f = 0; f < n; f++) + { + uitemp = mpz_get_ui(X[f]); + if (uitemp > imax) /* sanity check */ + { + if (g_debug) + fprintf (stderr, "mpz_freqt(): warning: input insanity: %u, "\ + "ignored.\n", uitemp); + usedn--; + continue; + } + v[uitemp]++; + } + + if (g_debug > DEBUG_2) + { + fprintf (stderr, "counts:\n"); + for (f = 0; f <= imax; f++) + fprintf (stderr, "%u:\t%lu\n", f, v[f]); + } + + /* chi-square with k=imax+1 and P(x)=1/(imax+1) for all x.*/ + x2 (V, v, d, Pzf, (void *) &d, usedn); + + free (v); + return (usedn); +} + +/* debug dummy to drag in dump funcs */ +void +foo_debug () +{ + if (0) + { + mpf_dump (0); +#ifndef OLDGMP + mpz_dump (0); +#endif + } +} + +/* merit (rop, t, v, m) -- calculate merit for spectral test result in + dimension T, see Knuth p. 105. BUGS: Only valid for 2 <= T <= + 6. */ +void +merit (mpf_t rop, unsigned int t, mpf_t v, mpz_t m) +{ + int f; + mpf_t f_m, f_const, f_pi; + + mpf_init (f_m); + mpf_set_z (f_m, m); + mpf_init_set_d (f_const, M_PI); + mpf_init_set_d (f_pi, M_PI); + + switch (t) + { + case 2: /* PI */ + break; + case 3: /* PI * 4/3 */ + mpf_mul_ui (f_const, f_const, 4); + mpf_div_ui (f_const, f_const, 3); + break; + case 4: /* PI^2 * 1/2 */ + mpf_mul (f_const, f_const, f_pi); + mpf_div_ui (f_const, f_const, 2); + break; + case 5: /* PI^2 * 8/15 */ + mpf_mul (f_const, f_const, f_pi); + mpf_mul_ui (f_const, f_const, 8); + mpf_div_ui (f_const, f_const, 15); + break; + case 6: /* PI^3 * 1/6 */ + mpf_mul (f_const, f_const, f_pi); + mpf_mul (f_const, f_const, f_pi); + mpf_div_ui (f_const, f_const, 6); + break; + default: + fprintf (stderr, + "spect (merit): can't calculate merit for dimensions > 6\n"); + mpf_set_ui (f_const, 0); + break; + } + + /* rop = v^t */ + mpf_set (rop, v); + for (f = 1; f < t; f++) + mpf_mul (rop, rop, v); + mpf_mul (rop, rop, f_const); + mpf_div (rop, rop, f_m); + + mpf_clear (f_m); + mpf_clear (f_const); + mpf_clear (f_pi); +} + +double +merit_u (unsigned int t, mpf_t v, mpz_t m) +{ + mpf_t rop; + double res; + + mpf_init (rop); + merit (rop, t, v, m); + res = mpf_get_d (rop); + mpf_clear (rop); + return res; +} + +/* f_floor (rop, op) -- Set rop = floor (op). */ +void +f_floor (mpf_t rop, mpf_t op) +{ + mpz_t z; + + mpz_init (z); + + /* No mpf_floor(). Convert to mpz and back. */ + mpz_set_f (z, op); + mpf_set_z (rop, z); + + mpz_clear (z); +} + + +/* vz_dot (rop, v1, v2, nelem) -- compute dot product of z-vectors V1, + V2. N is number of elements in vectors V1 and V2. */ + +void +vz_dot (mpz_t rop, mpz_t V1[], mpz_t V2[], unsigned int n) +{ + mpz_t t; + + mpz_init (t); + mpz_set_ui (rop, 0); + while (n--) + { + mpz_mul (t, V1[n], V2[n]); + mpz_add (rop, rop, t); + } + + mpz_clear (t); +} + +void +spectral_test (mpf_t rop[], unsigned int T, mpz_t a, mpz_t m) +{ + /* Knuth "Seminumerical Algorithms, Third Edition", section 3.3.4 + (pp. 101-103). */ + + /* v[t] = min { sqrt (x[1]^2 + ... + x[t]^2) | + x[1] + a*x[2] + ... + pow (a, t-1) * x[t] is congruent to 0 (mod m) } */ + + + /* Variables. */ + unsigned int ui_t; + unsigned int ui_i, ui_j, ui_k, ui_l; + mpf_t f_tmp1, f_tmp2; + mpz_t tmp1, tmp2, tmp3; + mpz_t U[GMP_SPECT_MAXT][GMP_SPECT_MAXT], + V[GMP_SPECT_MAXT][GMP_SPECT_MAXT], + X[GMP_SPECT_MAXT], + Y[GMP_SPECT_MAXT], + Z[GMP_SPECT_MAXT]; + mpz_t h, hp, r, s, p, pp, q, u, v; + + /* GMP inits. */ + mpf_init (f_tmp1); + mpf_init (f_tmp2); + for (ui_i = 0; ui_i < GMP_SPECT_MAXT; ui_i++) + { + for (ui_j = 0; ui_j < GMP_SPECT_MAXT; ui_j++) + { + mpz_init_set_ui (U[ui_i][ui_j], 0); + mpz_init_set_ui (V[ui_i][ui_j], 0); + } + mpz_init_set_ui (X[ui_i], 0); + mpz_init_set_ui (Y[ui_i], 0); + mpz_init (Z[ui_i]); + } + mpz_init (tmp1); + mpz_init (tmp2); + mpz_init (tmp3); + mpz_init (h); + mpz_init (hp); + mpz_init (r); + mpz_init (s); + mpz_init (p); + mpz_init (pp); + mpz_init (q); + mpz_init (u); + mpz_init (v); + + /* Implementation inits. */ + if (T > GMP_SPECT_MAXT) + T = GMP_SPECT_MAXT; /* FIXME: Lazy. */ + + /* S1 [Initialize.] */ + ui_t = 2 - 1; /* NOTE: `t' in description == ui_t + 1 + for easy indexing */ + mpz_set (h, a); + mpz_set (hp, m); + mpz_set_ui (p, 1); + mpz_set_ui (pp, 0); + mpz_set (r, a); + mpz_pow_ui (s, a, 2); + mpz_add_ui (s, s, 1); /* s = 1 + a^2 */ + + /* S2 [Euclidean step.] */ + while (1) + { + if (g_debug > DEBUG_1) + { + mpz_mul (tmp1, h, pp); + mpz_mul (tmp2, hp, p); + mpz_sub (tmp1, tmp1, tmp2); + if (mpz_cmpabs (m, tmp1)) + { + printf ("***BUG***: h*pp - hp*p = "); + mpz_out_str (stdout, 10, tmp1); + printf ("\n"); + } + } + if (g_debug > DEBUG_2) + { + printf ("hp = "); + mpz_out_str (stdout, 10, hp); + printf ("\nh = "); + mpz_out_str (stdout, 10, h); + printf ("\n"); + fflush (stdout); + } + + if (mpz_sgn (h)) + mpz_tdiv_q (q, hp, h); /* q = floor(hp/h) */ + else + mpz_set_ui (q, 1); + + if (g_debug > DEBUG_2) + { + printf ("q = "); + mpz_out_str (stdout, 10, q); + printf ("\n"); + fflush (stdout); + } + + mpz_mul (tmp1, q, h); + mpz_sub (u, hp, tmp1); /* u = hp - q*h */ + + mpz_mul (tmp1, q, p); + mpz_sub (v, pp, tmp1); /* v = pp - q*p */ + + mpz_pow_ui (tmp1, u, 2); + mpz_pow_ui (tmp2, v, 2); + mpz_add (tmp1, tmp1, tmp2); + if (mpz_cmp (tmp1, s) < 0) + { + mpz_set (s, tmp1); /* s = u^2 + v^2 */ + mpz_set (hp, h); /* hp = h */ + mpz_set (h, u); /* h = u */ + mpz_set (pp, p); /* pp = p */ + mpz_set (p, v); /* p = v */ + } + else + break; + } + + /* S3 [Compute v2.] */ + mpz_sub (u, u, h); + mpz_sub (v, v, p); + + mpz_pow_ui (tmp1, u, 2); + mpz_pow_ui (tmp2, v, 2); + mpz_add (tmp1, tmp1, tmp2); + if (mpz_cmp (tmp1, s) < 0) + { + mpz_set (s, tmp1); /* s = u^2 + v^2 */ + mpz_set (hp, u); + mpz_set (pp, v); + } + mpf_set_z (f_tmp1, s); + mpf_sqrt (rop[ui_t - 1], f_tmp1); + + /* S4 [Advance t.] */ + mpz_neg (U[0][0], h); + mpz_set (U[0][1], p); + mpz_neg (U[1][0], hp); + mpz_set (U[1][1], pp); + + mpz_set (V[0][0], pp); + mpz_set (V[0][1], hp); + mpz_neg (V[1][0], p); + mpz_neg (V[1][1], h); + if (mpz_cmp_ui (pp, 0) > 0) + { + mpz_neg (V[0][0], V[0][0]); + mpz_neg (V[0][1], V[0][1]); + mpz_neg (V[1][0], V[1][0]); + mpz_neg (V[1][1], V[1][1]); + } + + while (ui_t + 1 != T) /* S4 loop */ + { + ui_t++; + mpz_mul (r, a, r); + mpz_mod (r, r, m); + + /* Add new row and column to U and V. They are initialized with + all elements set to zero, so clearing is not necessary. */ + + mpz_neg (U[ui_t][0], r); /* U: First col in new row. */ + mpz_set_ui (U[ui_t][ui_t], 1); /* U: Last col in new row. */ + + mpz_set (V[ui_t][ui_t], m); /* V: Last col in new row. */ + + /* "Finally, for 1 <= i < t, + set q = round (vi1 * r / m), + vit = vi1*r - q*m, + and Ut=Ut+q*Ui */ + + for (ui_i = 0; ui_i < ui_t; ui_i++) + { + mpz_mul (tmp1, V[ui_i][0], r); /* tmp1=vi1*r */ + zdiv_round (q, tmp1, m); /* q=round(vi1*r/m) */ + mpz_mul (tmp2, q, m); /* tmp2=q*m */ + mpz_sub (V[ui_i][ui_t], tmp1, tmp2); + + for (ui_j = 0; ui_j <= ui_t; ui_j++) /* U[t] = U[t] + q*U[i] */ + { + mpz_mul (tmp1, q, U[ui_i][ui_j]); /* tmp=q*uij */ + mpz_add (U[ui_t][ui_j], U[ui_t][ui_j], tmp1); /* utj = utj + q*uij */ + } + } + + /* s = min (s, zdot (U[t], U[t]) */ + vz_dot (tmp1, U[ui_t], U[ui_t], ui_t + 1); + if (mpz_cmp (tmp1, s) < 0) + mpz_set (s, tmp1); + + ui_k = ui_t; + ui_j = 0; /* WARNING: ui_j no longer a temp. */ + + /* S5 [Transform.] */ + if (g_debug > DEBUG_2) + printf ("(t, k, j, q1, q2, ...)\n"); + do + { + if (g_debug > DEBUG_2) + printf ("(%u, %u, %u", ui_t + 1, ui_k + 1, ui_j + 1); + + for (ui_i = 0; ui_i <= ui_t; ui_i++) + { + if (ui_i != ui_j) + { + vz_dot (tmp1, V[ui_i], V[ui_j], ui_t + 1); /* tmp1=dot(Vi,Vj). */ + mpz_abs (tmp2, tmp1); + mpz_mul_ui (tmp2, tmp2, 2); /* tmp2 = 2*abs(dot(Vi,Vj) */ + vz_dot (tmp3, V[ui_j], V[ui_j], ui_t + 1); /* tmp3=dot(Vj,Vj). */ + + if (mpz_cmp (tmp2, tmp3) > 0) + { + zdiv_round (q, tmp1, tmp3); /* q=round(Vi.Vj/Vj.Vj) */ + if (g_debug > DEBUG_2) + { + printf (", "); + mpz_out_str (stdout, 10, q); + } + + for (ui_l = 0; ui_l <= ui_t; ui_l++) + { + mpz_mul (tmp1, q, V[ui_j][ui_l]); + mpz_sub (V[ui_i][ui_l], V[ui_i][ui_l], tmp1); /* Vi=Vi-q*Vj */ + mpz_mul (tmp1, q, U[ui_i][ui_l]); + mpz_add (U[ui_j][ui_l], U[ui_j][ui_l], tmp1); /* Uj=Uj+q*Ui */ + } + + vz_dot (tmp1, U[ui_j], U[ui_j], ui_t + 1); /* tmp1=dot(Uj,Uj) */ + if (mpz_cmp (tmp1, s) < 0) /* s = min(s,dot(Uj,Uj)) */ + mpz_set (s, tmp1); + ui_k = ui_j; + } + else if (g_debug > DEBUG_2) + printf (", #"); /* 2|Vi.Vj| <= Vj.Vj */ + } + else if (g_debug > DEBUG_2) + printf (", *"); /* i == j */ + } + + if (g_debug > DEBUG_2) + printf (")\n"); + + /* S6 [Advance j.] */ + if (ui_j == ui_t) + ui_j = 0; + else + ui_j++; + } + while (ui_j != ui_k); /* S5 */ + + /* From Knuth p. 104: "The exhaustive search in steps S8-S10 + reduces the value of s only rarely." */ +#ifdef DO_SEARCH + /* S7 [Prepare for search.] */ + /* Find minimum in (x[1], ..., x[t]) satisfying condition + x[k]^2 <= f(y[1], ...,y[t]) * dot(V[k],V[k]) */ + + ui_k = ui_t; + if (g_debug > DEBUG_2) + { + printf ("searching..."); + /*for (f = 0; f < ui_t*/ + fflush (stdout); + } + + /* Z[i] = floor (sqrt (floor (dot(V[i],V[i]) * s / m^2))); */ + mpz_pow_ui (tmp1, m, 2); + mpf_set_z (f_tmp1, tmp1); + mpf_set_z (f_tmp2, s); + mpf_div (f_tmp1, f_tmp2, f_tmp1); /* f_tmp1 = s/m^2 */ + for (ui_i = 0; ui_i <= ui_t; ui_i++) + { + vz_dot (tmp1, V[ui_i], V[ui_i], ui_t + 1); + mpf_set_z (f_tmp2, tmp1); + mpf_mul (f_tmp2, f_tmp2, f_tmp1); + f_floor (f_tmp2, f_tmp2); + mpf_sqrt (f_tmp2, f_tmp2); + mpz_set_f (Z[ui_i], f_tmp2); + } + + /* S8 [Advance X[k].] */ + do + { + if (g_debug > DEBUG_2) + { + printf ("X[%u] = ", ui_k); + mpz_out_str (stdout, 10, X[ui_k]); + printf ("\tZ[%u] = ", ui_k); + mpz_out_str (stdout, 10, Z[ui_k]); + printf ("\n"); + fflush (stdout); + } + + if (mpz_cmp (X[ui_k], Z[ui_k])) + { + mpz_add_ui (X[ui_k], X[ui_k], 1); + for (ui_i = 0; ui_i <= ui_t; ui_i++) + mpz_add (Y[ui_i], Y[ui_i], U[ui_k][ui_i]); + + /* S9 [Advance k.] */ + while (++ui_k <= ui_t) + { + mpz_neg (X[ui_k], Z[ui_k]); + mpz_mul_ui (tmp1, Z[ui_k], 2); + for (ui_i = 0; ui_i <= ui_t; ui_i++) + { + mpz_mul (tmp2, tmp1, U[ui_k][ui_i]); + mpz_sub (Y[ui_i], Y[ui_i], tmp2); + } + } + vz_dot (tmp1, Y, Y, ui_t + 1); + if (mpz_cmp (tmp1, s) < 0) + mpz_set (s, tmp1); + } + } + while (--ui_k); +#endif /* DO_SEARCH */ + mpf_set_z (f_tmp1, s); + mpf_sqrt (rop[ui_t - 1], f_tmp1); +#ifdef DO_SEARCH + if (g_debug > DEBUG_2) + printf ("done.\n"); +#endif /* DO_SEARCH */ + } /* S4 loop */ + + /* Clear GMP variables. */ + + mpf_clear (f_tmp1); + mpf_clear (f_tmp2); + for (ui_i = 0; ui_i < GMP_SPECT_MAXT; ui_i++) + { + for (ui_j = 0; ui_j < GMP_SPECT_MAXT; ui_j++) + { + mpz_clear (U[ui_i][ui_j]); + mpz_clear (V[ui_i][ui_j]); + } + mpz_clear (X[ui_i]); + mpz_clear (Y[ui_i]); + mpz_clear (Z[ui_i]); + } + mpz_clear (tmp1); + mpz_clear (tmp2); + mpz_clear (tmp3); + mpz_clear (h); + mpz_clear (hp); + mpz_clear (r); + mpz_clear (s); + mpz_clear (p); + mpz_clear (pp); + mpz_clear (q); + mpz_clear (u); + mpz_clear (v); + + return; +} diff --git a/gmp/tests/rand/t-iset.c b/gmp/tests/rand/t-iset.c new file mode 100644 index 0000000000..0414037c19 --- /dev/null +++ b/gmp/tests/rand/t-iset.c @@ -0,0 +1,68 @@ +/* Test gmp_randinit_set. + +Copyright 2003 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +#include <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "gmp-impl.h" +#include "tests.h" + +/* expect after a gmp_randinit_set that the new and old generators will + produce the same sequence of numbers */ +void +check_one (const char *name, gmp_randstate_ptr src) +{ + gmp_randstate_t dst; + mpz_t sz, dz; + int i; + + gmp_randinit_set (dst, src); + mpz_init (sz); + mpz_init (dz); + + for (i = 0; i < 20; i++) + { + mpz_urandomb (sz, src, 123); + mpz_urandomb (dz, dst, 123); + + if (mpz_cmp (sz, dz) != 0) + { + printf ("gmp_randinit_set didn't duplicate randstate\n"); + printf (" algorithm: %s\n", name); + gmp_printf (" from src: %#Zx\n", sz); + gmp_printf (" from dst: %#Zx\n", dz); + abort (); + } + } + + mpz_clear (sz); + mpz_clear (dz); + gmp_randclear (dst); +} + +int +main (int argc, char *argv[]) +{ + tests_start (); + + call_rand_algs (check_one); + + tests_end (); + exit (0); +} diff --git a/gmp/tests/rand/t-lc2exp.c b/gmp/tests/rand/t-lc2exp.c new file mode 100644 index 0000000000..b524441f29 --- /dev/null +++ b/gmp/tests/rand/t-lc2exp.c @@ -0,0 +1,217 @@ +/* Exercise the lc2exp random functions. + +Copyright 2002, 2011 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +#include <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "gmp-impl.h" +#include "tests.h" + + +/* a=0 and c=0 produces zero results always. */ +void +check_zero (unsigned long m2exp) +{ + gmp_randstate_t r; + mpz_t a; + unsigned long c; + int i; + + mpz_init_set_ui (a, 0L); + c = 0L; + + gmp_randinit_lc_2exp (r, a, c, m2exp); + gmp_randseed_ui (r, 0L); + + for (i = 0; i < 5; i++) + { + mpz_urandomb (a, r, 123L); + if (mpz_sgn (a) != 0) + { + printf ("check_zero m2exp=%lu: didn't get zero\n", m2exp); + gmp_printf (" rand=%#Zx\n", a); + abort (); + } + } + + mpz_clear (a); + gmp_randclear (r); +} + +/* negative a */ +void +check_nega (void) +{ + gmp_randstate_t r; + mpz_t a; + unsigned long c, m2exp; + int i; + + mpz_init (a); + mpz_setbit (a, 1000L); + mpz_neg (a, a); + c = 0L; + m2exp = 45L; + + gmp_randinit_lc_2exp (r, a, c, m2exp); + gmp_randseed_ui (r, 0L); + + for (i = 0; i < 5; i++) + { + mpz_urandomb (a, r, 123L); + if (mpz_sgn (a) != 0) + printf ("check_nega m2exp=%lu: didn't get zero\n", m2exp); + } + + mpz_clear (a); + gmp_randclear (r); +} + +void +check_bigc (void) +{ + gmp_randstate_t r; + mpz_t a; + unsigned long c, m2exp, bits; + int i; + + mpz_init_set_ui (a, 0L); + c = ULONG_MAX; + m2exp = 8; + + gmp_randinit_lc_2exp (r, a, c, m2exp); + gmp_randseed_ui (r, 0L); + + for (i = 0; i < 20; i++) + { + bits = 123L; + mpz_urandomb (a, r, bits); + if (mpz_sgn (a) < 0 || mpz_sizeinbase (a, 2) > bits) + { + printf ("check_bigc: mpz_urandomb out of range\n"); + printf (" m2exp=%lu\n", m2exp); + gmp_printf (" rand=%#ZX\n", a); + gmp_printf (" sizeinbase2=%u\n", mpz_sizeinbase (a, 2)); + abort (); + } + } + + mpz_clear (a); + gmp_randclear (r); +} + +void +check_bigc1 (void) +{ + gmp_randstate_t r; + mpz_t a; + unsigned long c, m2exp; + int i; + + mpz_init_set_ui (a, 0L); + c = ULONG_MAX; + m2exp = 2; + + gmp_randinit_lc_2exp (r, a, c, m2exp); + gmp_randseed_ui (r, 0L); + + for (i = 0; i < 20; i++) + { + mpz_urandomb (a, r, 1L); + if (mpz_cmp_ui (a, 1L) != 0) + { + printf ("check_bigc1: mpz_urandomb didn't give 1\n"); + printf (" m2exp=%lu\n", m2exp); + gmp_printf (" got rand=%#ZX\n", a); + abort (); + } + } + + mpz_clear (a); + gmp_randclear (r); +} + +/* Checks parameters which triggered an assertion failure in the past. + Happened when limbs(a)+limbs(c) < bits_to_limbs(m2exp). */ +void +check_bigm (void) +{ + gmp_randstate_t rstate; + mpz_t a; + + mpz_init_set_ui (a, 5L); + gmp_randinit_lc_2exp (rstate, a, 1L, 384L); + + mpz_urandomb (a, rstate, 20L); + + gmp_randclear (rstate); + mpz_clear (a); +} + +/* Checks for seeds bigger than the modulus. */ +void +check_bigs (void) +{ + gmp_randstate_t rstate; + mpz_t sd, a; + int i; + + mpz_init (sd); + mpz_setbit (sd, 300L); + mpz_sub_ui (sd, sd, 1L); + mpz_clrbit (sd, 13L); + mpz_init_set_ui (a, 123456789L); + + gmp_randinit_lc_2exp (rstate, a, 5L, 64L); + + for (i = 0; i < 20; i++) + { + mpz_neg (sd, sd); + gmp_randseed (rstate, sd); + mpz_mul_ui (sd, sd, 7L); + + mpz_urandomb (a, rstate, 80L); + } + + gmp_randclear (rstate); + mpz_clear (a); + mpz_clear (sd); +} + +int +main (void) +{ + tests_start (); + + check_zero (2L); + check_zero (7L); + check_zero (32L); + check_zero (64L); + check_zero (1000L); + + check_nega (); + check_bigc (); + check_bigc1 (); + + check_bigm (); + check_bigs (); + + tests_end (); + exit (0); +} diff --git a/gmp/tests/rand/t-mt.c b/gmp/tests/rand/t-mt.c new file mode 100644 index 0000000000..3aabffe88d --- /dev/null +++ b/gmp/tests/rand/t-mt.c @@ -0,0 +1,83 @@ +/* Test the Mersenne Twister random number generator. + +Copyright 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +#include <stdio.h> +#include "gmp.h" +#include "gmp-impl.h" +#include "tests.h" + +#ifndef TRUE +#define TRUE (1) +#endif +#ifndef FALSE +#define FALSE (0) +#endif + +/* Test that the sequence without seeding equals the sequence with the + default seed. */ +int +chk_default_seed (void) +{ + gmp_randstate_t r1, r2; + mpz_t a, b; + int i; + int ok = TRUE; + + mpz_init2 (a, 19936L); + mpz_init2 (b, 19936L); + + gmp_randinit_mt (r1); + gmp_randinit_mt (r2); + gmp_randseed_ui (r2, 5489L); /* Must match DEFAULT_SEED in randmt.c */ + for (i = 0; i < 3; i++) + { + /* Extract one whole buffer per iteration. */ + mpz_urandomb (a, r1, 19936L); + mpz_urandomb (b, r2, 19936L); + if (mpz_cmp (a, b) != 0) + { + ok = FALSE; + printf ("Default seed fails in iteration %d\n", i); + break; + } + } + gmp_randclear (r1); + gmp_randclear (r2); + + mpz_clear (a); + mpz_clear (b); + return ok; +} + +int +main (int argc, char *argv[]) +{ + int ok; + + tests_start (); + + ok = chk_default_seed (); + + tests_end (); + + if (ok) + return 0; /* pass */ + else + return 1; /* fail */ +} diff --git a/gmp/tests/rand/t-rand.c b/gmp/tests/rand/t-rand.c new file mode 100644 index 0000000000..1265a0d0a5 --- /dev/null +++ b/gmp/tests/rand/t-rand.c @@ -0,0 +1,290 @@ +/* t-rand -- Test random number generators. */ + +/* +Copyright 2000, 2001 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +#include <stdlib.h> +#include <stdio.h> +#include "gmp.h" + +#define SEED 1 +#define BASE 16 +#define ENTS 10 /* Number of entries in array when + printing. */ + +/* These were generated by this very program. Do not edit! */ +/* Integers. */ +const char *z1[ENTS] = {"0", "1", "1", "1", "1", "0", "1", "1", "1", "1"}; +const char *z2[ENTS] = {"0", "3", "1", "3", "3", "0", "3", "3", "3", "1"}; +const char *z3[ENTS] = {"4", "3", "1", "7", "3", "0", "3", "3", "3", "1"}; +const char *z4[ENTS] = {"c", "3", "1", "f", "b", "8", "3", "3", "3", "1"}; +const char *z5[ENTS] = {"1c", "13", "11", "1f", "b", "18", "3", "13", "3", "1"}; + +const char *z10[ENTS] = {"29c", "213", "f1", "17f", "12b", "178", "383", "d3", "3a3", "281"}; + +const char *z15[ENTS] = {"29c", "1a13", "74f1", "257f", "592b", "4978", "4783", "7cd3", "5ba3", "4681"}; +const char *z16[ENTS] = {"29c", "9a13", "74f1", "a57f", "d92b", "4978", "c783", "fcd3", "5ba3", "c681"}; +const char *z17[ENTS] = {"51e", "f17a", "54ff", "1a335", "cf65", "5d6f", "583f", "618f", "1bc6", "98ff"}; + +const char *z31[ENTS] = {"3aecd515", "13ae8ec6", "518c8090", "81ca077", "70b7134", "7ee78d71", "323a7636", "2122cb1a", "19811941", "41fd605"}; +const char *z32[ENTS] = {"baecd515", "13ae8ec6", "518c8090", "881ca077", "870b7134", "7ee78d71", "323a7636", "a122cb1a", "99811941", "841fd605"}; +const char *z33[ENTS] = {"1faf4cca", "15d6ef83b", "9095fe72", "1b6a3dff6", "b17cbddd", "16e5209d4", "6f65b12c", "493bbbc6", "abf2a5d5", "6d491a3c"}; + +const char *z63[ENTS] = {"48a74f367fa7b5c8", "3ba9e9dc1b263076", "1e0ac84e7678e0fb", "11416581728b3e35", "36ab610523f0f1f7", "3e540e8e95c0eb4b", "439ae16057dbc9d3", "734fb260db243950", "7d3a317effc289bf", "1d80301fb3d1a0d1"}; +const char *z64[ENTS] = {"48a74f367fa7b5c8", "bba9e9dc1b263076", "9e0ac84e7678e0fb", "11416581728b3e35", "b6ab610523f0f1f7", "be540e8e95c0eb4b", "439ae16057dbc9d3", "f34fb260db243950", "fd3a317effc289bf", "1d80301fb3d1a0d1"}; +const char *z65[ENTS] = {"1ff77710d846d49f0", "1b1411701d709ee10", "31ffa81a208b6af4", "446638d431d3c681", "df5c569d5baa8b55", "197d99ea9bf28e5a0", "191ade09edd94cfae", "194acefa6dde5e18d", "1afc1167c56272d92", "d092994da72f206f"}; + +const char *z127[ENTS] = {"2f66ba932aaf58a071fd8f0742a99a0c", "73cfa3c664c9c1753507ca60ec6b8425", "53ea074ca131dec12cd68b8aa8e20278", "3cf5ac8c343532f8a53cc0eb47581f73", "50c11d5869e208aa1b9aa317b8c2d0a9", "b23163c892876472b1ef19642eace09", "489f4c03d41f87509c8d6c90ce674f95", "2ab8748c96aa6762ea1932b44c9d7164", "98cb5591fc05ad31afbbc1d67b90edd", "77848bb991fd0be331adcf1457fbc672"}; +const char *z128[ENTS] = {"af66ba932aaf58a071fd8f0742a99a0c", "73cfa3c664c9c1753507ca60ec6b8425", "53ea074ca131dec12cd68b8aa8e20278", "3cf5ac8c343532f8a53cc0eb47581f73", "50c11d5869e208aa1b9aa317b8c2d0a9", "8b23163c892876472b1ef19642eace09", "489f4c03d41f87509c8d6c90ce674f95", "aab8748c96aa6762ea1932b44c9d7164", "98cb5591fc05ad31afbbc1d67b90edd", "f7848bb991fd0be331adcf1457fbc672"}; + +/* Floats. */ +const char *f1[ENTS] = {"0.@0", "0.8@0", "0.8@0", "0.8@0", "0.8@0", "0.@0", "0.8@0", "0.8@0", "0.8@0", "0.8@0"}; +const char *f2[ENTS] = {"0.@0", "0.c@0", "0.4@0", "0.c@0", "0.c@0", "0.@0", "0.c@0", "0.c@0", "0.c@0", "0.4@0"}; +const char *f3[ENTS] = {"0.8@0", "0.6@0", "0.2@0", "0.e@0", "0.6@0", "0.@0", "0.6@0", "0.6@0", "0.6@0", "0.2@0"}; +const char *f4[ENTS] = {"0.c@0", "0.3@0", "0.1@0", "0.f@0", "0.b@0", "0.8@0", "0.3@0", "0.3@0", "0.3@0", "0.1@0"}; +const char *f5[ENTS] = {"0.e@0", "0.98@0", "0.88@0", "0.f8@0", "0.58@0", "0.c@0", "0.18@0", "0.98@0", "0.18@0", "0.8@-1"}; + +const char *f10[ENTS] = {"0.a7@0", "0.84c@0", "0.3c4@0", "0.5fc@0", "0.4ac@0", "0.5e@0", "0.e0c@0", "0.34c@0", "0.e8c@0", "0.a04@0"}; + +const char *f15[ENTS] = {"0.538@-1", "0.3426@0", "0.e9e2@0", "0.4afe@0", "0.b256@0", "0.92f@0", "0.8f06@0", "0.f9a6@0", "0.b746@0", "0.8d02@0"}; +const char *f16[ENTS] = {"0.29c@-1", "0.9a13@0", "0.74f1@0", "0.a57f@0", "0.d92b@0", "0.4978@0", "0.c783@0", "0.fcd3@0", "0.5ba3@0", "0.c681@0"}; +const char *f17[ENTS] = {"0.28f@-1", "0.78bd@0", "0.2a7f8@0", "0.d19a8@0", "0.67b28@0", "0.2eb78@0", "0.2c1f8@0", "0.30c78@0", "0.de3@-1", "0.4c7f8@0"}; + +const char *f31[ENTS] = {"0.75d9aa2a@0", "0.275d1d8c@0", "0.a319012@0", "0.103940ee@0", "0.e16e268@-1", "0.fdcf1ae2@0", "0.6474ec6c@0", "0.42459634@0", "0.33023282@0", "0.83fac0a@-1"}; +const char *f32[ENTS] = {"0.baecd515@0", "0.13ae8ec6@0", "0.518c809@0", "0.881ca077@0", "0.870b7134@0", "0.7ee78d71@0", "0.323a7636@0", "0.a122cb1a@0", "0.99811941@0", "0.841fd605@0"}; +const char *f33[ENTS] = {"0.fd7a665@-1", "0.aeb77c1d8@0", "0.484aff39@0", "0.db51effb@0", "0.58be5eee8@0", "0.b72904ea@0", "0.37b2d896@0", "0.249ddde3@0", "0.55f952ea8@0", "0.36a48d1e@0"}; + +const char *f63[ENTS] = {"0.914e9e6cff4f6b9@0", "0.7753d3b8364c60ec@0", "0.3c15909cecf1c1f6@0", "0.2282cb02e5167c6a@0", "0.6d56c20a47e1e3ee@0", "0.7ca81d1d2b81d696@0", "0.8735c2c0afb793a6@0", "0.e69f64c1b64872a@0", "0.fa7462fdff85137e@0", "0.3b00603f67a341a2@0"}; +const char *f64[ENTS] = {"0.48a74f367fa7b5c8@0", "0.bba9e9dc1b263076@0", "0.9e0ac84e7678e0fb@0", "0.11416581728b3e35@0", "0.b6ab610523f0f1f7@0", "0.be540e8e95c0eb4b@0", "0.439ae16057dbc9d3@0", "0.f34fb260db24395@0", "0.fd3a317effc289bf@0", "0.1d80301fb3d1a0d1@0"}; +const char *f65[ENTS] = {"0.ffbbb886c236a4f8@0", "0.d8a08b80eb84f708@0", "0.18ffd40d1045b57a@0", "0.22331c6a18e9e3408@0", "0.6fae2b4eadd545aa8@0", "0.cbeccf54df9472d@0", "0.c8d6f04f6eca67d7@0", "0.ca5677d36ef2f0c68@0", "0.d7e08b3e2b1396c9@0", "0.68494ca6d39790378@0"}; + +const char *f127[ENTS] = {"0.5ecd7526555eb140e3fb1e0e85533418@0", "0.e79f478cc99382ea6a0f94c1d8d7084a@0", "0.a7d40e994263bd8259ad171551c404f@0", "0.79eb5918686a65f14a7981d68eb03ee6@0", "0.a1823ab0d3c411543735462f7185a152@0", "0.16462c791250ec8e563de32c85d59c12@0", "0.913e9807a83f0ea1391ad9219cce9f2a@0", "0.5570e9192d54cec5d4326568993ae2c8@0", "0.13196ab23f80b5a635f7783acf721dba@0", "0.ef09177323fa17c6635b9e28aff78ce4@0"}; +const char *f128[ENTS] = {"0.af66ba932aaf58a071fd8f0742a99a0c@0", "0.73cfa3c664c9c1753507ca60ec6b8425@0", "0.53ea074ca131dec12cd68b8aa8e20278@0", "0.3cf5ac8c343532f8a53cc0eb47581f73@0", "0.50c11d5869e208aa1b9aa317b8c2d0a9@0", "0.8b23163c892876472b1ef19642eace09@0", "0.489f4c03d41f87509c8d6c90ce674f95@0", "0.aab8748c96aa6762ea1932b44c9d7164@0", "0.98cb5591fc05ad31afbbc1d67b90edd@-1", "0.f7848bb991fd0be331adcf1457fbc672@0"}; + + +struct rt +{ + const char **s; + int nbits; +}; + +static struct rt zarr[] = +{ + {z1, 1}, + {z2, 2}, + {z3, 3}, + {z4, 4}, + {z5, 5}, + {z10, 10}, + {z15, 15}, + {z16, 16}, + {z17, 17}, + {z31, 31}, + {z32, 32}, + {z33, 33}, + {z63, 63}, + {z64, 64}, + {z65, 65}, + {z127, 127}, + {z128, 128}, + {NULL, 0} +}; + +static struct rt farr[] = +{ + {f1, 1}, + {f2, 2}, + {f3, 3}, + {f4, 4}, + {f5, 5}, + {f10, 10}, + {f15, 15}, + {f16, 16}, + {f17, 17}, + {f31, 31}, + {f32, 32}, + {f33, 33}, + {f63, 63}, + {f64, 64}, + {f65, 65}, + {f127, 127}, + {f128, 128}, + {NULL, 0} +}; + + +int +main (int argc, char *argv[]) +{ + static char usage[] = "\ +usage: t-rand [function nbits]\n\ + function is one of z, f\n\ + nbits is number of bits\n\ +"; + gmp_randstate_t rstate; + mpz_t z, rz; + mpf_t f, rf; + enum { Z, F } func = Z; + int nbits = 1; + int verify_mode_flag = 1; + int i; + struct rt *a; + + + if (argc > 1) + { + if (argc < 3) + { + fputs (usage, stderr); + exit (1); + } + verify_mode_flag = 0; + if (*argv[1] == 'z') + func = Z; + if (*argv[1] == 'f') + func = F; + nbits = atoi (argv[2]); + } + + mpz_init (rz); + + if (verify_mode_flag) + { +#ifdef VERBOSE + printf ("%s: verifying random numbers: ", argv[0]); +#endif + + /* Test z. */ + mpz_init (z); + for (a = zarr; a->s != NULL; a++) + { + gmp_randinit (rstate, GMP_RAND_ALG_LC, a->nbits); + if (gmp_errno != GMP_ERROR_NONE) + exit (1); + gmp_randseed_ui (rstate, SEED); + + for (i = 0; i < ENTS; i++) + { + mpz_urandomb (rz, rstate, a->nbits); + mpz_set_str (z, a->s[i], BASE); + if (mpz_cmp (z, rz) != 0) + { + printf ("z%d: ", a->nbits); + mpz_out_str (stdout, BASE, rz); + printf (" should be "); + mpz_out_str (stdout, BASE, z); + puts (""); + exit (1); + } + } +#ifdef VERBOSE + printf ("z%d ", a->nbits); +#endif + gmp_randclear (rstate); + } + mpz_clear (z); + + + /* Test f. */ + for (a = farr; a->s != NULL; a++) + { + gmp_randinit (rstate, GMP_RAND_ALG_LC, a->nbits); + if (gmp_errno != GMP_ERROR_NONE) + exit (1); + gmp_randseed_ui (rstate, SEED); + + mpf_init2 (f, a->nbits); + mpf_init2 (rf, a->nbits); + for (i = 0; i < ENTS; i++) + { + mpf_urandomb (rf, rstate, a->nbits); + mpf_set_str (f, a->s[i], BASE); + if (mpf_cmp (f, rf) != 0) + { + printf ("f%d: ", a->nbits); + mpf_out_str (stdout, BASE, a->nbits, rf); + printf (" should be "); + mpf_out_str (stdout, BASE, a->nbits, f); + puts (""); + exit (1); + } + } +#ifdef VERBOSE + printf ("f%d ", a->nbits); +#endif + gmp_randclear (rstate); + mpf_clear (f); + mpf_clear (rf); + } + +#ifdef VERBOSE + puts (""); +#endif + } + else /* Print mode. */ + { + gmp_randinit (rstate, GMP_RAND_ALG_LC, nbits); + if (gmp_errno != GMP_ERROR_NONE) + exit (1); + gmp_randseed_ui (rstate, SEED); + + switch (func) + { + case Z: + printf ("char *z%d[ENTS] = {", nbits); + for (i = 0; i < ENTS; i++) + { + mpz_urandomb (rz, rstate, nbits); + printf ("\""); + mpz_out_str (stdout, BASE, rz); + printf ("\""); + if (i != ENTS - 1) + printf (", "); + } + printf ("};\n"); + printf (" {z%d, %d},\n", nbits, nbits); + break; + + case F: + printf ("char *f%d[ENTS] = {", nbits); + mpf_init2 (rf, nbits); + for (i = 0; i < ENTS; i++) + { + mpf_urandomb (rf, rstate, nbits); + printf ("\""); + mpf_out_str (stdout, BASE, nbits, rf); + printf ("\""); + if (i != ENTS - 1) + printf (", "); + } + printf ("};\n"); + printf (" {f%d, %d},\n", nbits, nbits); + mpf_clear (rf); + break; + + default: + exit (1); + } + + gmp_randclear (rstate); + } + + mpz_clear (rz); + + return 0; +} diff --git a/gmp/tests/rand/t-urbui.c b/gmp/tests/rand/t-urbui.c new file mode 100644 index 0000000000..bac8b6d5a0 --- /dev/null +++ b/gmp/tests/rand/t-urbui.c @@ -0,0 +1,65 @@ +/* Test gmp_urandomb_ui. + +Copyright 2003, 2005 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +#include <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "gmp-impl.h" +#include "tests.h" + +/* Expect numbers generated by rstate to obey the number of bits requested. + No point testing bits==BITS_PER_ULONG, since any return is acceptable in + that case. */ +void +check_one (const char *name, gmp_randstate_ptr rstate) +{ + unsigned long bits, limit, got; + int i; + + for (bits = 0; bits < BITS_PER_ULONG; bits++) + { + /* will demand got < limit */ + limit = (1UL << bits); + + for (i = 0; i < 5; i++) + { + got = gmp_urandomb_ui (rstate, bits); + if (got >= limit) + { + printf ("Return value out of range:\n"); + printf (" algorithm: %s\n", name); + printf (" bits: %lu\n", bits); + printf (" limit: %#lx\n", limit); + printf (" got: %#lx\n", got); + abort (); + } + } + } +} + +int +main (int argc, char *argv[]) +{ + tests_start (); + + call_rand_algs (check_one); + + tests_end (); + exit (0); +} diff --git a/gmp/tests/rand/t-urmui.c b/gmp/tests/rand/t-urmui.c new file mode 100644 index 0000000000..c58d740f4e --- /dev/null +++ b/gmp/tests/rand/t-urmui.c @@ -0,0 +1,75 @@ +/* Test gmp_urandomm_ui. + +Copyright 2003, 2005 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +#include <stdio.h> +#include <stdlib.h> +#include "gmp.h" +#include "gmp-impl.h" +#include "tests.h" + +/* Expect numbers generated by rstate to obey the limit requested. */ +void +check_one (const char *name, gmp_randstate_ptr rstate) +{ + static const unsigned long n_table[] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 123, 456, 789, + + 255, 256, 257, + 1023, 1024, 1025, + 32767, 32768, 32769, + + ULONG_MAX/2-2, ULONG_MAX/2-1, ULONG_MAX/2, ULONG_MAX/2+1, ULONG_MAX/2+2, + + ULONG_MAX-2, ULONG_MAX-1, ULONG_MAX, + }; + + unsigned long got, n; + int i, j; + + for (i = 0; i < numberof (n_table); i++) + { + n = n_table[i]; + + for (j = 0; j < 5; j++) + { + got = gmp_urandomm_ui (rstate, n); + if (got >= n) + { + printf ("Return value out of range:\n"); + printf (" algorithm: %s\n", name); + printf (" n: %#lx\n", n); + printf (" got: %#lx\n", got); + abort (); + } + } + } +} + + +int +main (int argc, char *argv[]) +{ + tests_start (); + + call_rand_algs (check_one); + + tests_end (); + exit (0); +} diff --git a/gmp/tests/rand/t-urndmm.c b/gmp/tests/rand/t-urndmm.c new file mode 100644 index 0000000000..d5a9217b40 --- /dev/null +++ b/gmp/tests/rand/t-urndmm.c @@ -0,0 +1,159 @@ +/* Test mpz_urandomm. + +Copyright 2002 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +#include <stdio.h> +#include "gmp.h" +#include "gmp-impl.h" +#include "tests.h" + +#ifndef TRUE +#define TRUE (1) +#endif +#ifndef FALSE +#define FALSE (0) +#endif + +int +check_params (void) +{ + gmp_randstate_t r1, r2; + mpz_t a, b, m; + int i; + int result; + + result = TRUE; + + mpz_init (a); + mpz_init (b); + mpz_init (m); + + if (result) + { + /* Test the consistency between urandomm and urandomb. */ + gmp_randinit_default (r1); + gmp_randinit_default (r2); + gmp_randseed_ui (r1, 85L); + gmp_randseed_ui (r2, 85L); + mpz_set_ui (m, 0L); + mpz_setbit (m, 80L); + for (i = 0; i < 100; i++) + { + mpz_urandomm (a, r1, m); + mpz_urandomb (b, r2, 80L); + if (mpz_cmp (a, b) != 0) + { + result = FALSE; + printf ("mpz_urandomm != mpz_urandomb\n"); + break; + } + } + gmp_randclear (r1); + gmp_randclear (r2); + } + + if (result) + { + /* Test that mpz_urandomm returns the correct result with a + broken LC. */ + mpz_set_ui (a, 0L); + gmp_randinit_lc_2exp (r1, a, 0xffL, 8L); + mpz_set_ui (m, 5L); + /* Warning: This code hangs in gmp 4.1 and below */ + for (i = 0; i < 100; i++) + { + mpz_urandomm (a, r1, m); + if (mpz_cmp_ui (a, 2L) != 0) + { + result = FALSE; + gmp_printf ("mpz_urandomm returns %Zd instead of 2\n", a); + break; + } + } + gmp_randclear (r1); + } + + if (result) + { + /* Test that the results are always in range for either + positive or negative values of m. */ + gmp_randinit_default (r1); + mpz_set_ui (m, 5L); + mpz_set_si (b, -5L); + for (i = 0; i < 100; i++) + { + mpz_urandomm (a, r1, m); + if (mpz_cmp_ui (a, 5L) >= 0 || mpz_sgn (a) < 0) + { + result = FALSE; + gmp_printf ("Out-of-range or non-positive value: %Zd\n", a); + break; + } + mpz_urandomm (a, r1, b); + if (mpz_cmp_ui (a, 5L) >= 0 || mpz_sgn (a) < 0) + { + result = FALSE; + gmp_printf ("Out-of-range or non-positive value (from negative modulus): %Zd\n", a); + break; + } + } + gmp_randclear (r1); + } + + if (result) + { + /* Test that m=1 forces always result=0. */ + gmp_randinit_default (r1); + mpz_set_ui (m, 1L); + for (i = 0; i < 100; i++) + { + mpz_urandomm (a, r1, m); + if (mpz_sgn (a) != 0) + { + result = FALSE; + gmp_printf ("mpz_urandomm fails with m=1 (result=%Zd)\n", a); + break; + } + } + gmp_randclear (r1); + } + + mpz_clear (a); + mpz_clear (b); + mpz_clear (m); + return result; +} + +int +main (int argc, char *argv[]) +{ + int result = TRUE; + + tests_start (); + + if (result) + if (!check_params ()) + result = FALSE; + + tests_end (); + + if (result) + return 0; /* pass */ + else + return 1; /* fail */ +} diff --git a/gmp/tests/rand/zdiv_round.c b/gmp/tests/rand/zdiv_round.c new file mode 100644 index 0000000000..3a91e3092c --- /dev/null +++ b/gmp/tests/rand/zdiv_round.c @@ -0,0 +1,44 @@ +/* zdiv_round() -- divide integers, round to nearest */ + +/* +Copyright 1999 Free Software Foundation, Inc. + +This file is part of the GNU MP Library test suite. + +The GNU MP Library test suite is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +The GNU MP Library test suite 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 General +Public License for more details. + +You should have received a copy of the GNU General Public License along with +the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ + +#include "gmp.h" + +void +zdiv_round (mpz_t rop, mpz_t n, mpz_t d) +{ + mpf_t f_n, f_d; + + mpf_init (f_n); + mpf_init (f_d); + + mpf_set_z (f_d, d); + mpf_set_z (f_n, n); + + mpf_div (f_n, f_n, f_d); + mpf_set_d (f_d, .5); + if (mpf_sgn (f_n) < 0) + mpf_neg (f_d, f_d); + mpf_add (f_n, f_n, f_d); + mpz_set_f (rop, f_n); + + mpf_clear (f_n); + mpf_clear (f_d); + return; +} |