From 595536faf3608c8ba49d213b3bf5ac53dce3881f Mon Sep 17 00:00:00 2001 From: thevenyp Date: Mon, 20 Jan 2014 18:19:00 +0000 Subject: New test framework, merged from test branch. git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@1416 211d60ee-9f03-0410-a15a-8952a2c7a4e4 --- Makefile.am | 2 +- Makefile.vc | 14 +- doc/version.texi | 9 +- tests/Makefile.am | 50 ++-- tests/README.dev | 185 ++++++++++++ tests/abs.dsc | 29 ++ tests/acos.dsc | 28 ++ tests/acosh.dsc | 28 ++ tests/add.dsc | 30 ++ tests/add_fr.dsc | 30 ++ tests/add_si.dsc | 31 ++ tests/add_ui.dsc | 31 ++ tests/arg.dsc | 28 ++ tests/asin.dsc | 28 ++ tests/asinh.dsc | 28 ++ tests/atan.dsc | 28 ++ tests/atanh.dsc | 28 ++ tests/check_data.c | 118 ++++++++ tests/clear_parameters.c | 82 ++++++ tests/close_datafile.c | 28 ++ tests/conj.dsc | 29 ++ tests/copy_parameter.c | 122 ++++++++ tests/cos.dsc | 28 ++ tests/cosh.dsc | 28 ++ tests/data_check.tpl | 93 ++++++ tests/div.dsc | 29 ++ tests/div_2si.dsc | 29 ++ tests/div_2ui.dsc | 29 ++ tests/div_fr.dsc | 29 ++ tests/div_ui.dsc | 29 ++ tests/double_rounding.c | 151 ++++++++++ tests/exp.dsc | 28 ++ tests/fma.dsc | 31 ++ tests/fr_div.dsc | 29 ++ tests/fr_sub.dsc | 29 ++ tests/imag.dsc | 29 ++ tests/init_parameters.c | 83 ++++++ tests/log.dsc | 28 ++ tests/log10.dsc | 28 ++ tests/mpc-tests.h | 323 ++++++++++++++------- tests/mpfr_flags.c | 115 ++++++++ tests/mul.dsc | 30 ++ tests/mul_2si.dsc | 29 ++ tests/mul_2ui.dsc | 29 ++ tests/mul_fr.dsc | 29 ++ tests/mul_i.dsc | 29 ++ tests/mul_si.dsc | 29 ++ tests/mul_ui.dsc | 29 ++ tests/neg.dsc | 28 ++ tests/norm.dsc | 29 ++ tests/open_datafile.c | 57 ++++ tests/pow.dsc | 30 ++ tests/pow_d.dsc | 30 ++ tests/pow_fr.dsc | 30 ++ tests/pow_si.dsc | 31 ++ tests/pow_ui.dsc | 31 ++ tests/pow_z.dat | 51 ++++ tests/pow_z.dsc | 30 ++ tests/print_parameter.c | 107 +++++++ tests/proj.dsc | 28 ++ tests/random.c | 111 +++++++ tests/read_data.c | 698 +-------------------------------------------- tests/read_description.c | 267 +++++++++++++++++ tests/read_line.c | 242 ++++++++++++++++ tests/real.dsc | 29 ++ tests/rounding.c | 131 +++++++++ tests/setprec_parameters.c | 66 +++++ tests/sin.dsc | 28 ++ tests/sin_cos.dsc | 30 ++ tests/sinh.dsc | 28 ++ tests/sqr.dsc | 29 ++ tests/sqrt.dsc | 29 ++ tests/sub.dsc | 30 ++ tests/sub_fr.dsc | 30 ++ tests/sub_ui.dsc | 31 ++ tests/tabs.c | 15 +- tests/tacos.c | 17 +- tests/tacosh.c | 17 +- tests/tadd.c | 23 +- tests/tadd_fr.c | 17 +- tests/tadd_si.c | 68 +++-- tests/tadd_ui.c | 14 +- tests/tan.dsc | 28 ++ tests/tanh.dsc | 28 ++ tests/targ.c | 15 +- tests/tasin.c | 17 +- tests/tasinh.c | 17 +- tests/tatan.c | 16 +- tests/tatanh.c | 17 +- tests/tconj.c | 17 +- tests/tcos.c | 19 +- tests/tcosh.c | 19 +- tests/tdiv.c | 20 +- tests/tdiv_2si.c | 13 +- tests/tdiv_2ui.c | 13 +- tests/tdiv_fr.c | 19 +- tests/tdiv_ui.c | 15 +- tests/texp.c | 17 +- tests/tfma.c | 26 +- tests/tfr_div.c | 17 +- tests/tfr_sub.c | 18 +- tests/tgeneric.tpl | 328 +++++++++++++++++++++ tests/timag.c | 11 +- tests/tio_str.c | 6 +- tests/tlog.c | 18 +- tests/tlog10.c | 18 +- tests/tmul.c | 22 +- tests/tmul_2si.c | 13 +- tests/tmul_2ui.c | 13 +- tests/tmul_fr.c | 17 +- tests/tmul_i.c | 15 +- tests/tmul_si.c | 12 +- tests/tmul_ui.c | 13 +- tests/tneg.c | 16 +- tests/tnorm.c | 16 +- tests/tpl_gmp.c | 53 ++++ tests/tpl_mpc.c | 65 +++++ tests/tpl_mpfr.c | 158 ++++++++++ tests/tpl_native.c | 127 +++++++++ tests/tpow.c | 18 +- tests/tpow_d.c | 25 +- tests/tpow_fr.c | 19 +- tests/tpow_si.c | 13 +- tests/tpow_ui.c | 14 +- tests/tpow_z.c | 75 ++--- tests/tproj.c | 17 +- tests/treal.c | 11 +- tests/tsin.c | 17 +- tests/tsin_cos.c | 263 ++++++++++++++++- tests/tsinh.c | 17 +- tests/tsqr.c | 16 +- tests/tsqrt.c | 17 +- tests/tstrtoc.c | 4 +- tests/tsub.c | 19 +- tests/tsub_fr.c | 17 +- tests/tsub_ui.c | 13 +- tests/ttan.c | 18 +- tests/ttanh.c | 17 +- tests/tui_div.c | 17 +- tests/tui_ui_sub.c | 13 +- tests/ui_div.dsc | 29 ++ tests/ui_ui_sub.dsc | 30 ++ 142 files changed, 5607 insertions(+), 1154 deletions(-) create mode 100644 tests/README.dev create mode 100644 tests/abs.dsc create mode 100644 tests/acos.dsc create mode 100644 tests/acosh.dsc create mode 100644 tests/add.dsc create mode 100644 tests/add_fr.dsc create mode 100644 tests/add_si.dsc create mode 100644 tests/add_ui.dsc create mode 100644 tests/arg.dsc create mode 100644 tests/asin.dsc create mode 100644 tests/asinh.dsc create mode 100644 tests/atan.dsc create mode 100644 tests/atanh.dsc create mode 100644 tests/check_data.c create mode 100644 tests/clear_parameters.c create mode 100644 tests/close_datafile.c create mode 100644 tests/conj.dsc create mode 100644 tests/copy_parameter.c create mode 100644 tests/cos.dsc create mode 100644 tests/cosh.dsc create mode 100644 tests/data_check.tpl create mode 100644 tests/div.dsc create mode 100644 tests/div_2si.dsc create mode 100644 tests/div_2ui.dsc create mode 100644 tests/div_fr.dsc create mode 100644 tests/div_ui.dsc create mode 100644 tests/double_rounding.c create mode 100644 tests/exp.dsc create mode 100644 tests/fma.dsc create mode 100644 tests/fr_div.dsc create mode 100644 tests/fr_sub.dsc create mode 100644 tests/imag.dsc create mode 100644 tests/init_parameters.c create mode 100644 tests/log.dsc create mode 100644 tests/log10.dsc create mode 100644 tests/mpfr_flags.c create mode 100644 tests/mul.dsc create mode 100644 tests/mul_2si.dsc create mode 100644 tests/mul_2ui.dsc create mode 100644 tests/mul_fr.dsc create mode 100644 tests/mul_i.dsc create mode 100644 tests/mul_si.dsc create mode 100644 tests/mul_ui.dsc create mode 100644 tests/neg.dsc create mode 100644 tests/norm.dsc create mode 100644 tests/open_datafile.c create mode 100644 tests/pow.dsc create mode 100644 tests/pow_d.dsc create mode 100644 tests/pow_fr.dsc create mode 100644 tests/pow_si.dsc create mode 100644 tests/pow_ui.dsc create mode 100644 tests/pow_z.dat create mode 100644 tests/pow_z.dsc create mode 100644 tests/print_parameter.c create mode 100644 tests/proj.dsc create mode 100644 tests/read_description.c create mode 100644 tests/read_line.c create mode 100644 tests/real.dsc create mode 100644 tests/rounding.c create mode 100644 tests/setprec_parameters.c create mode 100644 tests/sin.dsc create mode 100644 tests/sin_cos.dsc create mode 100644 tests/sinh.dsc create mode 100644 tests/sqr.dsc create mode 100644 tests/sqrt.dsc create mode 100644 tests/sub.dsc create mode 100644 tests/sub_fr.dsc create mode 100644 tests/sub_ui.dsc create mode 100644 tests/tan.dsc create mode 100644 tests/tanh.dsc create mode 100644 tests/tgeneric.tpl create mode 100644 tests/tpl_gmp.c create mode 100644 tests/tpl_mpc.c create mode 100644 tests/tpl_mpfr.c create mode 100644 tests/tpl_native.c create mode 100644 tests/ui_div.dsc create mode 100644 tests/ui_ui_sub.dsc diff --git a/Makefile.am b/Makefile.am index cf0b6cb..940bd64 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,4 +26,4 @@ SUBDIRS = src tests doc EXTRA_HEADERS = src/mpc-log.h include_HEADERS = src/mpc.h @MPC_LOG_H@ -EXTRA_DIST = doc/fdl-1.3.texi src/mpc-log.h tests/tgeneric.c Makefile.vc +EXTRA_DIST = doc/fdl-1.3.texi src/mpc-log.h Makefile.vc diff --git a/Makefile.vc b/Makefile.vc index 8f5226f..ee5a94c 100644 --- a/Makefile.vc +++ b/Makefile.vc @@ -1,6 +1,6 @@ # Makefile for the MPC library (Windows version). # -# Copyright (C) INRIA - CNRS, 2002, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012 +# Copyright (C) INRIA - CNRS, 2002, 2004, 2005, 2007, 2008, 2009, 2010, 2011, 2012, 2013 # # This file is part of the MPC Library. # @@ -83,9 +83,15 @@ INCLUDES = /I$(DIRMPC) /I$(GMPDIR)\include /I$(MPFR)\include CKERNELFLAGS = $(CDEFAULTFLAGS) $(GMPMUSTBEDLL) $(INCLUDES) CFLAGS = $(CKERNELFLAGS) /D__MPC_WITHIN_MPC /D_GMP_IEEE_FLOATS /DHAVE_CONFIG_H -TESTCOMPILE=$(CC) $(CKERNELFLAGS) $(DIRMPCTESTS)\tgeneric.c $(DIRMPCTESTS)\comparisons.c $(DIRMPCTESTS)\read_data.c $(DIRMPCTESTS)\random.c $(DIRMPCTESTS) +TESTSSOURCES=$(DIRMPCTESTS)\check_data.c $(DIRMPCTESTS)\clear_parameters.c \ + $(DIRMPCTESTS)\close_datafile.c $(DIRMPCTESTS)\comparisons.c $(DIRMPCTESTS)\copy_parameter.c $(DIRMPCTESTS)\double_rounding.c \ + $(DIRMPCTESTS)\init_parameters.c $(DIRMPCTESTS)\mpfr_flags.c $(DIRMPCTESTS)\open_datafile.c $(DIRMPCTESTS)\print_parameter.c \ + $(DIRMPCTESTS)\random.c $(DIRMPCTESTS)\read_data.c $(DIRMPCTESTS)\read_description.c $(DIRMPCTESTS)\read_line.c $(DIRMPCTESTS)\rounding.c \ + $(DIRMPCTESTS)\setprec_parameters.c $(DIRMPCTESTS)\tpl_gmp.c $(DIRMPCTESTS)\tpl_mpc.c $(DIRMPCTESTS)\tpl_mpfr.c $(DIRMPCTESTS)\tpl_native.c + +TESTCOMPILE=$(CC) $(CKERNELFLAGS) $(TESTSSOURCES) $(DIRMPCTESTS) MIDTESTCOMPILE=/link /out:$(DIRMPCTESTS) -ENDTESTCOMPILE=/LIBPATH:"$(GMPDIR)\lib" libmpc.lib libmpfr.lib libgmp.lib $(LIBS_LOGGING) +ENDTESTCOMPILE=/LIBPATH:"$(DIRMPCTESTS)" libmpc.lib /LIBPATH:"$(GMPDIR)\lib" libmpfr.lib libgmp.lib $(LIBS_LOGGING) #generate the CPPOBJECTS : goto src and execute @@ -355,6 +361,8 @@ test : cd $(DIRMPCTESTS) && tlog10.exe && cd .. $(TESTCOMPILE)tmul.c $(MIDTESTCOMPILE)tmul.exe $(ENDTESTCOMPILE) cd $(DIRMPCTESTS) && tmul.exe && cd .. + $(TESTCOMPILE)tmul_2si.c $(MIDTESTCOMPILE)tmul_2si.exe $(ENDTESTCOMPILE) + cd $(DIRMPCTESTS) && tmul_2si.exe && cd .. $(TESTCOMPILE)tmul_2ui.c $(MIDTESTCOMPILE)tmul_2ui.exe $(ENDTESTCOMPILE) cd $(DIRMPCTESTS) && tmul_2ui.exe && cd .. $(TESTCOMPILE)tmul_fr.c $(MIDTESTCOMPILE)tmul_fr.exe $(ENDTESTCOMPILE) diff --git a/doc/version.texi b/doc/version.texi index 7184426..67f9e76 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -1,4 +1,5 @@ -@set UPDATED 19 July 2012 -@set UPDATED-MONTH July 2012 -@set EDITION 1.0 -@set VERSION 1.0 +@set UPDATED 29 October 2012 +@set UPDATED-MONTH October 2012 +@set EDITION 1.1dev +@set VERSION 1.1dev + diff --git a/tests/Makefile.am b/tests/Makefile.am index df44e1d..61e5583 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,6 @@ ## tests/Makefile.am -- Process this file with automake to produce Makefile.in ## -## Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA +## Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 INRIA ## ## This file is part of GNU MPC. ## @@ -25,28 +25,42 @@ AM_LDFLAGS = -no-install # LOADLIBES (documented in the "GNU make" manual and equivalent to LDLIBS) # enables to compile a program foo.c in the test directory by simply doing # "make foo". -LOADLIBES=$(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) $(top_builddir)/tests/.libs/libmpc-tests.a $(top_builddir)/src/.libs/libmpc.a $(LIBS) +LOADLIBES=$(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) $(CFLAGS) \ + $(top_builddir)/tests/.libs/libmpc-tests.a \ + $(top_builddir)/src/.libs/libmpc.a $(LIBS) -check_PROGRAMS = tabs tacos tacosh tadd tadd_fr tadd_si tadd_ui targ tasin \ -tasinh tatan tatanh tconj tcos tcosh tdiv tdiv_2si tdiv_2ui tdiv_fr tdiv_ui \ -texp tfma tfr_div tfr_sub timag tio_str tlog tlog10 \ -tmul tmul_2si tmul_2ui tmul_fr tmul_i tmul_si tmul_ui \ -tneg tnorm tpow tpow_ld tpow_d tpow_fr tpow_si tpow_ui tpow_z \ -tprec tproj treal treimref tset tsin tsin_cos tsinh tsqr tsqrt tstrtoc tsub \ -tsub_fr tsub_ui tswap ttan ttanh tui_div tui_ui_sub tget_version +check_PROGRAMS = tabs tacos tacosh tadd tadd_fr tadd_si tadd_ui targ \ + tasin tasinh tatan tatanh tconj tcos tcosh tdiv tdiv_2si tdiv_2ui \ + tdiv_fr tdiv_ui texp tfma tfr_div tfr_sub timag tio_str tlog tlog10 \ + tmul tmul_2si tmul_2ui tmul_fr tmul_i tmul_si tmul_ui tneg tnorm tpow \ + tpow_d tpow_fr tpow_ld tpow_si tpow_ui tpow_z tprec tproj treal \ + treimref tset tsin tsin_cos tsinh tsqr tsqrt tstrtoc tsub tsub_fr \ + tsub_ui tswap ttan ttanh tui_div tui_ui_sub tget_version check_LTLIBRARIES=libmpc-tests.la -libmpc_tests_la_SOURCES=mpc-tests.h random.c tgeneric.c read_data.c \ -comparisons.c +libmpc_tests_la_SOURCES = mpc-tests.h check_data.c clear_parameters.c \ + close_datafile.c comparisons.c copy_parameter.c double_rounding.c \ + init_parameters.c mpfr_flags.c open_datafile.c print_parameter.c \ + random.c read_data.c read_description.c read_line.c rounding.c \ + setprec_parameters.c tpl_gmp.c tpl_mpc.c tpl_mpfr.c tpl_native.c -EXTRA_DIST = abs.dat acos.dat acosh.dat asin.dat asinh.dat atan.dat atanh.dat \ -add.dat add_fr.dat arg.dat conj.dat cos.dat cosh.dat div.dat div_fr.dat \ -exp.dat fma.dat fr_div.dat fr_sub.dat inp_str.dat log.dat log10.dat mul.dat \ -mul_fr.dat neg.dat norm.dat pow.dat pow_fr.dat pow_si.dat pow_ui.dat proj.dat \ -sin.dat sinh.dat sqr.dat sqrt.dat strtoc.dat sub.dat sub_fr.dat tan.dat \ -tanh.dat +DESCRIPTIONS = abs.dsc acos.dsc acosh.dsc add.dsc add_fr.dsc add_si.dsc \ + add_ui.dsc arg.dsc asin.dsc asinh.dsc atan.dsc atanh.dsc conj.dsc \ + cos.dsc cosh.dsc div.dsc div_2si.dsc div_2ui.dsc div_fr.dsc \ + div_ui.dsc exp.dsc fma.dsc fr_div.dsc fr_sub.dsc imag.dsc log.dsc \ + log10.dsc mul.dsc mul_2si.dsc mul_2ui.dsc mul_fr.dsc mul_i.dsc \ + mul_si.dsc mul_ui.dsc neg.dsc norm.dsc pow.dsc pow_d.dsc pow_fr.dsc \ + pow_si.dsc pow_ui.dsc pow_z.dsc proj.dsc real.dsc sin.dsc sin_cos.dsc \ + sinh.dsc sqr.dsc sqrt.dsc sub.dsc sub_fr.dsc sub_ui.dsc tan.dsc \ + tanh.dsc ui_div.dsc ui_ui_sub.dsc +DATA_SETS = abs.dat acos.dat acosh.dat add.dat add_fr.dat arg.dat \ + asin.dat asinh.dat atan.dat atanh.dat conj.dat cos.dat cosh.dat \ + div.dat div_fr.dat exp.dat fma.dat fr_div.dat fr_sub.dat inp_str.dat \ + log.dat log10.dat mul.dat mul_fr.dat neg.dat norm.dat pow.dat \ + pow_fr.dat pow_si.dat pow_ui.dat pow_z.dat proj.dat sin.dat sinh.dat \ + sqr.dat sqrt.dat strtoc.dat sub.dat sub_fr.dat tan.dat tanh.dat +EXTRA_DIST = data_check.tpl tgeneric.tpl $(DATA_SETS) $(DESCRIPTIONS) TESTS_ENVIRONMENT = $(VALGRIND) TESTS = $(check_PROGRAMS) CLEANFILES = mpc_test - diff --git a/tests/README.dev b/tests/README.dev new file mode 100644 index 0000000..ad8faad --- /dev/null +++ b/tests/README.dev @@ -0,0 +1,185 @@ +This file describe the framework for testing MPC functions. +=========================================================== + +Functionality +------------- +The test suite usually perform 3 kinds of tests for a given function: + +1. it verifies that the result returned by the function matches with +precomputed data written in a '.dat' file, + +2. it checks that the function computes coherent results in low and high +precision, + +3. optionally, it performs additional checks specific to the function under +test. + +The test suite provides support for the first two items. This ensures that all +function tests using the framework execute a set of verifications in a +systematic way. + + +How to add a test for a new function? +------------------------------------- + +1. The test framework does support only functions with exactly one output +parameter. An ad hoc solution must be used for functions with other +prototypes. For an adaptation to a function with two output parameters, see +tsin_cos.c file. + +If you want to use the system checking against data sets or the random tests, +you will need to describe the function prototype in a file (procedure detailed +in 2.) and to define several macros (detailed in 3.). Then, you can call the +data_check_template() function for checking against a data set (see 4.) or the +tgeneric_template() function for random values (see 5.). + +In both cases, the 'mpc-test.h' header file must be included. + + +2. First write a description of the function interface describing, in this +order, the name of the function, the return value, the set of input +parameters, and the set of output parameters. + +For instance, the description file of the mpc_add function (excerpt of +add.dsc) is displayed below: + +# Description file of the function +NAME: + mpc_add +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_srcptr + mpc_rnd_t + +The integer value returned by MPC functions is usually the inexact flag. In +that case, the return value type must be denoted as 'mpc_inex'. Other types +are generally the C type that appears in the function prototype. + +The easiest way is to adapt a description file of a function with the same +prototype. + + +3. Second, define at least the MPC_FUNCTION_CALL macro. + +Because the framework is common to all MPC function (or so), the +data_check_template() and the tgeneric_template() functions are written in a +generic manner. Both function are defined in its own file that the user must +include. They call the function under test through several macros +defined by the user before the inclusion of the corresponding file. + +The definition of each macro specifies the name of the function under test and +the parameters in use along with their type. + +Four macros can be of interest: + +In all cases, the macro MPC_FUNCTION_CALL must + MPC_FUNCTION_CALL: mandatory, it describes a simple call to the function, + + MPC_FUNCTION_CALL_SYMMETRIC: optional, it describes a function call with a +switch of two parameters, it is useful for automatically checking the +consistency of symmetric functions, i. e. f(a,b) == f(b,a), + + MPC_FUNCTION_CALL_REUSE_OP1 + MPC_FUNCTION_CALL_REUSE_OP2 + MPC_FUNCTION_CALL_REUSE_OP3 + the last three macros can be used to check that the result is not affected by +the reuse of an input variable as output parameter + +Here is how these macros are defined for the mpc_add function: +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_add (P[1].mpc, P[2].mpc, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_SYMMETRIC \ + P[0].mpc_inex = mpc_add (P[1].mpc, P[3].mpc, P[2].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_add (P[1].mpc, P[1].mpc, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP2 \ + P[0].mpc_inex = mpc_add (P[1].mpc, P[2].mpc, P[1].mpc, P[4].mpc_rnd) + + +4. For precomputed values. + +The test framework can check the result of the function on given parameters +against a reference value written in a file. + +The file "data_check.tpl" must be included after the definition of +MPC_FUNCTION_CALL macros and the data_check_template() function can be used in +the code. + +The first parameter of data_check_template() is the name of the description +file of the function and the second is the name of the data file. +As an example, here is the function call for testing mpc_add(): + data_check_template ("add.dsc", "add.dat"); + +The data file contains a sequence of input and output values in the order +given by the function prototype. So, output values are usually first, as it is +the case for most MPC functions. + +Here is an excerpt of 'add.dat' (the data set for mpc_add()): +# special values (following ISO C99 standard) +0 0 53 -inf 53 -inf 53 -inf 53 -inf 53 -inf 53 -inf N Z +# pure real argument ++ 0 53 0x10000000000001p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-105 53 -0 N N + +The ternary value associated with an mpfr_t result is described as: +"?" it should not be checked +"+" if the computed result is greater than the exact mathematical result +"0" if the computed result is exactly the mathematical result +"-" if the computed result is less than the exact mathematical result + +The mpc_inex value is a pair of ternary values. + +The values for mpfr_t and mpc_t parameters come along with their +precision. Use prefixes "0b" for values in base two, "0x" for values in base +sixteen, no prefix for value in base ten. In all bases, "nan" is NaN, "inf" +is infinity; the sign of infinity and zero is checked if it is specified in +the data file, otherwise it is ignored. + +The MPFR rounding mode is denoted by +"N" for rounding to nearest +"Z" for rounding towards zero +"U" for rounding towards plus infinity +"D" for rounding towards minus infinity + +The MPC rounding mode is a pair of MPFR rounding mode. + +Thus, the following line from 'add.dat' +0 0 53 -inf 53 -inf 53 -inf 53 -inf 53 -inf 53 -inf N Z +indicates that +(-inf +i * -inf) + (-inf +i * -inf) +should be exactly +-inf +i * -inf +in 53-bit precision with rounding to nearest for the real part +and rounding toward minus infinity for the imaginary part. + +The line ++ 0 53 0x10000000000001p-52 53 -0 53 +1 53 -0 53 0x10000000000001p-105 53 -0 N N +indicates that +(+1 +i * -0) + (0x10000000000001p-105 +i * -0) +is +0x10000000000001p-52 +i * -0 +in 53-bit precision when rounding both part to nearest, the real part is +actually an overestimation of the exact result (ternary value: +), while the +imaginary part is exact. + + +5. Test with random values + +The framework also provides generic tests with random values. + +The file "tgeneric.tpl" must be included after the definition of +MPC_FUNCTION_CALL macros and the tgeneric_template() function can be used in +the code. + +The first parameter of tgeneric_template() is the description file of the +function under test. The second and third parameter are the minimum and +maximum precision for input and output parameters. The fourth is the iteration +step in the precision range. The last parameter is the maximum +exponent. Usually, the range of random parameter has to be restricted for a +reasonable testing time. + +As an example, here is the function call for testing mpc_add(): + tgeneric_template ("add.dsc", 2, 1024, 7, 128); diff --git a/tests/abs.dsc b/tests/abs.dsc new file mode 100644 index 0000000..345a332 --- /dev/null +++ b/tests/abs.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_abs +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_abs +RETURN: + mpfr_inex +OUTPUT: + mpfr_ptr +INPUT: + mpc_srcptr + mpfr_rnd_t diff --git a/tests/acos.dsc b/tests/acos.dsc new file mode 100644 index 0000000..08a1c13 --- /dev/null +++ b/tests/acos.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_acos +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_acos +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/acosh.dsc b/tests/acosh.dsc new file mode 100644 index 0000000..657066f --- /dev/null +++ b/tests/acosh.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_acosh +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_acosh +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/add.dsc b/tests/add.dsc new file mode 100644 index 0000000..d69e35e --- /dev/null +++ b/tests/add.dsc @@ -0,0 +1,30 @@ +# Description file for mpc_add +# +# Copyright (C) 2008, 2010, 2011, 2012, INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_add +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_srcptr + mpc_rnd_t diff --git a/tests/add_fr.dsc b/tests/add_fr.dsc new file mode 100644 index 0000000..ef6c11a --- /dev/null +++ b/tests/add_fr.dsc @@ -0,0 +1,30 @@ +# Description file for mpc_add_fr +# +# Copyright (C) 2008, 2010, 2011, 2012, INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_add_fr +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpfr_srcptr + mpc_rnd_t diff --git a/tests/add_si.dsc b/tests/add_si.dsc new file mode 100644 index 0000000..1647281 --- /dev/null +++ b/tests/add_si.dsc @@ -0,0 +1,31 @@ +# Description file for mpc_add_si +# +# Copyright (C) 2008, 2010, 2011, 2012, INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_add_si +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + long int + mpc_rnd_t + \ No newline at end of file diff --git a/tests/add_ui.dsc b/tests/add_ui.dsc new file mode 100644 index 0000000..03a04e2 --- /dev/null +++ b/tests/add_ui.dsc @@ -0,0 +1,31 @@ +# Description file for mpc_add_ui +# +# Copyright (C) 2008, 2010, 2011, 2012, INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_add_ui +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + unsigned long int + mpc_rnd_t + \ No newline at end of file diff --git a/tests/arg.dsc b/tests/arg.dsc new file mode 100644 index 0000000..7149931 --- /dev/null +++ b/tests/arg.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_arg +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_arg +RETURN: + mpfr_inex +OUTPUT: + mpfr_ptr +INPUT: + mpc_srcptr + mpfr_rnd_t diff --git a/tests/asin.dsc b/tests/asin.dsc new file mode 100644 index 0000000..01ef0f2 --- /dev/null +++ b/tests/asin.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_asin +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_asin +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/asinh.dsc b/tests/asinh.dsc new file mode 100644 index 0000000..5a7097b --- /dev/null +++ b/tests/asinh.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_asinh +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_asinh +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/atan.dsc b/tests/atan.dsc new file mode 100644 index 0000000..686190b --- /dev/null +++ b/tests/atan.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_atan +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_atan +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/atanh.dsc b/tests/atanh.dsc new file mode 100644 index 0000000..d02736a --- /dev/null +++ b/tests/atanh.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_atanh +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_atanh +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/check_data.c b/tests/check_data.c new file mode 100644 index 0000000..6d6bc69 --- /dev/null +++ b/tests/check_data.c @@ -0,0 +1,118 @@ +/* check_data.c -- Check computed data against reference result. + +Copyright (C) 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +#define MPC_INEX_CMP(c, r, i) \ + (((r) == TERNARY_NOT_CHECKED || (r) == MPC_INEX_RE(c)) \ + && ((i) == TERNARY_NOT_CHECKED || (i) == MPC_INEX_IM (c))) + +static int +check_param (mpc_operand_t* got, mpc_operand_t* expected, mpc_param_t t) +{ + switch (t) + { + case NATIVE_INT: + return got->i == expected->i; + case NATIVE_UL: + return got->ui == expected->ui; + case NATIVE_L: + return got->si == expected->si; + case NATIVE_D: + return got->d == expected->d; + + case GMP_Z: + return mpz_cmp (got->mpz, expected->mpz); + case GMP_Q: + return mpq_cmp (got->mpq, expected->mpq); + case GMP_F: + return mpf_cmp (got->mpf, expected->mpf); + + case MPFR_INEX: + return expected->mpfr_inex == TERNARY_NOT_CHECKED + || got->mpfr_inex == expected->mpfr_inex; + + case MPFR: + return tpl_check_mpfr_data (got->mpfr, + expected->mpfr_data); + + case MPC_INEX: + return MPC_INEX_CMP (got->mpc_inex, + expected->mpc_inex_data.real, + expected->mpc_inex_data.imag); + + case MPC: + return tpl_check_mpc_data (got->mpc, + expected->mpc_data); + + default: + fprintf (stderr, "check_data: unsupported type.\n"); + exit (1); + } +} + +void +check_data (mpc_datafile_context_t* dc, mpc_fun_param_t* params, int reused_op) +{ + int out, i; + int total = params->nbout + params->nbin; + + for (out = 0; out < params->nbout; out++) + { + if (!check_param (&(params->P[out]), &(params->P[total + out]), + params->T[out])) + { + printf ("%s() failed", params->name); + if (dc != NULL) + printf (" (line %lu, file %s)", + dc->test_line_number, dc->pathname); + else + printf (" with random parameter%c", + params->nbin > 2 ? 's' : '\0'); + + if (reused_op != 0) + printf (" when reusing input parameter op%d as output parameter", + reused_op - params->nbout); + printf ("\n"); + + for (i = 0; i < params->nbin; i++) + { + printf ("op%d", i + 1); + print_parameter (params, params->nbout + i); + } + + for (i = 0; i < params->nbout; i++) + { + if ((params->T[i] == MPFR_INEX && params->T[out] != MPFR_INEX) + || (params->T[i] == MPC_INEX && params->T[out] != MPC_INEX)) + continue; /* don't print inexact flag if it is correct */ + + printf (" got%c", + (total + i > params->nbout ? '\0' : i + '0')); + print_parameter (params, i); + printf ("expected%c", + (total + i > params->nbout ? '\0' : i + '0')); + print_parameter (params, total + i); + } + printf ("\n"); + exit (1); + } + } +} diff --git a/tests/clear_parameters.c b/tests/clear_parameters.c new file mode 100644 index 0000000..d5c74f8 --- /dev/null +++ b/tests/clear_parameters.c @@ -0,0 +1,82 @@ +/* clear_parameters -- Deallocate memory for function parameters. + +Copyright (C) 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +static void +clear_param (mpc_operand_t* p, mpc_param_t t) +{ + switch (t) + { + case NATIVE_INT: + case NATIVE_UL: + case NATIVE_L: + case NATIVE_D: + break; + + case GMP_Z: + mpz_clear (p->mpz); + break; + case GMP_Q: + mpq_clear (p->mpq); + break; + case GMP_F: + mpf_clear (p->mpf); + break; + + case MPFR_INEX: + break; + case MPFR: + mpfr_clear (p->mpfr); + break; + + case MPC_INEX: + break; + case MPC: + mpc_clear (p->mpc); + break; + + case MPFR_RND: + case MPC_RND: + break; + + default: + fprintf (stderr, "clear_parameters: unsupported type.\n"); + exit (1); + } +} + +void +clear_parameters (mpc_fun_param_t *params) +{ + int in, out; + int total = params->nbout + params->nbin; + + for (out = 0; out < params->nbout; out++) + { + clear_param (&(params->P[out]), params->T[out]); + clear_param (&(params->P[total + out]), params->T[out]); + } + + for (in = params->nbout; in < total; in++) + { + clear_param (&(params->P[in]), params->T[in]); + } +} diff --git a/tests/close_datafile.c b/tests/close_datafile.c new file mode 100644 index 0000000..b7ddcc6 --- /dev/null +++ b/tests/close_datafile.c @@ -0,0 +1,28 @@ +/* close_datafile.c -- Deallocate buffers and close datafile. + +Copyright (C) 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +void +close_datafile (mpc_datafile_context_t *dc) +{ + free (dc->pathname); + fclose (dc->fd); +} diff --git a/tests/conj.dsc b/tests/conj.dsc new file mode 100644 index 0000000..db02041 --- /dev/null +++ b/tests/conj.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_conj +# +# Copyright (C) 2008, 2010, 2011, 2012, 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_conj +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/copy_parameter.c b/tests/copy_parameter.c new file mode 100644 index 0000000..4c1ff37 --- /dev/null +++ b/tests/copy_parameter.c @@ -0,0 +1,122 @@ +/* copy_parameter.c -- Copy of an input parameter into a parameter reused for + output. + +Copyright (C) 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +int +copy_parameter (mpc_fun_param_t *params, int index_dest, int index_src) +{ + mpfr_prec_t pre1, pim1; + mpfr_prec_t pre2, pim2; + int index_ref; + + if (params->T[index_src] != params->T[index_dest]) + { + fprintf (stderr, "copy_parameter: types of parameters don't match.\n"); + exit (1); + } + + switch (params->T[index_src]) + { + case NATIVE_INT: + tpl_copy_int (¶ms->P[index_dest].i, ¶ms->P[index_src].i); + return 0; + case NATIVE_UL: + tpl_copy_ui (¶ms->P[index_dest].ui, ¶ms->P[index_src].ui); + return 0; + case NATIVE_L: + tpl_copy_si (¶ms->P[index_dest].si, ¶ms->P[index_src].si); + return 0; + case NATIVE_D: + tpl_copy_d (¶ms->P[index_dest].d, ¶ms->P[index_src].d); + return 0; + + case NATIVE_LD: + /* TODO */ + fprintf (stderr, "copy_parameter: type not implemented.\n"); + exit (1); + break; + + case NATIVE_DC: + case NATIVE_LDC: +#ifdef _Complex_I + /* TODO */ + fprintf (stderr, "copy_parameter: type not implemented.\n"); + exit (1); +#endif + break; + + case NATIVE_IM: + case NATIVE_UIM: +#ifdef _MPC_H_HAVE_INTMAX_T + /* TODO */ + fprintf (stderr, "copy_parameter: type not implemented.\n"); + exit (1); +#endif + break; + + case GMP_Z: + mpz_set (params->P[index_dest].mpz, params->P[index_src].mpz); + return 0; + case GMP_Q: + mpq_set (params->P[index_dest].mpq, params->P[index_src].mpq); + return 0; + case GMP_F: + mpf_set (params->P[index_dest].mpf, params->P[index_src].mpf); + return 0; + + case MPFR: + /* need same precision between source, destination, and reference */ + pre1 = mpfr_get_prec (params->P[index_dest].mpfr); + pre2 = mpfr_get_prec (params->P[index_src].mpfr); + index_ref = index_dest + params->nbout + params->nbin; + if (pre1 != pre2 + || pre1 != mpfr_get_prec (params->P[index_ref].mpfr)) + return -1; + + tpl_copy_mpfr (params->P[index_dest].mpfr, params->P[index_src].mpfr); + return 0; + + case MPC: + mpc_get_prec2 (&pre1, &pim1, params->P[index_dest].mpc); + /* check same precision between source and destination */ + mpc_get_prec2 (&pre2, &pim2, params->P[index_src].mpc); + if (pre1 != pre2 || pim1 != pim2) + return -1; + /* check same precision between source and reference */ + index_ref = index_dest + params->nbout + params->nbin; + mpc_get_prec2 (&pre2, &pim2, params->P[index_ref].mpc); + if (pre1 != pre2 || pim1 != pim2) + return -1; + + tpl_copy_mpc (params->P[index_dest].mpc, params->P[index_src].mpc); + return 0; + + case NATIVE_STRING: + case MPFR_INEX: case MPFR_RND: + case MPC_INEX: case MPC_RND: + /* no supported copy */ + break; + } + + fprintf (stderr, "copy_parameter: unsupported type.\n"); + exit (1); +} diff --git a/tests/cos.dsc b/tests/cos.dsc new file mode 100644 index 0000000..b71e24c --- /dev/null +++ b/tests/cos.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_cos +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_cos +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/cosh.dsc b/tests/cosh.dsc new file mode 100644 index 0000000..15a5937 --- /dev/null +++ b/tests/cosh.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_cosh +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_cosh +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/data_check.tpl b/tests/data_check.tpl new file mode 100644 index 0000000..08dfa2a --- /dev/null +++ b/tests/data_check.tpl @@ -0,0 +1,93 @@ +/* data_check.tpl -- template file for checking result against data + file. + + Usage: Before including this template file in your source file, + #define the prototype of the function under test in the + CALL_MPC_FUNCTION symbol, see tadd_tmpl.c for an example. + + To test the reuse of the first parameter, #define the + MPC_FUNCTION_CALL_REUSE_OP1 and MPC_FUNCTION_CALL_REUSE_OP2 symbols + with the first and second input parameter reused as the output, see + tadd_tmpl.c for an example. It is not possible to test parameter + reuse in functions with two output (like mpc_sin_cos) with this + system. + +Copyright (C) 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#ifndef MPC_FUNCTION_CALL +#error Define MPC_FUNCTION_CALL before including 'data_check.tpl'. +#endif + +int +data_check_template (const char* descr_file, const char * data_file) +{ + static int rand_counter = 0; + + mpc_datafile_context_t datafile_context; + mpc_datafile_context_t *dc = &datafile_context; + + mpc_fun_param_t params; + mpc_operand_t *P = params.P; /* developer-friendly alias */ + + read_description (¶ms, descr_file); + init_parameters (¶ms); + + open_datafile (dc, data_file); + while (datafile_context.nextchar != EOF) { + read_line (dc, ¶ms); + set_mpfr_flags (rand_counter); + MPC_FUNCTION_CALL; + check_mpfr_flags (rand_counter++); + check_data (dc, ¶ms, 0); + +#ifdef MPC_FUNCTION_CALL_SYMMETRIC + MPC_FUNCTION_CALL_SYMMETRIC; + check_data (dc, ¶ms, 0); +#endif + +#ifdef MPC_FUNCTION_CALL_REUSE_OP1 + if (copy_parameter (¶ms, 1, 2) == 0) + { + MPC_FUNCTION_CALL_REUSE_OP1; + check_data (dc, ¶ms, 2); + } +#endif + +#ifdef MPC_FUNCTION_CALL_REUSE_OP2 + if (copy_parameter (¶ms, 1, 3) == 0) + { + MPC_FUNCTION_CALL_REUSE_OP2; + check_data (dc, ¶ms, 3); + } +#endif + +#ifdef MPC_FUNCTION_CALL_REUSE_OP3 + if (copy_parameter (¶ms, 1, 4) == 0) + { + MPC_FUNCTION_CALL_REUSE_OP3; + check_data (dc, ¶ms, 4); + } +#endif + } + close_datafile (dc); + + clear_parameters (¶ms); + + return 0; +} diff --git a/tests/div.dsc b/tests/div.dsc new file mode 100644 index 0000000..e2dc546 --- /dev/null +++ b/tests/div.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_div +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_div +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_srcptr + mpc_rnd_t diff --git a/tests/div_2si.dsc b/tests/div_2si.dsc new file mode 100644 index 0000000..43339f8 --- /dev/null +++ b/tests/div_2si.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_div_2si +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_div_2si +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + unsigned long int + mpc_rnd_t diff --git a/tests/div_2ui.dsc b/tests/div_2ui.dsc new file mode 100644 index 0000000..85e0707 --- /dev/null +++ b/tests/div_2ui.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_div_2ui +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_div_2ui +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + unsigned long int + mpc_rnd_t diff --git a/tests/div_fr.dsc b/tests/div_fr.dsc new file mode 100644 index 0000000..69b4693 --- /dev/null +++ b/tests/div_fr.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_div_fr +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_div_fr +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpfr_srcptr + mpc_rnd_t diff --git a/tests/div_ui.dsc b/tests/div_ui.dsc new file mode 100644 index 0000000..7365b82 --- /dev/null +++ b/tests/div_ui.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_div_ui +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_div_ui +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + unsigned long int + mpc_rnd_t diff --git a/tests/double_rounding.c b/tests/double_rounding.c new file mode 100644 index 0000000..6181d1a --- /dev/null +++ b/tests/double_rounding.c @@ -0,0 +1,151 @@ +/* double_rounding.c -- Functions for checking double rounding. + +Copyright (C) 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +/* return 1 if double rounding occurs; + return 0 otherwise */ +static int +double_rounding_mpfr (mpfr_ptr lowprec, + mpfr_ptr hiprec, int hiprec_inex, mpfr_rnd_t hiprec_rnd) +{ + mpfr_exp_t hiprec_err; + mpfr_rnd_t lowprec_rnd = hiprec_rnd; + mpfr_prec_t lowprec_prec = mpfr_get_prec (lowprec); + + /* hiprec error is bounded by one ulp */ + hiprec_err = mpfr_get_prec (hiprec) - 1; + + if (hiprec_rnd == MPFR_RNDN) + /* when rounding to nearest, use the trick for determining the + correct ternary value which is described in MPFR + documentation */ + { + hiprec_err++; /* error is bounded by one half-ulp */ + lowprec_rnd = MPFR_RNDZ; + lowprec_prec++; + } + + return (hiprec_inex == 0 + || mpfr_can_round (hiprec, hiprec_err, hiprec_rnd, + lowprec_rnd, lowprec_prec)); +} + +/* return 1 if double rounding occurs; + return 0 otherwise */ +static int +double_rounding_mpc (mpc_ptr lowprec, + mpc_ptr hiprec, int hiprec_inex, mpc_rnd_t hiprec_rnd) +{ + mpfr_ptr lowprec_re = mpc_realref (lowprec); + mpfr_ptr lowprec_im = mpc_imagref (lowprec); + mpfr_ptr hiprec_re = mpc_realref (hiprec); + mpfr_ptr hiprec_im = mpc_imagref (hiprec); + int inex_re = MPC_INEX_RE (hiprec_inex); + int inex_im = MPC_INEX_IM (hiprec_inex); + mpfr_rnd_t rnd_re = MPC_RND_RE (hiprec_rnd); + mpfr_rnd_t rnd_im = MPC_RND_IM (hiprec_rnd); + + return (double_rounding_mpfr (lowprec_re, hiprec_re, inex_re, rnd_re) + && double_rounding_mpfr (lowprec_im, hiprec_im, inex_im, rnd_im)); +} + +/* check whether double rounding occurs; if not, round extra precise output + value and set reference parameter */ +int +double_rounding (mpc_fun_param_t *params) +{ + int out; + const int offset = params->nbout + params->nbin; + const int rnd_index = params->nbout + params->nbin - 1; + + for (out = 0; out < params->nbout; out++) { + if (params->T[out] == MPC) + { + MPC_ASSERT (params->T[0] == MPC_INEX); + MPC_ASSERT (params->T[offset] == MPC_INEX); + MPC_ASSERT (params->T[out + offset] == MPC); + MPC_ASSERT (params->T[rnd_index] == MPC_RND); + + if (double_rounding_mpc (params->P[out + offset].mpc_data.mpc, + params->P[out].mpc, + params->P[0].mpc_inex, + params->P[rnd_index].mpc_rnd)) + /* the hight-precision value and the exact value round to the same + low-precision value */ + { + int inex; + inex = mpc_set (params->P[out + offset].mpc_data.mpc, + params->P[out].mpc, + params->P[rnd_index].mpc_rnd); + params->P[out + offset].mpc_data.known_sign_real = -1; + params->P[out + offset].mpc_data.known_sign_imag = -1; + + /* no double rounding means that the ternary value may comes from + the high-precision calculation or from the rounding */ + if (MPC_INEX_RE (inex) == 0) + params->P[offset].mpc_inex_data.real = + MPC_INEX_RE (params->P[0].mpc_inex); + else + params->P[offset].mpc_inex_data.real = MPC_INEX_RE (inex); + if (MPC_INEX_IM (inex) == 0) + params->P[offset].mpc_inex_data.imag = + MPC_INEX_IM (params->P[0].mpc_inex); + else + params->P[offset].mpc_inex_data.imag = MPC_INEX_IM (inex); + } + else + /* double rounding occurs */ + return 1; + } + else if (params->T[out] == MPFR) + { + MPC_ASSERT (params->T[0] == MPFR_INEX); + MPC_ASSERT (params->T[offset] == MPFR_INEX); + MPC_ASSERT (params->T[out + offset] == MPFR); + MPC_ASSERT (params->T[rnd_index] == MPFR_RND); + + if (double_rounding_mpfr (params->P[out + offset].mpfr_data.mpfr, + params->P[out].mpfr, + params->P[0].mpfr_inex, + params->P[rnd_index].mpfr_rnd)) + /* the hight-precision value and the exact value round to the same + low-precision value */ + { + int inex; + inex = mpfr_set (params->P[out + offset].mpfr_data.mpfr, + params->P[out].mpfr, + params->P[rnd_index].mpfr_rnd); + params->P[out + offset].mpfr_data.known_sign = -1; + + /* no double rounding means that the ternary value may comes from + the high-precision calculation or from the rounding */ + if (inex == 0) + params->P[offset].mpfr_inex = params->P[0].mpfr_inex; + else + params->P[offset].mpfr_inex = inex; + } + else + /* double rounding occurs */ + return 1; + } + } + return 0; +} diff --git a/tests/exp.dsc b/tests/exp.dsc new file mode 100644 index 0000000..83ba4b7 --- /dev/null +++ b/tests/exp.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_exp +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_exp +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/fma.dsc b/tests/fma.dsc new file mode 100644 index 0000000..54bcd9b --- /dev/null +++ b/tests/fma.dsc @@ -0,0 +1,31 @@ +# Description file for mpc_fma +# +# Copyright (C) 2012, INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_fma +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_srcptr + mpc_srcptr + mpc_rnd_t diff --git a/tests/fr_div.dsc b/tests/fr_div.dsc new file mode 100644 index 0000000..7bc24d7 --- /dev/null +++ b/tests/fr_div.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_fr_div +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_fr_div +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpfr_srcptr + mpc_srcptr + mpc_rnd_t diff --git a/tests/fr_sub.dsc b/tests/fr_sub.dsc new file mode 100644 index 0000000..63f14b4 --- /dev/null +++ b/tests/fr_sub.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_fr_sub +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_fr_sub +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpfr_srcptr + mpc_srcptr + mpc_rnd_t diff --git a/tests/imag.dsc b/tests/imag.dsc new file mode 100644 index 0000000..0f6880d --- /dev/null +++ b/tests/imag.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_imag +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_imag +RETURN: + mpfr_inex +OUTPUT: + mpfr_ptr +INPUT: + mpc_srcptr + mpfr_rnd_t diff --git a/tests/init_parameters.c b/tests/init_parameters.c new file mode 100644 index 0000000..ea94a34 --- /dev/null +++ b/tests/init_parameters.c @@ -0,0 +1,83 @@ +/* init_parameters -- Allocate memory for function parameters. + +Copyright (C) 2012 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include +#include "mpc-tests.h" + +static void +init_param (mpc_operand_t* p, mpc_param_t t) +{ + switch (t) + { + case NATIVE_INT: + case NATIVE_UL: + case NATIVE_L: + case NATIVE_D: + break; + + case GMP_Z: + mpz_init (p->mpz); + break; + case GMP_Q: + mpq_init (p->mpq); + break; + case GMP_F: + mpf_init (p->mpf); + break; + + case MPFR_INEX: + break; + case MPFR: + mpfr_init2 (p->mpfr, 512); + break; + + case MPC_INEX: + break; + case MPC: + mpc_init2 (p->mpc, 512); + break; + + case MPFR_RND: + case MPC_RND: + break; + + default: + fprintf (stderr, "init_parameters: unsupported type.\n"); + exit (1); + } +} + +void +init_parameters (mpc_fun_param_t *params) +{ + int in, out; + int total = params->nbout + params->nbin; + + for (out = 0; out < params->nbout; out++) + { + init_param (&(params->P[out]), params->T[out]); + init_param (&(params->P[total + out]), params->T[total + out]); + } + + for (in = params->nbout; in < total; in++) + { + init_param (&(params->P[in]), params->T[in]); + } +} diff --git a/tests/log.dsc b/tests/log.dsc new file mode 100644 index 0000000..c225241 --- /dev/null +++ b/tests/log.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_log +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_log +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/log10.dsc b/tests/log10.dsc new file mode 100644 index 0000000..3a7dc5a --- /dev/null +++ b/tests/log10.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_log10 +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_log10 +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/mpc-tests.h b/tests/mpc-tests.h index fe3e452..19027a5 100644 --- a/tests/mpc-tests.h +++ b/tests/mpc-tests.h @@ -1,6 +1,6 @@ /* mpc-tests.h -- Tests helper functions. -Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA +Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -103,9 +103,17 @@ do { \ extern gmp_randstate_t rands; extern void test_start (void); -extern void test_end (void); -extern void test_default_random (mpc_ptr, mp_exp_t, mp_exp_t, unsigned int, unsigned int); - +extern void test_end (void); +extern void test_default_random (mpc_ptr, mp_exp_t, mp_exp_t, + unsigned int, unsigned int); + +void test_random_si (long int *n, unsigned long emax, + unsigned int negative_probability); +void test_random_d (double *x, unsigned int negative_probability); +void test_random_mpfr (mpfr_ptr x, mpfr_exp_t emin, mpfr_exp_t emax, + unsigned int negative_probability); +void test_random_mpc (mpc_ptr z, mpfr_exp_t emin, mpfr_exp_t emax, + unsigned int negative_probability); /** COMPARISON FUNCTIONS **/ /* some sign are unspecified in ISO C99, thus we record in struct known_signs_t @@ -125,111 +133,222 @@ typedef struct Unlike mpfr_cmp, same_mpfr_value(got, ref, x) return 1 when got and ref are both NaNs. */ extern int same_mpfr_value (mpfr_ptr got, mpfr_ptr ref, int known_sign); -extern int same_mpc_value (mpc_ptr got, mpc_ptr ref, known_signs_t known_signs); - - -/** GENERIC TESTS **/ - -typedef int (*CC_func_ptr) (mpc_t, mpc_srcptr, mpc_rnd_t); -typedef int (*C_CC_func_ptr) (mpc_t, mpc_srcptr, mpc_srcptr, mpc_rnd_t); -typedef int (*CCCC_func_ptr) (mpc_t, mpc_srcptr, mpc_srcptr, mpc_srcptr, - mpc_rnd_t); -typedef int (*CCU_func_ptr) (mpc_t, mpc_srcptr, unsigned long, mpc_rnd_t); -typedef int (*CCS_func_ptr) (mpc_t, mpc_srcptr, long, mpc_rnd_t); -typedef int (*CCI_func_ptr) (mpc_t, mpc_srcptr, int, mpc_rnd_t); -typedef int (*CCF_func_ptr) (mpc_t, mpc_srcptr, mpfr_srcptr, mpc_rnd_t); -typedef int (*CFC_func_ptr) (mpc_t, mpfr_srcptr, mpc_srcptr, mpc_rnd_t); -typedef int (*CUC_func_ptr) (mpc_t, unsigned long, mpc_srcptr, mpc_rnd_t); -typedef int (*CUUC_func_ptr) (mpc_t, unsigned long, unsigned long, mpc_srcptr, - mpc_rnd_t); -typedef int (*FC_func_ptr) (mpfr_t, mpc_srcptr, mpfr_rnd_t); -typedef int (*CC_C_func_ptr) (mpc_t, mpc_t, mpc_srcptr, mpc_rnd_t, mpc_rnd_t); - -typedef union { - FC_func_ptr FC; /* output: mpfr_t, input: mpc_t */ - CC_func_ptr CC; /* output: mpc_t, input: mpc_t */ - C_CC_func_ptr C_CC; /* output: mpc_t, inputs: (mpc_t, mpc_t) */ - CCCC_func_ptr CCCC; /* output: mpc_t, inputs: (mpc_t, mpc_t, mpc_t) */ - CCU_func_ptr CCU; /* output: mpc_t, inputs: (mpc_t, unsigned long) */ - CCS_func_ptr CCS; /* output: mpc_t, inputs: (mpc_t, long) */ - CCI_func_ptr CCI; /* output: mpc_t, inputs: (mpc_t, int) */ - CCF_func_ptr CCF; /* output: mpc_t, inputs: (mpc_t, mpfr_t) */ - CFC_func_ptr CFC; /* output: mpc_t, inputs: (mpfr_t, mpc_t) */ - CUC_func_ptr CUC; /* output: mpc_t, inputs: (unsigned long, mpc_t) */ - CUUC_func_ptr CUUC; /* output: mpc_t, inputs: (ulong, ulong, mpc_t) */ - CC_C_func_ptr CC_C; /* outputs: (mpc_t, mpc_t), input: mpc_t */ -} func_ptr; - -/* the rounding mode is implicit */ -typedef enum { - FC, /* output: mpfr_t, input: mpc_t */ - CC, /* output: mpc_t, input: mpc_t */ - C_CC, /* output: mpc_t, inputs: (mpc_t, mpc_t) */ - CCCC, /* output: mpc_t, inputs: (mpc_t, mpc_t, mpc_t) */ - CCU, /* output: mpc_t, inputs: (mpc_t, unsigned long) */ - CCS, /* output: mpc_t, inputs: (mpc_t, long) */ - CCI, /* output: mpc_t, inputs: (mpc_t, int) */ - CCF, /* output: mpc_t, inputs: (mpc_t, mpfr_t) */ - CFC, /* output: mpc_t, inputs: (mpfr_t, mpc_t) */ - CUC, /* output: mpc_t, inputs: (unsigned long, mpc_t) */ - CUUC, /* output: mpc_t, inputs: (ulong, ulong, mpc_t) */ - CC_C /* outputs: (mpc_t, mpc_t), input: mpc_t */ -} func_type; - -/* properties */ -#define FUNC_PROP_NONE 0 -#define FUNC_PROP_SYMETRIC 1 - -typedef struct -{ - func_ptr pointer; - func_type type; - const char * name; - int properties; -} mpc_function; - -#define DECL_FUNC(_ftype, _fvar, _func) \ - mpc_function _fvar; \ - _fvar.pointer._ftype = _func; \ - _fvar.type = _ftype; \ - _fvar.name = QUOTE (_func); \ - _fvar.properties = FUNC_PROP_NONE; - - -/* tgeneric(mpc_function, prec_min, prec_max, step, exp_max) checks rounding - with random numbers: - - with precision ranging from prec_min to prec_max with an increment of - step, - - with exponent between -exp_max and exp_max. - - It also checks parameter reuse (it is assumed here that either two mpc_t - variables are equal or they are different, in the sense that the real part of - one of them cannot be the imaginary part of the other). */ -void tgeneric (mpc_function, mpfr_prec_t, mpfr_prec_t, mpfr_prec_t, mp_exp_t); - +extern int same_mpc_value (mpc_ptr got, mpc_ptr ref, + known_signs_t known_signs); /** READ FILE WITH TEST DATA SET **/ -/* data_check (function, "data_file_name") checks function results against - precomputed data in a file.*/ -extern void data_check (mpc_function, const char *); - -extern FILE * open_data_file (const char *file_name); -extern void close_data_file (FILE *fp); +extern FILE * open_data_file (const char *file_name); +extern void close_data_file (FILE *fp); /* helper file reading functions */ extern void skip_whitespace_comments (FILE *fp); -extern void read_ternary (FILE *fp, int* ternary); -extern void read_mpfr_rounding_mode (FILE *fp, mpfr_rnd_t* rnd); -extern void read_mpc_rounding_mode (FILE *fp, mpc_rnd_t* rnd); -extern mpfr_prec_t read_mpfr_prec (FILE *fp); -extern void read_int (FILE *fp, int *n, const char *name); -extern size_t read_string (FILE *fp, char **buffer_ptr, size_t buffer_length, const char *name); -extern void read_mpfr (FILE *fp, mpfr_ptr x, int *known_sign); -extern void read_mpc (FILE *fp, mpc_ptr z, known_signs_t *ks); +extern void read_ternary (FILE *fp, int* ternary); +extern void read_mpfr_rounding_mode (FILE *fp, mpfr_rnd_t* rnd); +extern void read_mpc_rounding_mode (FILE *fp, mpc_rnd_t* rnd); +extern mpfr_prec_t read_mpfr_prec (FILE *fp); +extern void read_int (FILE *fp, int *n, const char *name); +extern size_t read_string (FILE *fp, char **buffer_ptr, + size_t buffer_length, const char *name); +extern void read_mpfr (FILE *fp, mpfr_ptr x, int *known_sign); +extern void read_mpc (FILE *fp, mpc_ptr z, known_signs_t *ks); + +void set_mpfr_flags (int counter); +void check_mpfr_flags (int counter); + +/* + function descriptions +*/ + +/* type for return, output and input parameters */ +typedef enum { + NATIVE_INT, /* int */ + NATIVE_UL, /* unsigned long */ + NATIVE_L, /* signed long */ + NATIVE_D, /* double */ + NATIVE_LD, /* long double */ + NATIVE_DC, /* double _Complex */ + NATIVE_LDC, /* long double _Complex */ + NATIVE_IM, /* intmax_t */ + NATIVE_UIM, /* uintmax_t */ + NATIVE_STRING, /* char* */ + GMP_Z, /* mpz_t */ + GMP_Q, /* mpq_t */ + GMP_F, /* mpf_t */ + MPFR_INEX, /* mpfr_inex */ + MPFR, /* mpfr_t */ + MPFR_RND, /* mpfr_rnd_t */ + MPC_INEX, /* mpc_inex */ + MPC, /* mpc_t */ + MPC_RND /* mpc_rnd_t */ +} mpc_param_t; + +/* additional information for checking mpfr_t result */ +typedef struct { + mpfr_t mpfr; /* skip space for the variable */ + int known_sign; +} mpfr_data_t; #define TERNARY_NOT_CHECKED 255 - /* special value to indicate that the ternary value is not checked */ +/* special value to indicate that the ternary value is not checked */ #define TERNARY_ERROR 254 - /* special value to indicate that an error occurred in an mpc function */ +/* special value to indicate that an error occurred in an mpc function */ + +/* mpc nonary value as a pair of ternary value for data from a file */ +typedef struct { + int real; + int imag; +} mpc_inex_data_t; + +/* additional information for checking mpc_t result */ +typedef struct { + mpc_t mpc; /* skip space */ + int known_sign_real; + int known_sign_imag; +} mpc_data_t; + +/* string buffer information */ +typedef struct { + char* string; /* skip space */ + int length; +} string_info_t; + +/* abstract parameter type + + Let consider an abstract parameter p, which is declared as follows: + mpc_operand_t p; + we use the fact that a mpfr_t (respectively mpc_t) value can be accessed as + 'p.mpfr' (resp. 'p.mpc') as well as 'p.mpfr_info.mpfr' + (resp. 'p.mpc_info.mpc'), the latter form permitting access to the + 'known_sign' field(s). + Similarly, if the abstract parameter represent a string variable, we can + access its value with 'p.string' or 'p.string_info.string' and its size + with 'p.string_info.length'. + + The user uses the simple form when adding a test, the second form is used by the + test suite itself when reading reference data and checking result against them. +*/ +typedef union { + int i; + unsigned long ui; + signed long si; + double d; + long double ld; +#ifdef _MPC_H_HAVE_INTMAX_T + intmax_t im; + uintmax_t uim; +#endif +#ifdef _Complex_I + double _Complex dc; + long double _Complex ldc; +#endif + char * string; + string_info_t string_info; + mpz_t mpz; + mpq_t mpq; + mpf_t mpf; + mpfr_t mpfr; + mpfr_data_t mpfr_data; + mpfr_rnd_t mpfr_rnd; + int mpfr_inex; + mpc_t mpc; + mpc_data_t mpc_data; + mpc_rnd_t mpc_rnd; + int mpc_inex; + mpc_inex_data_t mpc_inex_data; +} mpc_operand_t; + +#define PARAMETER_ARRAY_SIZE 10 + +/* function name plus parameters */ +typedef struct { + char *name; /* name of the function */ + int nbout; /* number of output parameters */ + int nbin; /* number of input parameters */ + mpc_operand_t P[PARAMETER_ARRAY_SIZE]; /* value of parameters */ + mpc_param_t T[PARAMETER_ARRAY_SIZE]; /* type of parameters */ +} mpc_fun_param_t; + + +void read_description (mpc_fun_param_t* param, const char *file); +const char* read_description_findname (mpc_param_t e); + +/* file functions */ +typedef struct { + char *pathname; + FILE *fd; + unsigned long line_number; + unsigned long test_line_number; + int nextchar; +} mpc_datafile_context_t; + +void open_datafile (mpc_datafile_context_t* datafile_context, + const char * data_filename); +void close_datafile (mpc_datafile_context_t *dc); + +/* data file functions */ +void read_line (mpc_datafile_context_t* datafile_context, + mpc_fun_param_t* params); +void check_data (mpc_datafile_context_t* datafile_context, + mpc_fun_param_t* params, + int index_reused_operand); + +/* parameters templated functions */ +int data_check_template (const char* descr_file, const char * data_file); + +void init_parameters (mpc_fun_param_t *params); +void clear_parameters (mpc_fun_param_t *params); +void print_parameter (mpc_fun_param_t *params, int index); +int copy_parameter (mpc_fun_param_t *params, + int index_dest, int index_src); + +void tpl_read_int (mpc_datafile_context_t* datafile_context, + int *nread, const char *name); +void tpl_read_ui (mpc_datafile_context_t* datafile_context, + unsigned long int *ui); +void tpl_read_si (mpc_datafile_context_t* datafile_context, + long int *si); +void tpl_read_mpz (mpc_datafile_context_t* datafile_context, + mpz_t z); +void tpl_skip_whitespace_comments (mpc_datafile_context_t* datafile_context); +void tpl_read_ternary (mpc_datafile_context_t* datafile_context, + int* ternary); +void tpl_read_mpfr (mpc_datafile_context_t* datafile_context, + mpfr_ptr x, int* known_sign); +void tpl_read_mpfr_rnd (mpc_datafile_context_t* datafile_context, + mpfr_rnd_t* rnd); +void tpl_read_mpfr_inex (mpc_datafile_context_t* datafile_context, + int *ternary); +void tpl_read_mpc_inex (mpc_datafile_context_t* datafile_context, + mpc_inex_data_t* ternarypair); +void tpl_read_mpc (mpc_datafile_context_t* datafile_context, + mpc_data_t* z); +void tpl_read_mpc_rnd (mpc_datafile_context_t* datafile_context, + mpc_rnd_t* rnd); + +int tpl_same_mpz_value (mpz_ptr n1, mpz_ptr n2); +int tpl_same_mpfr_value (mpfr_ptr x1, mpfr_ptr x2, int known_sign); +int tpl_check_mpfr_data (mpfr_t got, mpfr_data_t expected); +int tpl_check_mpc_data (mpc_ptr got, mpc_data_t expected); + +void tpl_copy_int (int *dest, const int * const src); +void tpl_copy_ui (unsigned long int *dest, + const unsigned long int * const src); +void tpl_copy_si (long int *dest, const long int * const src); +void tpl_copy_d (double *dest, const double * const src); +void tpl_copy_mpz (mpz_ptr dest, mpz_srcptr src); +void tpl_copy_mpfr (mpfr_ptr dest, mpfr_srcptr src); +void tpl_copy_mpc (mpc_ptr dest, mpc_srcptr src); + +int double_rounding (mpc_fun_param_t *params); + +/* iterating over rounding modes */ +void first_rnd_mode (mpc_fun_param_t *params); +int is_valid_rnd_mode (mpc_fun_param_t *params); +void next_rnd_mode (mpc_fun_param_t *params); + +/* parameter precision */ +void set_output_precision (mpc_fun_param_t *params, mpfr_prec_t prec); +void set_input_precision (mpc_fun_param_t *params, mpfr_prec_t prec); +void set_reference_precision (mpc_fun_param_t *params, mpfr_prec_t prec); #endif /* __MPC_TESTS_H */ diff --git a/tests/mpfr_flags.c b/tests/mpfr_flags.c new file mode 100644 index 0000000..1f82063 --- /dev/null +++ b/tests/mpfr_flags.c @@ -0,0 +1,115 @@ +/* random.c -- Handle seed for random numbers. + +Copyright (C) 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +/* set MPFR flags to random values */ +void +set_mpfr_flags (int counter) +{ + if (counter & 1) + mpfr_set_underflow (); + else + mpfr_clear_underflow (); + if (counter & 2) + mpfr_set_overflow (); + else + mpfr_clear_overflow (); + /* the divide-by-0 flag was added in MPFR 3.1.0 */ +#ifdef mpfr_set_divby0 + if (counter & 4) + mpfr_set_divby0 (); + else + mpfr_clear_divby0 (); +#endif + if (counter & 8) + mpfr_set_nanflag (); + else + mpfr_clear_nanflag (); + if (counter & 16) + mpfr_set_inexflag (); + else + mpfr_clear_inexflag (); + if (counter & 32) + mpfr_set_erangeflag (); + else + mpfr_clear_erangeflag (); +} + +/* Check MPFR flags: we allow that some flags are set internally by MPC, + for example if MPC does internal computations (using MPFR) which yield + an overflow, even if the final MPC result fits in the exponent range. + However we don't allow MPC to *clear* the MPFR flags */ +void +check_mpfr_flags (int counter) +{ + int old, neu; + + old = (counter & 1) != 0; + neu = mpfr_underflow_p () != 0; + if (old && (neu == 0)) + { + printf ("Error, underflow flag has been modified from %d to %d\n", + old, neu); + exit (1); + } + old = (counter & 2) != 0; + neu = mpfr_overflow_p () != 0; + if (old && (neu == 0)) + { + printf ("Error, overflow flag has been modified from %d to %d\n", + old, neu); + exit (1); + } +#ifdef mpfr_divby0_p + old = (counter & 4) != 0; + neu = mpfr_divby0_p () != 0; + if (old && (neu == 0)) + { + printf ("Error, divby0 flag has been modified from %d to %d\n", + old, neu); + exit (1); + } +#endif + old = (counter & 8) != 0; + neu = mpfr_nanflag_p () != 0; + if (old && (neu == 0)) + { + printf ("Error, nanflag flag has been modified from %d to %d\n", + old, neu); + exit (1); + } + old = (counter & 16) != 0; + neu = mpfr_inexflag_p () != 0; + if (old && (neu == 0)) + { + printf ("Error, inexflag flag has been modified from %d to %d\n", + old, neu); + exit (1); + } + old = (counter & 32) != 0; + neu = mpfr_erangeflag_p () != 0; + if (old && (neu == 0)) + { + printf ("Error, erangeflag flag has been modified from %d to %d\n", + old, neu); + exit (1); + } +} diff --git a/tests/mul.dsc b/tests/mul.dsc new file mode 100644 index 0000000..78dc659 --- /dev/null +++ b/tests/mul.dsc @@ -0,0 +1,30 @@ +# Description file for mpc_mul +# +# Copyright (C) 2012, INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_mul +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_srcptr + mpc_rnd_t diff --git a/tests/mul_2si.dsc b/tests/mul_2si.dsc new file mode 100644 index 0000000..f5dc7ce --- /dev/null +++ b/tests/mul_2si.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_mul_2si +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_mul_2si +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + unsigned long int + mpc_rnd_t diff --git a/tests/mul_2ui.dsc b/tests/mul_2ui.dsc new file mode 100644 index 0000000..95774b4 --- /dev/null +++ b/tests/mul_2ui.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_mul_2ui +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_mul_2ui +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + unsigned long int + mpc_rnd_t diff --git a/tests/mul_fr.dsc b/tests/mul_fr.dsc new file mode 100644 index 0000000..27de3f9 --- /dev/null +++ b/tests/mul_fr.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_mul_fr +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_mul_fr +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpfr_srcptr + mpc_rnd_t diff --git a/tests/mul_i.dsc b/tests/mul_i.dsc new file mode 100644 index 0000000..628cd1d --- /dev/null +++ b/tests/mul_i.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_mul_i +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_mul_i +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + int + mpc_rnd_t diff --git a/tests/mul_si.dsc b/tests/mul_si.dsc new file mode 100644 index 0000000..3d653c3 --- /dev/null +++ b/tests/mul_si.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_mul_si +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_mul_si +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + unsigned long int + mpc_rnd_t diff --git a/tests/mul_ui.dsc b/tests/mul_ui.dsc new file mode 100644 index 0000000..e272149 --- /dev/null +++ b/tests/mul_ui.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_mul_ui +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_mul_ui +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + unsigned long int + mpc_rnd_t diff --git a/tests/neg.dsc b/tests/neg.dsc new file mode 100644 index 0000000..f7cdae1 --- /dev/null +++ b/tests/neg.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_neg +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_neg +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/norm.dsc b/tests/norm.dsc new file mode 100644 index 0000000..373a8d3 --- /dev/null +++ b/tests/norm.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_norm +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_norm +RETURN: + mpfr_inex +OUTPUT: + mpfr_ptr +INPUT: + mpc_srcptr + mpfr_rnd_t diff --git a/tests/open_datafile.c b/tests/open_datafile.c new file mode 100644 index 0000000..71ca91a --- /dev/null +++ b/tests/open_datafile.c @@ -0,0 +1,57 @@ +/* open_datafile.c -- Set up datafile context. + + Usage: Before including this template file in your source file, + #define the prototype of the function under test in the CALL + symbol, see tadd_tmpl.c for an example. + +Copyright (C) 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include +#include "mpc-tests.h" + +void +open_datafile (mpc_datafile_context_t* datafile_context, + const char * data_filename) +{ + char *src_dir; + char default_srcdir[] = "."; + + src_dir = getenv ("srcdir"); + if (src_dir == NULL) + src_dir = default_srcdir; + + datafile_context->pathname = + (char *) malloc ((strlen (src_dir)) + strlen (data_filename) + 2); + if (datafile_context->pathname == NULL) + { + fprintf (stderr, "Cannot allocate memory\n"); + exit (1); + } + sprintf (datafile_context->pathname, "%s/%s", src_dir, data_filename); + datafile_context->fd = fopen (datafile_context->pathname, "r"); + if (datafile_context->fd == NULL) + { + fprintf (stderr, "Unable to open %s\n", datafile_context->pathname); + exit (1); + } + + datafile_context->line_number = 1; + datafile_context->nextchar = getc (datafile_context->fd); + tpl_skip_whitespace_comments (datafile_context); +} diff --git a/tests/pow.dsc b/tests/pow.dsc new file mode 100644 index 0000000..1a4afac --- /dev/null +++ b/tests/pow.dsc @@ -0,0 +1,30 @@ +# Description file for mpc_pow +# +# Copyright (C) 2012 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_pow +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_srcptr + mpc_rnd_t diff --git a/tests/pow_d.dsc b/tests/pow_d.dsc new file mode 100644 index 0000000..cb04e98 --- /dev/null +++ b/tests/pow_d.dsc @@ -0,0 +1,30 @@ +# Description file for mpc_pow_d +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_pow_d +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + double + mpc_rnd_t diff --git a/tests/pow_fr.dsc b/tests/pow_fr.dsc new file mode 100644 index 0000000..a21f756 --- /dev/null +++ b/tests/pow_fr.dsc @@ -0,0 +1,30 @@ +# Description file for mpc_pow_fr +# +# Copyright (C) 2012 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_pow_fr +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpfr_srcptr + mpc_rnd_t diff --git a/tests/pow_si.dsc b/tests/pow_si.dsc new file mode 100644 index 0000000..7d9a1f0 --- /dev/null +++ b/tests/pow_si.dsc @@ -0,0 +1,31 @@ +# Description file for mpc_pow_si +# +# Copyright (C) 2008, 2010, 2011, 2012 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_pow_si +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + long int + mpc_rnd_t + \ No newline at end of file diff --git a/tests/pow_ui.dsc b/tests/pow_ui.dsc new file mode 100644 index 0000000..5b2c281 --- /dev/null +++ b/tests/pow_ui.dsc @@ -0,0 +1,31 @@ +# Description file for mpc_pow_ui +# +# Copyright (C) 2008, 2010, 2011, 2012, INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_pow_ui +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + unsigned long int + mpc_rnd_t + \ No newline at end of file diff --git a/tests/pow_z.dat b/tests/pow_z.dat new file mode 100644 index 0000000..873bf43 --- /dev/null +++ b/tests/pow_z.dat @@ -0,0 +1,51 @@ +# Data file for mpc_pow_z. +# +# Copyright (C) 2012 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# The line format respects the parameter order in function prototype as +# follow: +# +# INEX_RE INEX_IM PREC_ROP_RE ROP_RE PREC_ROP_IM ROP_IM PREC_OP1_RE OP1_RE PREC_OP1_IM OP1_IM OP2 RND_RE RND_IM +# +# where op1 = op1_re + i * op1_im, rop = rop_re + i * rop_im, +# The data are read from the file and stored in variables op1, op2, rop using +# rounding to nearest when needed, for instance: rop_re is ROP_RE rounded to +# nearest to the precision of PREC_ROP_RE. +# ROP_RE is checked against Re(op1^op2) rounded to the precision PREC_ROP_RE +# in the direction RND_RE +# ROP_IM is checked against Im(op1^op2) rounded to the precision PREC_ROP_IM +# in the direction RND_IM +# INEX_RE is the ternary value for the real part with the following notation: +# "?" ternary value not checked +# "+" if ROP_RE is greater than the exact mathematical result +# "0" if ROP_RE is exactly the mathematical result +# "-" if ROP_RE is less than the exact mathematical result +# (m.m. INEX_IM) +# rounding modes notation: +# "N" is rounding to nearest +# "Z" is rounding towards zero +# "U" is rounding towards plus infinity +# "D" is rounding towards minus infinity +# Use prefixes "0b" for values in base two, "0x" for values in base sixteen, +# no prefix for value in base ten. +# In all bases, "nan" is NaN, "inf" is infinity; +# The sign of the result is checked with "+inf", "-inf", "-0", or "+0". + +0 0 5 17 5 42 5 17 5 42 1 N N +0 0 5 0.5 5 -0.5 5 1 5 1 -1 N N +0 0 5 1 5 0 5 0 5 1 0x8000000000000000 N N diff --git a/tests/pow_z.dsc b/tests/pow_z.dsc new file mode 100644 index 0000000..7730921 --- /dev/null +++ b/tests/pow_z.dsc @@ -0,0 +1,30 @@ +# Description file for mpc_pow_z +# +# Copyright (C) 2012 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_pow_fr +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpz_srcptr + mpc_rnd_t diff --git a/tests/print_parameter.c b/tests/print_parameter.c new file mode 100644 index 0000000..7d59309 --- /dev/null +++ b/tests/print_parameter.c @@ -0,0 +1,107 @@ +/* print_parameter.c -- Helper function for parameter printing. + +Copyright (C) 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +static const char *mpfr_rnd_mode [] = + { "MPFR_RNDN", "MPFR_RNDZ", "MPFR_RNDU", "MPFR_RNDD" }; + +extern const char *mpc_rnd_mode[]; + +#define MPFR_INEX_STR(inex) \ + (inex) == TERNARY_NOT_CHECKED ? "?" \ + : (inex) == +1 ? "+1" \ + : (inex) == -1 ? "-1" : "0" + +void +print_parameter (mpc_fun_param_t* params, int index) +{ + switch (params->T[index]) + { + case NATIVE_INT: + printf ("= %d\n", params->P[index].i); + break; + + case NATIVE_UL: + printf ("= %lu\n", params->P[index].ui); + break; + + case NATIVE_L: + printf ("= %ld\n", params->P[index].si); + break; + + case NATIVE_D: + printf ("= %e\n", params->P[index].d); + break; + + case GMP_Z: + gmp_printf ("= %Zd\n", params->P[index].mpz); + break; + case GMP_Q: + gmp_printf ("= %Qd\n", params->P[index].mpq); + break; + case GMP_F: + gmp_printf ("= %Fe\n", params->P[index].mpf); + break; + + case MPFR_INEX: + printf (" ternary value = %s\n", + MPFR_INEX_STR (params->P[index].mpfr_inex)); + break; + + case MPFR: + printf ("[%lu]=", + (unsigned long int) mpfr_get_prec (params->P[index].mpfr)); + mpfr_out_str (stdout, 2, 0, params->P[index].mpfr, GMP_RNDN); + printf ("\n"); + break; + + case MPC_INEX: + if (index >= params->nbout + params->nbin) + printf (" ternary value = (%s, %s)\n", + MPFR_INEX_STR (params->P[index].mpc_inex_data.real), + MPFR_INEX_STR (params->P[index].mpc_inex_data.imag)); + else + printf (" ternary value = %s\n", MPC_INEX_STR (params->P[index].mpc_inex)); + break; + + case MPC: + printf ("[%lu,%lu]=", + (unsigned long int) MPC_PREC_RE (params->P[index].mpc), + (unsigned long int) MPC_PREC_IM (params->P[index].mpc)); + mpc_out_str (stdout, 2, 0, params->P[index].mpc, MPC_RNDNN); + printf ("\n"); + break; + + case MPFR_RND: + printf ("(rounding mode): %s\n", + mpfr_rnd_mode[params->P[index].mpfr_rnd]); + break; + + case MPC_RND: + printf ("(rounding mode): %s\n", + mpc_rnd_mode[params->P[index].mpc_rnd]); + break; + + default: + fprintf (stderr, "print_parameter: unsupported type.\n"); + exit (1); + } +} diff --git a/tests/proj.dsc b/tests/proj.dsc new file mode 100644 index 0000000..d9b45f3 --- /dev/null +++ b/tests/proj.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_proj +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_proj +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/random.c b/tests/random.c index 0730fee..89da546 100644 --- a/tests/random.c +++ b/tests/random.c @@ -158,3 +158,114 @@ test_default_random (mpc_ptr z, mpfr_exp_t emin, mpfr_exp_t emax, if (((r>>8) & 0xFF) < negative_probability) mpfr_neg (mpc_imagref (z), mpc_imagref (z), MPFR_RNDN); } + +/* Set n to a non zero value random value with absolute values less than + 2^emax. + + n is negative with probability equal to NEGATIVE_PROBABILITY / 256. +*/ +void test_random_si (long int *n, unsigned long emax, + unsigned int negative_probability) +{ + unsigned long r; + + if (!rands_initialized) + { + fprintf (stderr, + "Put test_start at the beginning of your test function.\n"); + exit (1); + } + + do + { + *n = gmp_urandomb_ui (rands, emax); + } while (*n == 0); + + if (negative_probability > 256) + negative_probability = 256; + r = gmp_urandomb_ui (rands, 8); + if ((r & 0xFF) < negative_probability) + *n = -(*n); +} + +/* Set x to a non zero value random value with absolute values greater than + or equal to 2^{emin-1} and less than 2^emax. + + x is negative with probability equal to NEGATIVE_PROBABILITY / 256. +*/ +void +test_random_mpfr (mpfr_ptr x, mpfr_exp_t emin, mpfr_exp_t emax, + unsigned int negative_probability) +{ + const unsigned long range = (unsigned long int) (emax - emin) + 1; + unsigned long r; + + if (!rands_initialized) + { + fprintf (stderr, + "Put test_start at the beginning of your test function.\n"); + exit (1); + } + + do + { + mpfr_urandom (x, rands, MPFR_RNDN); + } while (mpfr_zero_p (x)); + + mpfr_set_exp (x, (mpfr_exp_t) gmp_urandomm_ui (rands, range) + emin); + if (negative_probability > 256) + negative_probability = 256; + r = gmp_urandomb_ui (rands, 8); + if ((r & 0xFF) < negative_probability) + mpfr_neg (x, x, MPFR_RNDN); +} + +/* Set x to a non zero value random value. + x is negative with probability equal to NEGATIVE_PROBABILITY / 256. +*/ +void +test_random_d (double *x, unsigned int negative_probability) +{ + MPFR_DECL_INIT (mpfr_x, 53); + test_random_mpfr (mpfr_x, -1022, 1022, negative_probability); + *x = mpfr_get_d (mpfr_x, MPFR_RNDN); +} + +/* Set z to a non zero value random value with absolute values of Re(z) and + Im(z) greater than or equal to 2^{emin-1} and less than 2^emax. + + Each part is negative with probability equal to NEGATIVE_PROBABILITY / 256. +*/ +void +test_random_mpc (mpc_ptr z, mpfr_exp_t emin, mpfr_exp_t emax, + unsigned int negative_probability) +{ + const unsigned long range = (unsigned long int) (emax - emin) + 1; + unsigned long r; + + if (!rands_initialized) + { + fprintf (stderr, + "Put test_start at the beginning of your test function.\n"); + exit (1); + } + + do + { + mpc_urandom (z, rands); + } while (mpfr_zero_p (mpc_realref (z)) || mpfr_zero_p (mpc_imagref (z))); + + mpfr_set_exp (mpc_realref (z), + (mpfr_exp_t) gmp_urandomm_ui (rands, range) + emin); + + mpfr_set_exp (mpc_imagref (z), + (mpfr_exp_t) gmp_urandomm_ui (rands, range) + emin); + + if (negative_probability > 256) + negative_probability = 256; + r = gmp_urandomb_ui (rands, 16); + if ((r & 0xFF) < negative_probability) + mpfr_neg (mpc_realref (z), mpc_realref (z), MPFR_RNDN); + if (((r>>8) & 0xFF) < negative_probability) + mpfr_neg (mpc_imagref (z), mpc_imagref (z), MPFR_RNDN); +} diff --git a/tests/read_data.c b/tests/read_data.c index c1cf677..039c5a5 100644 --- a/tests/read_data.c +++ b/tests/read_data.c @@ -1,4 +1,4 @@ -/* read_data,c -- Read data file and check function. +/* read_data.c -- Read data file and check function. Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA @@ -40,10 +40,7 @@ int nextchar; : (inex) == +1 ? "+1" \ : (inex) == -1 ? "-1" : "0" -static const char *mpfr_rnd_mode [] = - { "MPFR_RNDN", "MPFR_RNDZ", "MPFR_RNDU", "MPFR_RNDD" }; - -const char *rnd_mode[] = +const char *mpc_rnd_mode[] = { "MPC_RNDNN", "MPC_RNDZN", "MPC_RNDUN", "MPC_RNDDN", "undefined", "undefined", "undefined", "undefined", "undefined", "undefined", "undefined", "undefined", "undefined", "undefined", @@ -138,7 +135,6 @@ skip_whitespace_comments (FILE *fp) } } - size_t read_string (FILE *fp, char **buffer_ptr, size_t buffer_length, const char *name) { @@ -298,54 +294,6 @@ read_int (FILE *fp, int *nread, const char *name) skip_whitespace_comments (fp); } -static void -read_uint (FILE *fp, unsigned long int *ui) -{ - int n = 0; - - if (nextchar == EOF) - { - printf ("Error: Unexpected EOF when reading uint " - "in file '%s' line %lu\n", - pathname, line_number); - exit (1); - } - ungetc (nextchar, fp); - n = fscanf (fp, "%lu", ui); - if (ferror (fp) || n == 0 || n == EOF) - { - printf ("Error: Cannot read uint in file '%s' line %lu\n", - pathname, line_number); - exit (1); - } - nextchar = getc (fp); - skip_whitespace_comments (fp); -} - -static void -read_sint (FILE *fp, long int *si) -{ - int n = 0; - - if (nextchar == EOF) - { - printf ("Error: Unexpected EOF when reading sint " - "in file '%s' line %lu\n", - pathname, line_number); - exit (1); - } - ungetc (nextchar, fp); - n = fscanf (fp, "%li", si); - if (ferror (fp) || n == 0 || n == EOF) - { - printf ("Error: Cannot read sint in file '%s' line %lu\n", - pathname, line_number); - exit (1); - } - nextchar = getc (fp); - skip_whitespace_comments (fp); -} - mpfr_prec_t read_mpfr_prec (FILE *fp) { @@ -415,645 +363,3 @@ read_mpc (FILE *fp, mpc_ptr z, known_signs_t *ks) read_mpfr (fp, mpc_realref (z), ks == NULL ? NULL : &ks->re); read_mpfr (fp, mpc_imagref (z), ks == NULL ? NULL : &ks->im); } - -static void -check_compatible (int inex, mpfr_t expected, mpfr_rnd_t rnd, const char *s) -{ - if ((rnd == MPFR_RNDU && inex == -1) || - (rnd == MPFR_RNDD && inex == +1) || - (rnd == MPFR_RNDZ && !mpfr_signbit (expected) && inex == +1) || - (rnd == MPFR_RNDZ && mpfr_signbit (expected) && inex == -1)) - { - if (s != NULL) - printf ("Incompatible ternary value '%c' (%s part) in file '%s' line %lu\n", - (inex == 1) ? '+' : '-', s, pathname, test_line_number); - else - printf ("Incompatible ternary value '%c' in file '%s' line %lu\n", - (inex == 1) ? '+' : '-', pathname, test_line_number); - } -} - -/* read lines of data */ -static void -read_cc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, - known_signs_t *signs, mpc_ptr op, mpc_rnd_t *rnd) -{ - test_line_number = line_number; - read_ternary (fp, inex_re); - read_ternary (fp, inex_im); - read_mpc (fp, expected, signs); - read_mpc (fp, op, NULL); - read_mpc_rounding_mode (fp, rnd); - check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); - check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); -} - -static void -read_fc (FILE *fp, int *inex, mpfr_ptr expected, int *sign, mpc_ptr op, - mpfr_rnd_t *rnd) -{ - test_line_number = line_number; - read_ternary (fp, inex); - read_mpfr (fp, expected, sign); - read_mpc (fp, op, NULL); - read_mpfr_rounding_mode (fp, rnd); - check_compatible (*inex, expected, *rnd, NULL); -} - -static void -read_ccc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, - known_signs_t *signs, mpc_ptr op1, mpc_ptr op2, mpc_rnd_t *rnd) -{ - test_line_number = line_number; - read_ternary (fp, inex_re); - read_ternary (fp, inex_im); - read_mpc (fp, expected, signs); - read_mpc (fp, op1, NULL); - read_mpc (fp, op2, NULL); - read_mpc_rounding_mode (fp, rnd); - check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); - check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); -} - -/* read lines of data for function with three mpc_t inputs and one mpc_t - output like mpc_fma */ -static void -read_cccc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, - known_signs_t *signs, mpc_ptr op1, mpc_ptr op2, mpc_ptr op3, - mpc_rnd_t *rnd) -{ - test_line_number = line_number; - read_ternary (fp, inex_re); - read_ternary (fp, inex_im); - read_mpc (fp, expected, signs); - read_mpc (fp, op1, NULL); - read_mpc (fp, op2, NULL); - read_mpc (fp, op3, NULL); - read_mpc_rounding_mode (fp, rnd); - check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); - check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); -} - -static void -read_cfc (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, - known_signs_t *signs, mpfr_ptr op1, mpc_ptr op2, mpc_rnd_t *rnd) -{ - test_line_number = line_number; - read_ternary (fp, inex_re); - read_ternary (fp, inex_im); - read_mpc (fp, expected, signs); - read_mpfr (fp, op1, NULL); - read_mpc (fp, op2, NULL); - read_mpc_rounding_mode (fp, rnd); - check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); - check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); -} - -static void -read_ccf (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, - known_signs_t *signs, mpc_ptr op1, mpfr_ptr op2, mpc_rnd_t *rnd) -{ - test_line_number = line_number; - read_ternary (fp, inex_re); - read_ternary (fp, inex_im); - read_mpc (fp, expected, signs); - read_mpc (fp, op1, NULL); - read_mpfr (fp, op2, NULL); - read_mpc_rounding_mode (fp, rnd); - check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); - check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); -} - -static void -read_ccu (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, - known_signs_t *signs, mpc_ptr op1, unsigned long int *op2, mpc_rnd_t *rnd) -{ - test_line_number = line_number; - read_ternary (fp, inex_re); - read_ternary (fp, inex_im); - read_mpc (fp, expected, signs); - read_mpc (fp, op1, NULL); - read_uint (fp, op2); - read_mpc_rounding_mode (fp, rnd); - check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); - check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); -} - -static void -read_ccs (FILE *fp, int *inex_re, int *inex_im, mpc_ptr expected, - known_signs_t *signs, mpc_ptr op1, long int *op2, mpc_rnd_t *rnd) -{ - test_line_number = line_number; - read_ternary (fp, inex_re); - read_ternary (fp, inex_im); - read_mpc (fp, expected, signs); - read_mpc (fp, op1, NULL); - read_sint (fp, op2); - read_mpc_rounding_mode (fp, rnd); - check_compatible (*inex_re, mpc_realref(expected), MPC_RND_RE(*rnd), "real"); - check_compatible (*inex_im, mpc_imagref(expected), MPC_RND_IM(*rnd), "imag"); -} - -/* set MPFR flags to random values */ -static void -set_mpfr_flags (int counter) -{ - if (counter & 1) - mpfr_set_underflow (); - else - mpfr_clear_underflow (); - if (counter & 2) - mpfr_set_overflow (); - else - mpfr_clear_overflow (); - /* the divide-by-0 flag was added in MPFR 3.1.0 */ -#ifdef mpfr_set_divby0 - if (counter & 4) - mpfr_set_divby0 (); - else - mpfr_clear_divby0 (); -#endif - if (counter & 8) - mpfr_set_nanflag (); - else - mpfr_clear_nanflag (); - if (counter & 16) - mpfr_set_inexflag (); - else - mpfr_clear_inexflag (); - if (counter & 32) - mpfr_set_erangeflag (); - else - mpfr_clear_erangeflag (); -} - -/* Check MPFR flags: we allow that some flags are set internally by MPC, - for example if MPC does internal computations (using MPFR) which yield - an overflow, even if the final MPC result fits in the exponent range. - However we don't allow MPC to *clear* the MPFR flags */ -static void -check_mpfr_flags (int counter) -{ - int old, neu; - - old = (counter & 1) != 0; - neu = mpfr_underflow_p () != 0; - if (old && (neu == 0)) - { - printf ("Error, underflow flag has been modified from %d to %d\n", - old, neu); - exit (1); - } - old = (counter & 2) != 0; - neu = mpfr_overflow_p () != 0; - if (old && (neu == 0)) - { - printf ("Error, overflow flag has been modified from %d to %d\n", - old, neu); - exit (1); - } -#ifdef mpfr_divby0_p - old = (counter & 4) != 0; - neu = mpfr_divby0_p () != 0; - if (old && (neu == 0)) - { - printf ("Error, divby0 flag has been modified from %d to %d\n", - old, neu); - exit (1); - } -#endif - old = (counter & 8) != 0; - neu = mpfr_nanflag_p () != 0; - if (old && (neu == 0)) - { - printf ("Error, nanflag flag has been modified from %d to %d\n", - old, neu); - exit (1); - } - old = (counter & 16) != 0; - neu = mpfr_inexflag_p () != 0; - if (old && (neu == 0)) - { - printf ("Error, inexflag flag has been modified from %d to %d\n", - old, neu); - exit (1); - } - old = (counter & 32) != 0; - neu = mpfr_erangeflag_p () != 0; - if (old && (neu == 0)) - { - printf ("Error, erangeflag flag has been modified from %d to %d\n", - old, neu); - exit (1); - } -} - -/* data_check (function, data_file_name) checks function results against - precomputed data in a file.*/ -void -data_check (mpc_function function, const char *file_name) -{ - FILE *fp; - - int inex_re; - mpfr_t x1, x2; - mpfr_rnd_t mpfr_rnd = MPFR_RNDN; - int sign_real; - - int inex_im; - mpc_t z1, z2, z3, z4, z5; - mpc_rnd_t rnd = MPC_RNDNN; - - unsigned long int ui; - long int si; - - known_signs_t signs; - int inex = 0; - - static int rand_counter = 0; - - fp = open_data_file (file_name); - - /* 1. init needed variables */ - mpc_init2 (z1, 2); - switch (function.type) - { - case FC: - mpfr_init (x1); - mpfr_init (x2); - break; - case CC: case CCU: case CCS: - mpc_init2 (z2, 2); - mpc_init2 (z3, 2); - break; - case C_CC: - mpc_init2 (z2, 2); - mpc_init2 (z3, 2); - mpc_init2 (z4, 2); - break; - case CCCC: - mpc_init2 (z2, 2); - mpc_init2 (z3, 2); - mpc_init2 (z4, 2); - mpc_init2 (z5, 2); - break; - case CFC: case CCF: - mpfr_init (x1); - mpc_init2 (z2, 2); - mpc_init2 (z3, 2); - break; - default: - ; - } - - /* 2. read data file */ - line_number = 1; - nextchar = getc (fp); - skip_whitespace_comments (fp); - while (nextchar != EOF) { - set_mpfr_flags (rand_counter); - - /* for each kind of function prototype: */ - /* 3.1 read a line of data: expected result, parameters, rounding mode */ - /* 3.2 compute function at the same precision as the expected result */ - /* 3.3 compare this result with the expected one */ - switch (function.type) - { - case FC: /* example mpc_norm */ - read_fc (fp, &inex_re, x1, &sign_real, z1, &mpfr_rnd); - mpfr_set_prec (x2, mpfr_get_prec (x1)); - inex = function.pointer.FC (x2, z1, mpfr_rnd); - if ((inex_re != TERNARY_NOT_CHECKED && inex_re != inex) - || !same_mpfr_value (x1, x2, sign_real)) - { - mpfr_t got, expected; - mpc_t op; - op[0] = z1[0]; - got[0] = x2[0]; - expected[0] = x1[0]; - printf ("%s(op) failed (%s:%lu)\nwith rounding mode %s\n", - function.name, file_name, test_line_number, - mpfr_rnd_mode[mpfr_rnd]); - if (inex_re != TERNARY_NOT_CHECKED && inex_re != inex) - printf("ternary value: got %s, expected %s\n", - MPFR_INEX_STR (inex), MPFR_INEX_STR (inex_re)); - MPC_OUT (op); - printf (" "); - MPFR_OUT (got); - MPFR_OUT (expected); - - exit (1); - } - break; - - case CC: /* example mpc_log */ - read_cc (fp, &inex_re, &inex_im, z1, &signs, z2, &rnd); - mpfr_set_prec (mpc_realref (z3), MPC_PREC_RE (z1)); - mpfr_set_prec (mpc_imagref (z3), MPC_PREC_IM (z1)); - inex = function.pointer.CC (z3, z2, rnd); - if (!MPC_INEX_CMP (inex_re, inex_im, inex) - || !same_mpc_value (z3, z1, signs)) - { - mpc_t op, got, expected; /* display sensible variable names */ - op[0] = z2[0]; - expected[0]= z1[0]; - got[0] = z3[0]; - printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", - function.name, test_line_number, rnd_mode[rnd]); - if (!MPC_INEX_CMP (inex_re, inex_im, inex)) - printf("ternary value: got %s, expected (%s, %s)\n", - MPC_INEX_STR (inex), - MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); - MPC_OUT (op); - printf (" "); - MPC_OUT (got); - MPC_OUT (expected); - - exit (1); - } - break; - - case C_CC: /* example mpc_mul */ - read_ccc (fp, &inex_re, &inex_im, z1, &signs, z2, z3, &rnd); - mpfr_set_prec (mpc_realref(z4), MPC_PREC_RE (z1)); - mpfr_set_prec (mpc_imagref(z4), MPC_PREC_IM (z1)); - inex = function.pointer.C_CC (z4, z2, z3, rnd); - if (!MPC_INEX_CMP (inex_re, inex_im, inex) - || !same_mpc_value (z4, z1, signs)) - { - /* display sensible variable names */ - mpc_t op1, op2, got, expected; - op1[0] = z2[0]; - op2[0] = z3[0]; - expected[0]= z1[0]; - got[0] = z4[0]; - printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", - function.name, test_line_number, rnd_mode[rnd]); - if (!MPC_INEX_CMP (inex_re, inex_im, inex)) - printf("ternary value: got %s, expected (%s, %s)\n", - MPC_INEX_STR (inex), - MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); - MPC_OUT (op1); - MPC_OUT (op2); - printf (" "); - MPC_OUT (got); - MPC_OUT (expected); - - exit (1); - } - if (function.properties & FUNC_PROP_SYMETRIC) - { - inex = function.pointer.C_CC (z4, z3, z2, rnd); - if (!MPC_INEX_CMP (inex_re, inex_im, inex) - || !same_mpc_value (z4, z1, signs)) - { - /* display sensible variable names */ - mpc_t op1, op2, got, expected; - op1[0] = z3[0]; - op2[0] = z2[0]; - expected[0]= z1[0]; - got[0] = z4[0]; - printf ("%s(op) failed (line %lu/symetric test)\n" - "with rounding mode %s\n", - function.name, test_line_number, rnd_mode[rnd]); - if (!MPC_INEX_CMP (inex_re, inex_im, inex)) - printf("ternary value: got %s, expected (%s, %s)\n", - MPC_INEX_STR (inex), - MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); - MPC_OUT (op1); - MPC_OUT (op2); - printf (" "); - MPC_OUT (got); - MPC_OUT (expected); - - exit (1); - } - } - break; - - case CCCC: /* example mpc_fma */ - read_cccc (fp, &inex_re, &inex_im, z1, &signs, z2, z3, z4, &rnd); - /* z1 is the expected value, z2, z3, z4 are the inputs, and z5 is - the computed value */ - mpfr_set_prec (mpc_realref(z5), MPC_PREC_RE (z1)); - mpfr_set_prec (mpc_imagref(z5), MPC_PREC_IM (z1)); - inex = function.pointer.CCCC (z5, z2, z3, z4, rnd); - if (!MPC_INEX_CMP (inex_re, inex_im, inex) - || !same_mpc_value (z5, z1, signs)) - { - /* display sensible variable names */ - mpc_t op1, op2, op3, got, expected; - op1[0] = z2[0]; - op2[0] = z3[0]; - op3[0] = z4[0]; - expected[0]= z1[0]; - got[0] = z5[0]; - printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", - function.name, test_line_number, rnd_mode[rnd]); - if (!MPC_INEX_CMP (inex_re, inex_im, inex)) - printf("ternary value: got %s, expected (%s, %s)\n", - MPC_INEX_STR (inex), - MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); - MPC_OUT (op1); - MPC_OUT (op2); - MPC_OUT (op3); - printf (" "); - MPC_OUT (got); - MPC_OUT (expected); - - exit (1); - } - if (function.properties & FUNC_PROP_SYMETRIC) - { - inex = function.pointer.CCCC (z5, z3, z2, z4, rnd); - if (!MPC_INEX_CMP (inex_re, inex_im, inex) - || !same_mpc_value (z5, z1, signs)) - { - /* display sensible variable names */ - mpc_t op1, op2, op3, got, expected; - op1[0] = z3[0]; - op2[0] = z2[0]; - op3[0] = z4[0]; - expected[0]= z1[0]; - got[0] = z5[0]; - printf ("%s(op) failed (line %lu/symetric test)\n" - "with rounding mode %s\n", - function.name, test_line_number, rnd_mode[rnd]); - if (!MPC_INEX_CMP (inex_re, inex_im, inex)) - printf("ternary value: got %s, expected (%s, %s)\n", - MPC_INEX_STR (inex), - MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); - MPC_OUT (op1); - MPC_OUT (op2); - MPC_OUT (op3); - printf (" "); - MPC_OUT (got); - MPC_OUT (expected); - - exit (1); - } - } - break; - - case CFC: /* example mpc_fr_div */ - read_cfc (fp, &inex_re, &inex_im, z1, &signs, x1, z2, &rnd); - mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1)); - mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1)); - inex = function.pointer.CFC (z3, x1, z2, rnd); - if (!MPC_INEX_CMP (inex_re, inex_im, inex) - || !same_mpc_value (z3, z1, signs)) - { - /* display sensible variable names */ - mpc_t op2, got, expected; - mpfr_t op1; - op1[0] = x1[0]; - op2[0] = z2[0]; - expected[0]= z1[0]; - got[0] = z3[0]; - printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", - function.name, test_line_number, rnd_mode[rnd]); - if (!MPC_INEX_CMP (inex_re, inex_im, inex)) - printf("ternary value: got %s, expected (%s, %s)\n", - MPC_INEX_STR (inex), - MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); - MPFR_OUT (op1); - MPC_OUT (op2); - printf (" "); - MPC_OUT (got); - MPC_OUT (expected); - - exit (1); - } - break; - - case CCF: /* example mpc_mul_fr */ - read_ccf (fp, &inex_re, &inex_im, z1, &signs, z2, x1, &rnd); - mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1)); - mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1)); - inex = function.pointer.CCF (z3, z2, x1, rnd); - if (!MPC_INEX_CMP (inex_re, inex_im, inex) - || !same_mpc_value (z3, z1, signs)) - { - /* display sensible variable names */ - mpc_t op1, got, expected; - mpfr_t op2; - op1[0] = z2[0]; - op2[0] = x1[0]; - expected[0]= z1[0]; - got[0] = z3[0]; - printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", - function.name, test_line_number, rnd_mode[rnd]); - if (!MPC_INEX_CMP (inex_re, inex_im, inex)) - printf("ternary value: got %s, expected (%s, %s)\n", - MPC_INEX_STR (inex), - MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); - MPC_OUT (op1); - MPFR_OUT (op2); - printf (" "); - MPC_OUT (got); - MPC_OUT (expected); - - exit (1); - } - break; - - case CCU: /* example mpc_pow_ui */ - read_ccu (fp, &inex_re, &inex_im, z1, &signs, z2, &ui, &rnd); - mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1)); - mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1)); - inex = function.pointer.CCU (z3, z2, ui, rnd); - if (!MPC_INEX_CMP (inex_re, inex_im, inex) - || !same_mpc_value (z3, z1, signs)) - { - /* display sensible variable names */ - mpc_t op1, got, expected; - op1[0] = z2[0]; - expected[0]= z1[0]; - got[0] = z3[0]; - printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", - function.name, test_line_number, rnd_mode[rnd]); - if (!MPC_INEX_CMP (inex_re, inex_im, inex)) - printf("ternary value: got %s, expected (%s, %s)\n", - MPC_INEX_STR (inex), - MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); - MPC_OUT (op1); - printf ("op2 %lu\n ", ui); - MPC_OUT (got); - MPC_OUT (expected); - - exit (1); - } - break; - - case CCS: /* example mpc_pow_si */ - read_ccs (fp, &inex_re, &inex_im, z1, &signs, z2, &si, &rnd); - mpfr_set_prec (mpc_realref(z3), MPC_PREC_RE (z1)); - mpfr_set_prec (mpc_imagref(z3), MPC_PREC_IM (z1)); - inex = function.pointer.CCS (z3, z2, si, rnd); - if (!MPC_INEX_CMP (inex_re, inex_im, inex) - || !same_mpc_value (z3, z1, signs)) - { - /* display sensible variable names */ - mpc_t op1, got, expected; - op1[0] = z2[0]; - expected[0]= z1[0]; - got[0] = z3[0]; - printf ("%s(op) failed (line %lu)\nwith rounding mode %s\n", - function.name, test_line_number, rnd_mode[rnd]); - if (!MPC_INEX_CMP (inex_re, inex_im, inex)) - printf("ternary value: got %s, expected (%s, %s)\n", - MPC_INEX_STR (inex), - MPFR_INEX_STR (inex_re), MPFR_INEX_STR (inex_im)); - MPC_OUT (op1); - printf ("op2 %li\n ", si); - MPC_OUT (got); - MPC_OUT (expected); - - exit (1); - } - break; - - default: - printf ("Unhandled function prototype %i in 'data_check'\n", function.type); - exit (1); - } - - /* check MPFR flags were not modified */ - check_mpfr_flags (rand_counter); - rand_counter ++; - } - - /* 3. Clear used variables */ - mpc_clear (z1); - switch (function.type) - { - case FC: - mpfr_clear (x1); - mpfr_clear (x2); - break; - case CC: case CCU: case CCS: - mpc_clear (z2); - mpc_clear (z3); - break; - case C_CC: - mpc_clear (z2); - mpc_clear (z3); - mpc_clear (z4); - break; - case CCCC: - mpc_clear (z2); - mpc_clear (z3); - mpc_clear (z4); - mpc_clear (z5); - break; - case CFC: case CCF: - mpfr_clear (x1); - mpc_clear (z2); - mpc_clear (z3); - break; - default: - ; - } - - close_data_file (fp); -} diff --git a/tests/read_description.c b/tests/read_description.c new file mode 100644 index 0000000..899a600 --- /dev/null +++ b/tests/read_description.c @@ -0,0 +1,267 @@ +/* read_description.c -- read parameters from description file + +Copyright (C) 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include +#include "mpc-tests.h" + +static size_t read_keyworddesc (mpc_datafile_context_t* datafile_context, + char **buffer_ptr, size_t buffer_length); + +/* tuple to link name with the enum value */ +typedef struct { + const char *typename; /* type name */ + mpc_param_t typeval ; /* type enum */ +} param_typeval_t; + +/* available types for function description */ +static const param_typeval_t sparam_typeval[]= { + { "int" , NATIVE_INT }, + { "unsigned long int" , NATIVE_UL }, + { "unsigned long" , NATIVE_UL }, + { "long int" , NATIVE_L }, + { "long" , NATIVE_L }, + { "double" , NATIVE_D }, + { "long double" , NATIVE_LD }, + { "double _Complex" , NATIVE_DC }, + { "long double _Complex", NATIVE_LDC }, + { "intmax_t" , NATIVE_IM }, + { "uintmax_t" , NATIVE_UIM }, + { "mpz_ptr" , GMP_Z }, + { "mpz_srcptr" , GMP_Z }, + { "mpq_ptr" , GMP_Q }, + { "mpq_srcptr" , GMP_Q }, + { "mpf_ptr" , GMP_F }, + { "mpf_srcptr" , GMP_F }, + { "mpfr_inex" , MPFR_INEX }, + { "mpfr_ptr" , MPFR }, + { "mpfr_srcptr" , MPFR }, + { "mpfr_rnd_t" , MPFR_RND }, + { "mpc_inex" , MPC_INEX }, + { "mpc_ptr" , MPC }, + { "mpc_srcptr" , MPC }, + { "mpc_rnd_t" , MPC_RND } +}; + +/* read primitives */ + +static size_t +read_keyworddesc (mpc_datafile_context_t* datafile_context, + char **buffer_ptr, + size_t buffer_length) +{ + size_t pos; + char *buffer; + + pos = 0; + buffer = *buffer_ptr; + + while (datafile_context->nextchar != EOF + && datafile_context->nextchar != '#' + && datafile_context->nextchar != '\n') + { + if (pos + 1 > buffer_length) + { + if (buffer_length == 0) + buffer_length = pos + 1; + buffer = (char *) realloc (buffer, 2 * buffer_length); + buffer_length *= 2; + if (buffer == NULL) + { + printf ("Cannot allocate memory\n"); + exit (1); + } + } + buffer[pos++] = (char) datafile_context->nextchar; + datafile_context->nextchar = getc (datafile_context->fd); + } + while (pos>0 && isspace(buffer[pos-1])) pos--; + + if (pos + 1 > buffer_length) + { + buffer = (char *) realloc (buffer, buffer_length + 1); + buffer_length++; + if (buffer == NULL) + { + printf ("Cannot allocate memory\n"); + exit (1); + } + } + buffer[pos] = '\0'; + + *buffer_ptr = buffer; + + return buffer_length; +} + +/* return the enum associated to name */ +static mpc_param_t +description_findtype (const char *name) +{ + + mpc_param_t r = sparam_typeval[0].typeval; + size_t s = 0; + const size_t send = sizeof (sparam_typeval) / sizeof (param_typeval_t); + + while (s < send && strcmp (sparam_typeval[s].typename, name) != 0) + s++; + + if (s < send) + r = sparam_typeval[s].typeval; + else + { + printf ("Error: Unable to find the type '%s'\n",name); + exit (1); + } + return r; +} + +/* return the name associated to the enum */ +const char* +read_description_findname (mpc_param_t e) +{ + + const char * name = NULL; + size_t s = 0; + const size_t send = sizeof (sparam_typeval) / sizeof (param_typeval_t); + + while (s < send && sparam_typeval[s].typeval != e) + s++; + + if (sname = namestr; + namestr = NULL; + + /* read RETURN fields */ + tpl_skip_whitespace_comments (&datafile_context); + len = 0; + len = read_keyworddesc (&datafile_context, &buffer, len); + if (buffer == NULL || strcmp (buffer,"RETURN:") != 0) + { + printf ("Error: Unable to read 'RETURN:' in file '%s'\n", + pathname); + exit (1); + } + + tpl_skip_whitespace_comments (&datafile_context); + len = read_keyworddesc (&datafile_context, &buffer, len); + if (buffer == NULL) + { + printf ("Error: Unable to read the return type of the function" + " in file '%s'\n", pathname); + exit (1); + } + param->T[nbout++] = description_findtype (buffer); + + /* read OUPUT fields */ + tpl_skip_whitespace_comments (&datafile_context); + len = read_keyworddesc (&datafile_context, &buffer, len); + if (buffer == NULL || strcmp (buffer,"OUTPUT:")!=0) + { + printf ("Error: Unable to read 'OUTPUT:' in file '%s'\n", + pathname); + exit (1); + } + + while (!feof (datafile_context.fd)) + { + tpl_skip_whitespace_comments (&datafile_context); + len = read_keyworddesc (&datafile_context, &buffer, len); + if (buffer == NULL) + { + printf ("Error: Unable to read the output type of the function" + " in file '%s'\n", pathname); + exit (1); + } + if (strcmp (buffer, "INPUT:") == 0) + break; /* exit the output loop */ + param->T[nbout++] = description_findtype (buffer); + } + + /* read INPUT fields */ + while (!feof (datafile_context.fd)) + { + tpl_skip_whitespace_comments (&datafile_context); + len = read_keyworddesc (&datafile_context, &buffer, len); + if (buffer == NULL) + { + printf ("Error: Unable to read the input type of the function" + " in file '%s'\n", pathname); + exit (1); + } + if (strlen (buffer) == 0 && feof (datafile_context.fd)) + break; + param->T[nbout+nbin] = description_findtype (buffer); + nbin++; + } + free (buffer); + + param->nbout = nbout; + param->nbin = nbin; + + /* duplicate output parameters at the end for the expected values */ + for (j = 0; j < param->nbout; j++) + { + MPC_ASSERT (nbout + nbin + j < PARAMETER_ARRAY_SIZE); + param->T[nbout + nbin + j] = param->T[j]; + } +} diff --git a/tests/read_line.c b/tests/read_line.c new file mode 100644 index 0000000..3fb29c5 --- /dev/null +++ b/tests/read_line.c @@ -0,0 +1,242 @@ +/* read_line.c -- Read line of test data in file. + +Copyright (C) 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +static void +read_param (mpc_datafile_context_t* datafile_context, + mpc_operand_t* p, mpc_param_t t) +{ + switch (t) + { + case NATIVE_INT: + tpl_read_int (datafile_context, &(p->i),""); + return; + case NATIVE_UL: + tpl_read_ui (datafile_context, &(p->ui)); + return; + case NATIVE_L: + tpl_read_si (datafile_context, &(p->si)); + return; + + case NATIVE_D: + case NATIVE_LD: + /* TODO */ + fprintf (stderr, "read_param: type not implemented.\n"); + exit (1); + break; + + case NATIVE_DC: + case NATIVE_LDC: +#ifdef _Complex_I + /* TODO */ + fprintf (stderr, "read_param: type not implemented.\n"); + exit (1); +#endif + break; + + case NATIVE_IM: + case NATIVE_UIM: +#ifdef _MPC_H_HAVE_INTMAX_T + /* TODO */ + fprintf (stderr, "read_param: type not implemented.\n"); + exit (1); +#endif + break; + + case NATIVE_STRING: + /* TODO */ + fprintf (stderr, "read_param: type not implemented.\n"); + exit (1); + break; + + case GMP_Z: + tpl_read_mpz (datafile_context, p->mpz); + return; + + case GMP_Q: + case GMP_F: + /* TODO */ + fprintf (stderr, "read_param: type not implemented.\n"); + exit (1); + break; + + case MPFR_INEX: + tpl_read_mpfr_inex (datafile_context, &p->mpfr_inex); + return; + case MPFR: + tpl_read_mpfr (datafile_context, + p->mpfr_data.mpfr, &p->mpfr_data.known_sign); + return; + case MPFR_RND: + tpl_read_mpfr_rnd (datafile_context, &p->mpfr_rnd); + return; + + case MPC_INEX: + tpl_read_mpc_inex (datafile_context, &p->mpc_inex_data); + return; + case MPC: + tpl_read_mpc (datafile_context, &p->mpc_data); + return; + case MPC_RND: + tpl_read_mpc_rnd (datafile_context, &p->mpc_rnd); + return; + } + + fprintf (stderr, "read_param: unsupported type.\n"); + exit (1); +} + +static void +set_precision (mpc_fun_param_t* params, int index) +{ + /* set output precision to reference precision */ + int index_ref = index + params->nbout + params->nbin; + + switch (params->T[index]) + { + case MPFR: + mpfr_set_prec (params->P[index].mpfr, + mpfr_get_prec (params->P[index_ref].mpfr)); + return; + + case MPC: + mpfr_set_prec (mpc_realref (params->P[index].mpc), + MPC_PREC_RE (params->P[index_ref].mpc)); + mpfr_set_prec (mpc_imagref (params->P[index].mpc), + MPC_PREC_IM (params->P[index_ref].mpc)); + return; + + case NATIVE_INT: + case NATIVE_UL: case NATIVE_L: + case NATIVE_D: case NATIVE_LD: + case NATIVE_DC: case NATIVE_LDC: + case NATIVE_IM: case NATIVE_UIM: + case NATIVE_STRING: + case GMP_Z: case GMP_Q: + case GMP_F: + case MPFR_INEX: case MPFR_RND: + case MPC_INEX: case MPC_RND: + /* unsupported types */ + break; + } + + fprintf (stderr, "set_precision: unsupported type.\n"); + exit (1); +} + +void +read_line (mpc_datafile_context_t* datafile_context, + mpc_fun_param_t* params) +{ + int in, out; + int total = params->nbout + params->nbin; + + datafile_context->test_line_number = datafile_context->line_number; + + for (out = 0; out < params->nbout; out++) + + { + read_param (datafile_context, &(params->P[total + out]), + params->T[total + out]); + if (params->T[out] == MPFR || params->T[out] == MPC) + set_precision (params, out); + } + + for (in = params->nbout; in < total; in++) + { + read_param (datafile_context, &(params->P[in]), params->T[in]); + } +} + +/* read primitives */ +static void +tpl_skip_line (mpc_datafile_context_t* datafile_context) + /* skips characters until reaching '\n' or EOF; */ + /* '\n' is skipped as well */ +{ + while (datafile_context->nextchar != EOF && datafile_context->nextchar != '\n') + datafile_context->nextchar = getc (datafile_context->fd); + if (datafile_context->nextchar != EOF) + { + datafile_context->line_number ++; + datafile_context->nextchar = getc (datafile_context->fd); + } +} + +static void +tpl_skip_whitespace (mpc_datafile_context_t* datafile_context) + /* skips over whitespace if any until reaching EOF */ + /* or non-whitespace */ +{ + while (isspace (datafile_context->nextchar)) + { + if (datafile_context->nextchar == '\n') + datafile_context->line_number ++; + datafile_context->nextchar = getc (datafile_context->fd); + } +} + +void +tpl_skip_whitespace_comments (mpc_datafile_context_t* datafile_context) + /* skips over all whitespace and comments, if any */ +{ + tpl_skip_whitespace (datafile_context); + while (datafile_context->nextchar == '#') { + tpl_skip_line (datafile_context); + if (datafile_context->nextchar != EOF) + tpl_skip_whitespace (datafile_context); + } +} + +/* All following read routines skip over whitespace and comments; */ +/* so after calling them, nextchar is either EOF or the beginning */ +/* of a non-comment token. */ +void +tpl_read_ternary (mpc_datafile_context_t* datafile_context, int* ternary) +{ + switch (datafile_context->nextchar) + { + case '!': + *ternary = TERNARY_ERROR; + break; + case '?': + *ternary = TERNARY_NOT_CHECKED; + break; + case '+': + *ternary = +1; + break; + case '0': + *ternary = 0; + break; + case '-': + *ternary = -1; + break; + default: + printf ("Error: Unexpected ternary value '%c' in file '%s' line %lu\n", + datafile_context->nextchar, + datafile_context->pathname, + datafile_context->line_number); + exit (1); + } + + datafile_context->nextchar = getc (datafile_context->fd); + tpl_skip_whitespace_comments (datafile_context); +} diff --git a/tests/real.dsc b/tests/real.dsc new file mode 100644 index 0000000..4872e33 --- /dev/null +++ b/tests/real.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_real +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_real +RETURN: + mpfr_inex +OUTPUT: + mpfr_ptr +INPUT: + mpc_srcptr + mpfr_rnd_t diff --git a/tests/rounding.c b/tests/rounding.c new file mode 100644 index 0000000..603e627 --- /dev/null +++ b/tests/rounding.c @@ -0,0 +1,131 @@ +/* rounding.c -- file for functions iterating over rounding modes. + +Copyright (C) 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +/* helper functions for iterating over mpfr rounding modes */ + +#define FIRST_MPFR_RND_MODE MPFR_RNDN + +static mpfr_rnd_t +next_mpfr_rnd_mode (mpfr_rnd_t curr) +{ + switch (curr) + { + case MPFR_RNDN: + return MPFR_RNDZ; + case MPFR_RNDZ: + return MPFR_RNDU; + case MPFR_RNDU: + return MPFR_RNDD; + default: + /* return invalid guard value in mpfr_rnd_t */ +#if MPFR_VERSION_MAJOR < 3 + return MPFR_RNDNA; +#else + return MPFR_RNDA; /* valid rounding type, but not used in mpc */ +#endif + } +} + +static int +is_valid_mpfr_rnd_mode (mpfr_rnd_t curr) +/* returns 1 if curr is a valid rounding mode, and 0 otherwise */ +{ + if ( curr == MPFR_RNDN || curr == MPFR_RNDZ + || curr == MPFR_RNDU || curr == MPFR_RNDD) + return 1; + else + return 0; +} + + +/* functions using abstract parameters */ + +void +first_rnd_mode (mpc_fun_param_t *params) +{ + int rnd_mode_index = params->nbout + params->nbin - 1; + switch (params->T[rnd_mode_index]) + { + case MPC_RND: + params->P[rnd_mode_index].mpc_rnd = + MPC_RND(FIRST_MPFR_RND_MODE, FIRST_MPFR_RND_MODE); + break; + case MPFR_RND: + params->P[rnd_mode_index].mpfr_rnd = FIRST_MPFR_RND_MODE; + break; + default: + printf ("The rounding mode is expected to be" + " the last input parameter.\n"); + exit (-1); + } +} + +void +next_rnd_mode (mpc_fun_param_t *params) +{ + mpfr_rnd_t rnd_re, rnd_im; + int rnd_mode_index = params->nbout + params->nbin - 1; + switch (params->T[rnd_mode_index]) + { + case MPC_RND: + rnd_re = MPC_RND_RE (params->P[rnd_mode_index].mpc_rnd); + rnd_im = MPC_RND_IM (params->P[rnd_mode_index].mpc_rnd); + rnd_im = next_mpfr_rnd_mode (rnd_im); + if (!is_valid_mpfr_rnd_mode (rnd_im)) + { + rnd_re = next_mpfr_rnd_mode (rnd_re); + rnd_im = FIRST_MPFR_RND_MODE; + } + params->P[rnd_mode_index].mpc_rnd = MPC_RND(rnd_re, rnd_im); + break; + case MPFR_RND: + params->P[rnd_mode_index].mpfr_rnd = + next_mpfr_rnd_mode (params->P[rnd_mode_index].mpfr_rnd); + break; + default: + printf ("The rounding mode is expected to be" + " the last input parameter.\n"); + exit (-1); + } +} + +int +is_valid_rnd_mode (mpc_fun_param_t *params) +/* returns 1 if curr is a valid rounding mode, and 0 otherwise */ +{ + mpfr_rnd_t rnd_re, rnd_im; + int rnd_mode_index = params->nbout + params->nbin - 1; + switch (params->T[rnd_mode_index]) + { + case MPC_RND: + rnd_re = MPC_RND_RE (params->P[rnd_mode_index].mpc_rnd); + rnd_im = MPC_RND_IM (params->P[rnd_mode_index].mpc_rnd); + return is_valid_mpfr_rnd_mode (rnd_re) + && is_valid_mpfr_rnd_mode (rnd_im); + case MPFR_RND: + return is_valid_mpfr_rnd_mode (params->P[rnd_mode_index].mpfr_rnd); + default: + printf ("The rounding mode is expected to be" + " the last input parameter.\n"); + exit (-1); + } +} diff --git a/tests/setprec_parameters.c b/tests/setprec_parameters.c new file mode 100644 index 0000000..2080867 --- /dev/null +++ b/tests/setprec_parameters.c @@ -0,0 +1,66 @@ +/* setprec_parameters.c -- Functions changing the precision of i/o parameters. + +Copyright (C) 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +void +set_output_precision (mpc_fun_param_t *params, mpfr_prec_t prec) +{ + int out; + const int start = 0; + const int end = params->nbout; + for (out = start; out < end; out++) + { + if (params->T[out] == MPFR) + mpfr_set_prec (params->P[out].mpfr, prec); + else if (params->T[out] == MPC) + mpc_set_prec (params->P[out].mpc, prec); + } +} + +void +set_input_precision (mpc_fun_param_t *params, mpfr_prec_t prec) +{ + int i; + const int start = params->nbout; + const int end = start + params->nbin; + for (i = start; i < end; i++) + { + if (params->T[i] == MPFR) + mpfr_set_prec (params->P[i].mpfr, prec); + else if (params->T[i] == MPC) + mpc_set_prec (params->P[i].mpc, prec); + } +} + +void +set_reference_precision (mpc_fun_param_t *params, mpfr_prec_t prec) +{ + int i; + const int start = params->nbout + params->nbin; + const int end = start + params->nbout; + for (i = start; i < end; i++) + { + if (params->T[i] == MPFR) + mpfr_set_prec (params->P[i].mpfr_data.mpfr, prec); + else if (params->T[i] == MPC) + mpc_set_prec (params->P[i].mpc_data.mpc, prec); + } +} diff --git a/tests/sin.dsc b/tests/sin.dsc new file mode 100644 index 0000000..8d3eaae --- /dev/null +++ b/tests/sin.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_sin +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_sin +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/sin_cos.dsc b/tests/sin_cos.dsc new file mode 100644 index 0000000..ddefe79 --- /dev/null +++ b/tests/sin_cos.dsc @@ -0,0 +1,30 @@ +# Description file for mpc_sin_cos +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_sin_cos +RETURN: + mpc_inex +OUTPUT: + mpc_ptr + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t + mpc_rnd_t diff --git a/tests/sinh.dsc b/tests/sinh.dsc new file mode 100644 index 0000000..9fe4d03 --- /dev/null +++ b/tests/sinh.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_sinh +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_sinh +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/sqr.dsc b/tests/sqr.dsc new file mode 100644 index 0000000..56f098a --- /dev/null +++ b/tests/sqr.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_sqr +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_sqr +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/sqrt.dsc b/tests/sqrt.dsc new file mode 100644 index 0000000..b564f00 --- /dev/null +++ b/tests/sqrt.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_sqrt +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_sqrt +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/sub.dsc b/tests/sub.dsc new file mode 100644 index 0000000..bd073fb --- /dev/null +++ b/tests/sub.dsc @@ -0,0 +1,30 @@ +# Description file for mpc_sub +# +# Copyright (C) 2008, 2011, 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_sub +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_srcptr + mpc_rnd_t diff --git a/tests/sub_fr.dsc b/tests/sub_fr.dsc new file mode 100644 index 0000000..2e95113 --- /dev/null +++ b/tests/sub_fr.dsc @@ -0,0 +1,30 @@ +# Description file for mpc_sub_fr +# +# Copyright (C) 2008, 2010, 2011, 2012, INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_sub_fr +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpfr_srcptr + mpc_rnd_t diff --git a/tests/sub_ui.dsc b/tests/sub_ui.dsc new file mode 100644 index 0000000..300d129 --- /dev/null +++ b/tests/sub_ui.dsc @@ -0,0 +1,31 @@ +# Description file for mpc_sub_ui +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# Description file of the function +NAME: + mpc_sub_ui +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + unsigned long int + mpc_rnd_t + \ No newline at end of file diff --git a/tests/tabs.c b/tests/tabs.c index 4651089..afd33ee 100644 --- a/tests/tabs.c +++ b/tests/tabs.c @@ -1,6 +1,6 @@ /* tabs -- test file for mpc_abs. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,20 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpfr_inex = mpc_abs (P[1].mpfr, P[2].mpc, P[3].mpfr_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (FC, f, mpc_abs); - test_start (); - tgeneric (f, 2, 1024, 1, 0); - data_check (f, "abs.dat"); + data_check_template ("abs.dsc", "abs.dat"); + + tgeneric_template ("abs.dsc", 2, 1024, 1, 1024); test_end (); diff --git a/tests/tacos.c b/tests/tacos.c index 38653a4..6ad1cc6 100644 --- a/tests/tacos.c +++ b/tests/tacos.c @@ -1,6 +1,6 @@ /* tacos -- test file for mpc_acos. -Copyright (C) 2009 INRIA +Copyright (C) 2009, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,22 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_acos (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_acos (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_acos); - test_start (); - data_check (f, "acos.dat"); - tgeneric (f, 2, 512, 7, 7); + data_check_template ("acos.dsc", "acos.dat"); + + tgeneric_template ("acos.dsc", 2, 512, 7, 7); test_end (); diff --git a/tests/tacosh.c b/tests/tacosh.c index f8fbdc6..1ea1077 100644 --- a/tests/tacosh.c +++ b/tests/tacosh.c @@ -1,6 +1,6 @@ /* tacosh.c -- test file for mpc_acosh. -Copyright (C) 2009 INRIA +Copyright (C) 2009, 2013 INRIA This file is part of GNU MPC. @@ -39,17 +39,24 @@ bug20091120 (void) mpc_clear (y); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_acosh (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_acosh (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_acosh); - test_start (); bug20091120 (); - data_check (f, "acosh.dat"); - tgeneric (f, 2, 512, 7, 7); + data_check_template ("acosh.dsc", "acosh.dat"); + + tgeneric_template ("acosh.dsc", 2, 512, 7, 7); test_end (); diff --git a/tests/tadd.c b/tests/tadd.c index 11a305b..9654026 100644 --- a/tests/tadd.c +++ b/tests/tadd.c @@ -1,6 +1,6 @@ /* tadd -- test file for mpc_add. -Copyright (C) 2008, 2010, 2011, 2012 INRIA +Copyright (C) 2008, 2010, 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -52,17 +52,28 @@ check_ternary_value (void) mpc_clear (z); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_add (P[1].mpc, P[2].mpc, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_SYMMETRIC \ + P[0].mpc_inex = mpc_add (P[1].mpc, P[3].mpc, P[2].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_add (P[1].mpc, P[1].mpc, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP2 \ + P[0].mpc_inex = mpc_add (P[1].mpc, P[2].mpc, P[1].mpc, P[4].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (C_CC, f, mpc_add); - f.properties = FUNC_PROP_SYMETRIC; - test_start (); check_ternary_value(); - data_check (f, "add.dat"); - tgeneric (f, 2, 1024, 7, -1); + + data_check_template ("add.dsc", "add.dat"); + + tgeneric_template ("add.dsc", 2, 1024, 7, 128); test_end (); diff --git a/tests/tadd_fr.c b/tests/tadd_fr.c index 0f1a5cf..225a32d 100644 --- a/tests/tadd_fr.c +++ b/tests/tadd_fr.c @@ -1,6 +1,6 @@ /* tadd_fr -- test file for mpc_add_fr. -Copyright (C) 2008, 2010, 2012 INRIA +Copyright (C) 2008, 2010, 2012, 2013 INRIA This file is part of GNU MPC. @@ -56,17 +56,26 @@ check_ternary_value (mpfr_prec_t prec_max, mpfr_prec_t step) mpfr_clear (f); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_add_fr (P[1].mpc, P[2].mpc, P[3].mpfr, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_add_fr (P[1].mpc, P[1].mpc, P[3].mpfr, P[4].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCF, f, mpc_add_fr); test_start (); check_ternary_value (1024, 1); - data_check (f, "add_fr.dat"); - tgeneric (f, 2, 1024, 7, 10); + data_check_template ("add_fr.dsc", "add_fr.dat"); + + tgeneric_template ("add_fr.dsc", 2, 1024, 7, 128); test_end (); + return 0; } diff --git a/tests/tadd_si.c b/tests/tadd_si.c index 969f552..7bc1449 100644 --- a/tests/tadd_si.c +++ b/tests/tadd_si.c @@ -1,6 +1,6 @@ /* tadd_si -- test file for mpc_add_si. -Copyright (C) 2011, 2012 INRIA +Copyright (C) 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -24,45 +24,51 @@ along with this program. If not, see http://www.gnu.org/licenses/ . static void check_ternary_value (void) { - mpfr_prec_t prec; - mpc_t z; - const long int s = -1; - - mpc_init2 (z, 2); - - for (prec=2; prec <= 1024; prec++) { - mpc_set_prec (z, prec); - mpc_set_ui (z, 3ul, MPC_RNDNN); - if (mpc_add_si (z, z, s, MPC_RNDDU)) { - printf ("Error in mpc_add_si: 3+(-1) should be exact\n"); - exit (1); - } - else if (mpc_cmp_si (z, 2l) != 0) { - printf ("Error in mpc_add_si: 3+(-1) should be 2\n"); - exit (1); - } - - mpc_mul_2ui (z, z, (unsigned long int) prec, MPC_RNDNN); - if (mpc_add_si (z, z, s, MPC_RNDNN) == 0) { - printf ("Error in mpc_add_si: 2^(prec+1)-1 cannot be exact\n"); - exit (1); - } + mpfr_prec_t prec; + mpc_t z; + const long int s = -1; + + mpc_init2 (z, 2); + + for (prec=2; prec <= 1024; prec++) { + mpc_set_prec (z, prec); + mpc_set_ui (z, 3ul, MPC_RNDNN); + if (mpc_add_si (z, z, s, MPC_RNDDU)) { + printf ("Error in mpc_add_si: 3+(-1) should be exact\n"); + exit (1); } + else if (mpc_cmp_si (z, 2l) != 0) { + printf ("Error in mpc_add_si: 3+(-1) should be 2\n"); + exit (1); + } + + mpc_mul_2ui (z, z, (unsigned long int) prec, MPC_RNDNN); + if (mpc_add_si (z, z, s, MPC_RNDNN) == 0) { + printf ("Error in mpc_add_si: 2^(prec+1)-1 cannot be exact\n"); + exit (1); + } + } - mpc_clear (z); + mpc_clear (z); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_add_si (P[1].mpc, P[2].mpc, P[3].si, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_add_si (P[1].mpc, P[1].mpc, P[3].si, P[4].mpc_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCS, f, mpc_add_si); + test_start (); - test_start (); + check_ternary_value (); - check_ternary_value (); - tgeneric (f, 2, 1024, 11, -2); + tgeneric_template ("add_si.dsc", 2, 1024, 1, 1024); - test_end (); + test_end (); - return 0; + return 0; } diff --git a/tests/tadd_ui.c b/tests/tadd_ui.c index 4f8efea..a62979d 100644 --- a/tests/tadd_ui.c +++ b/tests/tadd_ui.c @@ -1,6 +1,6 @@ /* tadd_ui -- test file for mpc_add_ui. -Copyright (C) 2008, 2010, 2012 INRIA +Copyright (C) 2008, 2010, 2012, 2013 INRIA This file is part of GNU MPC. @@ -52,15 +52,21 @@ check_ternary_value (void) mpc_clear (z); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_add_ui (P[1].mpc, P[2].mpc, P[3].ui, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_add_ui (P[1].mpc, P[1].mpc, P[3].ui, P[4].mpc_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCU, f, mpc_add_ui); - test_start (); check_ternary_value (); - tgeneric (f, 2, 1024, 7, -1); + + tgeneric_template ("add_ui.dsc", 2, 1024, 1, 1024); test_end (); diff --git a/tests/tan.dsc b/tests/tan.dsc new file mode 100644 index 0000000..7657117 --- /dev/null +++ b/tests/tan.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_tan +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_tan +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/tanh.dsc b/tests/tanh.dsc new file mode 100644 index 0000000..2e20ded --- /dev/null +++ b/tests/tanh.dsc @@ -0,0 +1,28 @@ +# Description file for mpc_tanh +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_tanh +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + mpc_srcptr + mpc_rnd_t diff --git a/tests/targ.c b/tests/targ.c index b84c292..84b027f 100644 --- a/tests/targ.c +++ b/tests/targ.c @@ -1,6 +1,6 @@ /* targ -- test file for mpc_arg. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,20 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpfr_inex = mpc_arg (P[1].mpfr, P[2].mpc, P[3].mpfr_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (FC, f, mpc_arg); - test_start (); - tgeneric (f, 2, 1024, 1, 4096); - data_check (f, "arg.dat"); + data_check_template ("arg.dsc", "arg.dat"); + + tgeneric_template ("arg.dsc", 2, 1024, 1, 4096); test_end (); diff --git a/tests/tasin.c b/tests/tasin.c index 3470408..612cd47 100644 --- a/tests/tasin.c +++ b/tests/tasin.c @@ -1,6 +1,6 @@ /* tasin -- test file for mpc_asin. -Copyright (C) 2009 INRIA +Copyright (C) 2009, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,22 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_asin (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_asin (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_asin); - test_start (); - data_check (f, "asin.dat"); - tgeneric (f, 2, 512, 7, 7); + data_check_template ("asin.dsc", "asin.dat"); + + tgeneric_template ("asin.dsc", 2, 512, 7, 7); test_end (); diff --git a/tests/tasinh.c b/tests/tasinh.c index c266829..207aa54 100644 --- a/tests/tasinh.c +++ b/tests/tasinh.c @@ -1,6 +1,6 @@ /* tasinh -- test file for mpc_asinh. -Copyright (C) 2009 INRIA +Copyright (C) 2009, 2013 INRIA This file is part of GNU MPC. @@ -39,17 +39,24 @@ bug20091120 (void) mpc_clear (y); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_asinh (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_asinh (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_asinh); - test_start (); bug20091120 (); - data_check (f, "asinh.dat"); - tgeneric (f, 2, 512, 7, 7); + data_check_template ("asinh.dsc", "asinh.dat"); + + tgeneric_template ("asinh.dsc", 2, 512, 7, 7); test_end (); diff --git a/tests/tatan.c b/tests/tatan.c index ca93ec4..fcb7e4d 100644 --- a/tests/tatan.c +++ b/tests/tatan.c @@ -1,6 +1,6 @@ /* tatan -- test file for mpc_atan. -Copyright (C) 2009, 2012 INRIA +Copyright (C) 2009, 2012, 2013 INRIA This file is part of GNU MPC. @@ -50,16 +50,22 @@ test_underflow (void) } #endif +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_atan (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_atan (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" int main (void) { - DECL_FUNC (CC, f, mpc_atan); - test_start (); - data_check (f, "atan.dat"); - tgeneric (f, 2, 512, 5, 128); + data_check_template ("atan.dsc", "atan.dat"); + + tgeneric_template ("atan.dsc", 2, 512, 5, 128); test_end (); diff --git a/tests/tatanh.c b/tests/tatanh.c index ddba68c..188b772 100644 --- a/tests/tatanh.c +++ b/tests/tatanh.c @@ -1,6 +1,6 @@ /* tatanh -- test file for mpc_atanh. -Copyright (C) 2009 INRIA +Copyright (C) 2009, 2013 INRIA This file is part of GNU MPC. @@ -39,17 +39,24 @@ bug20091120 (void) mpc_clear (y); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_atanh (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_atanh (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_atanh); - test_start (); bug20091120 (); - data_check (f, "atanh.dat"); - tgeneric (f, 2, 512, 5, 128); + data_check_template ("atanh.dsc", "atanh.dat"); + + tgeneric_template ("atanh.dsc", 2, 512, 5, 128); test_end (); diff --git a/tests/tconj.c b/tests/tconj.c index 949a80b..c179135 100644 --- a/tests/tconj.c +++ b/tests/tconj.c @@ -1,6 +1,6 @@ /* tconj -- test file for mpc_conj. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,22 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_conj (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_conj (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_conj); - test_start (); - data_check (f, "conj.dat"); - tgeneric (f, 2, 1024, 1, 0); + data_check_template ("conj.dsc", "conj.dat"); + + tgeneric_template ("conj.dsc", 2, 1024, 1, 0); test_end (); diff --git a/tests/tcos.c b/tests/tcos.c index dafc01d..bfd7a76 100644 --- a/tests/tcos.c +++ b/tests/tcos.c @@ -1,6 +1,6 @@ /* tcos -- test file for mpc_cos. -Copyright (C) 2008, 2009, 2011, 2012 INRIA +Copyright (C) 2008, 2009, 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -47,17 +47,24 @@ bug20090105 (void) mpc_clear (op); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_cos (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_cos (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_cos); - test_start (); - data_check (f, "cos.dat"); - tgeneric (f, 2, 512, 7, 7); + data_check_template ("cos.dsc", "cos.dat"); + + tgeneric_template ("cos.dsc", 2, 512, 7, 7); - bug20090105 (); + bug20090105 (); /* TODO: move data in cos.dat */ test_end (); diff --git a/tests/tcosh.c b/tests/tcosh.c index 0d6a9da..8c04653 100644 --- a/tests/tcosh.c +++ b/tests/tcosh.c @@ -1,6 +1,6 @@ -/* test file for mpc_cosh. +/* tcosh -- test file for mpc_cosh. -Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA +Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -115,16 +115,23 @@ pure_imaginary_argument (void) mpc_clear (u); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_cosh (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_cosh (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" int main (void) { - DECL_FUNC(CC, f,mpc_cosh); - test_start (); - data_check (f, "cosh.dat"); - tgeneric (f, 2, 512, 7, 7); + data_check_template ("cosh.dsc", "cosh.dat"); + + tgeneric_template ("cosh.dsc", 2, 512, 7, 7); + /* FIXME: remove the following tests? (Now tested by tgeneric) */ pure_real_argument (); pure_imaginary_argument (); diff --git a/tests/tdiv.c b/tests/tdiv.c index 3b8340f..51ffb39 100644 --- a/tests/tdiv.c +++ b/tests/tdiv.c @@ -1,6 +1,6 @@ /* tdiv -- test file for mpc_div. -Copyright (C) 2002, 2008, 2009, 2011 INRIA +Copyright (C) 2002, 2008, 2009, 2011, 2013 INRIA This file is part of GNU MPC. @@ -21,16 +21,26 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_div (P[1].mpc, P[2].mpc, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_div (P[1].mpc, P[1].mpc, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP2 \ + P[0].mpc_inex = mpc_div (P[1].mpc, P[2].mpc, P[1].mpc, P[4].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (C_CC, f, mpc_div); - test_start (); - data_check (f, "div.dat"); - tgeneric (f, 2, 1024, 7, 4096); + data_check_template ("div.dsc", "div.dat"); + + tgeneric_template ("div.dsc", 2, 1024, 7, 4096); test_end (); + return 0; } diff --git a/tests/tdiv_2si.c b/tests/tdiv_2si.c index 5046201..2b34aec 100644 --- a/tests/tdiv_2si.c +++ b/tests/tdiv_2si.c @@ -1,6 +1,6 @@ /* tdiv_2si -- test file for mpc_div_2si. -Copyright (C) 2012 INRIA +Copyright (C) 2012, 2013 INRIA This file is part of GNU MPC. @@ -20,14 +20,19 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_div_2si (P[1].mpc, P[2].mpc, P[3].si, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_div_2si (P[1].mpc, P[1].mpc, P[3].si, P[4].mpc_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCS, f, mpc_div_2si); - test_start (); - tgeneric (f, 2, 1024, 7, -1); + tgeneric_template ("div_2si.dsc", 2, 1024, 7, 1024); test_end (); diff --git a/tests/tdiv_2ui.c b/tests/tdiv_2ui.c index 6cc8f14..8c6a7f4 100644 --- a/tests/tdiv_2ui.c +++ b/tests/tdiv_2ui.c @@ -1,6 +1,6 @@ /* tdiv_2ui -- test file for mpc_div_2ui. -Copyright (C) 2008, 2012 INRIA +Copyright (C) 2008, 2012, 2013 INRIA This file is part of GNU MPC. @@ -20,14 +20,19 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_div_2ui (P[1].mpc, P[2].mpc, P[3].ui, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_div_2ui (P[1].mpc, P[1].mpc, P[3].ui, P[4].mpc_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCU, f, mpc_div_2ui); - test_start (); - tgeneric (f, 2, 1024, 7, -1); + tgeneric_template ("div_2ui.dsc", 2, 1024, 7, 1024); test_end (); diff --git a/tests/tdiv_fr.c b/tests/tdiv_fr.c index 21e677e..a56f701 100644 --- a/tests/tdiv_fr.c +++ b/tests/tdiv_fr.c @@ -1,6 +1,6 @@ -/* test file for mpc_div_fr. +/* tdiv_fr.c -- test file for mpc_div_fr. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,22 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_div_fr (P[1].mpc, P[2].mpc, P[3].mpfr, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_div_fr (P[1].mpc, P[1].mpc, P[3].mpfr, P[4].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCF, f, mpc_div_fr); - test_start (); - data_check (f, "div_fr.dat"); - tgeneric (f, 2, 1024, 7, -1); + data_check_template ("div_fr.dsc", "div_fr.dat"); + + tgeneric_template ("div_fr.dsc", 2, 1024, 7, 1024); test_end (); diff --git a/tests/tdiv_ui.c b/tests/tdiv_ui.c index 5e62d57..1455730 100644 --- a/tests/tdiv_ui.c +++ b/tests/tdiv_ui.c @@ -1,6 +1,6 @@ -/* test file for mpc_div_ui. +/* tdiv_ui.c -- test file for mpc_div_ui. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,14 +20,19 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_div_ui (P[1].mpc, P[2].mpc, P[3].ui, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_div_ui (P[1].mpc, P[1].mpc, P[3].ui, P[4].mpc_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCU, f, mpc_div_ui); - test_start (); - tgeneric (f, 2, 1024, 7, -1); + tgeneric_template ("div_ui.dsc", 2, 1024, 7, -1); test_end (); diff --git a/tests/texp.c b/tests/texp.c index 0486cce..4415d3f 100644 --- a/tests/texp.c +++ b/tests/texp.c @@ -1,6 +1,6 @@ /* texp -- test file for mpc_exp. -Copyright (C) 2002, 2008 INRIA +Copyright (C) 2002, 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,22 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_exp (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_exp (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_exp); - test_start (); - data_check (f, "exp.dat"); - tgeneric (f, 2, 512, 7, 256); + data_check_template ("exp.dsc", "exp.dat"); + + tgeneric_template ("exp.dsc", 2, 512, 7, 256); test_end (); diff --git a/tests/tfma.c b/tests/tfma.c index 81bc167..62a7b0c 100644 --- a/tests/tfma.c +++ b/tests/tfma.c @@ -1,6 +1,6 @@ /* tfma -- test file for mpc_fma. -Copyright (C) 2011, 2012 INRIA +Copyright (C) 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -88,18 +88,32 @@ check_random (void) mpc_clear (c); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = \ + mpc_fma (P[1].mpc, P[2].mpc, P[3].mpc, P[4].mpc, P[5].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = \ + mpc_fma (P[1].mpc, P[1].mpc, P[3].mpc, P[4].mpc, P[5].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP2 \ + P[0].mpc_inex = \ + mpc_fma (P[1].mpc, P[2].mpc, P[1].mpc, P[4].mpc, P[5].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP3 \ + P[0].mpc_inex = \ + mpc_fma (P[1].mpc, P[2].mpc, P[3].mpc, P[1].mpc, P[5].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" int main (void) { - DECL_FUNC (CCCC, f, mpc_fma); - test_start (); - check_random (); + check_random (); /* Remove it? */ + + data_check_template ("fma.dsc", "fma.dat"); - data_check (f, "fma.dat"); - tgeneric (f, 2, 1024, 1, 256); + tgeneric_template ("fma.dsc", 2, 1024, 1, 256); test_end (); diff --git a/tests/tfr_div.c b/tests/tfr_div.c index bea8a21..e257384 100644 --- a/tests/tfr_div.c +++ b/tests/tfr_div.c @@ -1,6 +1,6 @@ /* tfr_div -- test file for mpc_fr_div. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,24 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_fr_div (P[1].mpc, P[2].mpfr, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP2 \ + P[0].mpc_inex = mpc_fr_div (P[1].mpc, P[2].mpfr, P[1].mpc, P[4].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CFC, f, mpc_fr_div); test_start(); - data_check (f, "fr_div.dat"); - tgeneric (f, 2, 1024, 7, 65535); + data_check_template ("fr_div.dsc", "fr_div.dat"); + + tgeneric_template ("fr_div.dsc", 2, 1024, 7, 65535); test_end (); + return 0; } diff --git a/tests/tfr_sub.c b/tests/tfr_sub.c index e366bc6..5665cc2 100644 --- a/tests/tfr_sub.c +++ b/tests/tfr_sub.c @@ -1,6 +1,6 @@ /* tfr_div -- test file for mpc_fr_sub. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,16 +20,24 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_fr_sub (P[1].mpc, P[2].mpfr, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP2 \ + P[0].mpc_inex = mpc_fr_sub (P[1].mpc, P[2].mpfr, P[1].mpc, P[4].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC(CFC, f, mpc_fr_sub); - test_start(); - data_check (f, "fr_sub.dat"); - tgeneric (f, 2, 4096, 7, 0); + data_check_template ("fr_sub.dsc", "fr_sub.dat"); + + tgeneric_template ("fr_sub.dsc", 2, 4096, 7, 1024); test_end (); + return 0; } diff --git a/tests/tgeneric.tpl b/tests/tgeneric.tpl new file mode 100644 index 0000000..5d65afb --- /dev/null +++ b/tests/tgeneric.tpl @@ -0,0 +1,328 @@ +/* tgeneric.tpl -- template file for generic tests. + +Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#ifndef MPC_FUNCTION_CALL +#error Define MPC_FUNCTION_CALL before including 'data_check.tpl'. +#endif + +/* helper functions, defined after tgeneric */ +static int count_special_cases (mpc_fun_param_t *params); +static void random_params (mpc_fun_param_t *params, + mpfr_exp_t exp_min, mpfr_exp_t exp_max, + int special); +static void check_against_quadruple_precision (mpc_fun_param_t *params, + mpfr_prec_t prec, + mpfr_exp_t exp_min, + mpfr_exp_t exp_max, + int special); + + +/* tgeneric(desc, prec_min, prec_max, step, exp_max) checks rounding with + random numbers: + - with precision ranging from prec_min to prec_max with an increment of + step, + - with exponent between -exp_max and exp_max. + - for pure real, pure imaginary and infinite random parameters. + + It also checks parameter reuse. +*/ +static void +tgeneric_template (const char *description_file, + mpfr_prec_t prec_min, mpfr_prec_t prec_max, mpfr_prec_t step, + mpfr_exp_t exp_max) +{ + int special = 0; + int last_special; + mpfr_prec_t prec; + mpfr_exp_t exp_min; + mpc_fun_param_t params; + + read_description (¶ms, description_file); + init_parameters (¶ms); + + /* ask for enough memory */ + set_output_precision (¶ms, 4 * prec_max); + set_input_precision (¶ms, prec_max); + set_reference_precision (¶ms, prec_max); + + /* sanity checks */ + exp_min = mpfr_get_emin (); + if (exp_max <= 0 || exp_max > mpfr_get_emax ()) + exp_max = mpfr_get_emax(); + if (-exp_max > exp_min) + exp_min = - exp_max; + if (step < 1) + step = 1; + + /* check consistency with quadruple precision for random parameters */ + for (prec = prec_min; prec <= prec_max; prec += step) + check_against_quadruple_precision (¶ms, prec, exp_min, exp_max, -1); + + + /* check consistency with quadruple precision for special values: + pure real, pure imaginary, or infinite arguments */ + last_special = count_special_cases (¶ms); + for (special = 0; special < last_special ; special++) + check_against_quadruple_precision (¶ms, prec_max, exp_min, exp_max, + special); + + clear_parameters (¶ms); +} + + +static void +check_against_quadruple_precision (mpc_fun_param_t *params, + mpfr_prec_t prec, + mpfr_exp_t exp_min, mpfr_exp_t exp_max, + int special) +{ + static int rand_counter = 0; + mpc_operand_t *P = params->P; /* developer-friendly alias, used in macros */ + + set_input_precision (params, prec); + set_reference_precision (params, prec); + + set_output_precision (params, 4 * prec); + random_params (params, exp_min, exp_max, special); + + for (first_rnd_mode (params); + is_valid_rnd_mode (params); + next_rnd_mode (params)) + { + MPC_FUNCTION_CALL; + while (double_rounding (params)) + /* try another input parameters until no double rounding occurs when + the extra-precise result is rounded to working precision */ + { + random_params (params, exp_min, exp_max, special); + MPC_FUNCTION_CALL; + } + set_output_precision (params, prec); + + set_mpfr_flags (rand_counter); + MPC_FUNCTION_CALL; + check_mpfr_flags (rand_counter++); + check_data (NULL, params, 0); + +#ifdef MPC_FUNCTION_CALL_SYMMETRIC + MPC_FUNCTION_CALL_SYMMETRIC; + check_data (NULL, params, 0); +#endif + +#ifdef MPC_FUNCTION_CALL_REUSE_OP1 + if (copy_parameter (params, 1, 2) == 0) + { + MPC_FUNCTION_CALL_REUSE_OP1; + check_data (NULL, params, 2); + } +#endif + +#ifdef MPC_FUNCTION_CALL_REUSE_OP2 + if (copy_parameter (params, 1, 3) == 0) + { + MPC_FUNCTION_CALL_REUSE_OP2; + check_data (NULL, params, 3); + } +#endif + +#ifdef MPC_FUNCTION_CALL_REUSE_OP3 + if (copy_parameter (params, 1, 4) == 0) + { + MPC_FUNCTION_CALL_REUSE_OP3; + check_data (NULL, params, 4); + } +#endif + + set_output_precision (params, 4 * prec); + } +} + + +/* special cases */ + +enum { + SPECIAL_MINF, + SPECIAL_MZERO, + SPECIAL_PZERO, + SPECIAL_PINF, + SPECIAL_COUNT, +} special_case; + +static int +count_special_cases (mpc_fun_param_t *params) +{ + int i; + const int start = params->nbout; + const int end = start + params->nbin - 1; /* the last input parameter is the + rounding mode */ + int count = 0; + + for (i = start; i < end; i++) + { + if (params->T[i] == MPFR) + count += SPECIAL_COUNT; + else if (params->T[i] == MPC) + /* special + i x random and random + i x special */ + count += 2 * SPECIAL_COUNT; + } + return count; +} + +static void +special_mpfr (mpfr_ptr x, int special) +{ + switch (special) + { + case SPECIAL_MINF: + mpfr_set_inf (x, -1); + break; + case SPECIAL_MZERO: + mpfr_set_zero (x, -1); + break; + case SPECIAL_PZERO: + mpfr_set_zero (x, +1); + break; + case SPECIAL_PINF: + mpfr_set_inf (x, +1); + break; + } +} + +static void +special_random_mpc (mpc_ptr z, mpfr_exp_t exp_min, mpfr_exp_t exp_max, + int special) +{ + mpfr_ptr special_part; + mpfr_ptr random_part; + int mpfr_special; + + if (special < SPECIAL_COUNT) + { + mpfr_special = special; + special_part = mpc_realref (z); + random_part = mpc_imagref (z); + } + else + { + mpfr_special = special - SPECIAL_COUNT; + special_part = mpc_imagref (z); + random_part = mpc_realref (z); + } + + special_mpfr (special_part, mpfr_special); + test_random_mpfr (random_part, exp_min, exp_max, 128); +} + +static void +random_params (mpc_fun_param_t *params, + mpfr_exp_t exp_min, mpfr_exp_t exp_max, + int special) +{ + int i; + int base_index = 0; + const int start = params->nbout; + const int end = start + params->nbin; + const unsigned int int_emax = 42; /* maximum binary exponent for random + integer */ + + for (i = start; i < end; i++) + { + long int si; + switch (params->T[i]) + { + case NATIVE_INT: + test_random_si (&si, int_emax, 128); + params->P[i].i = (int) si; + break; + case NATIVE_L: + test_random_si (¶ms->P[i].si, int_emax, 128); + break; + case NATIVE_UL: + test_random_si (&si, int_emax, 128); + params->P[i].ui = (unsigned long)si; + break; + + case NATIVE_D: + test_random_d (¶ms->P[i].d, 128); + break; + + case NATIVE_LD: + case NATIVE_DC: case NATIVE_LDC: + /* TODO: draw random value */ + fprintf (stderr, "random_params: type not implemented.\n"); + exit (1); + break; + + case NATIVE_IM: case NATIVE_UIM: + /* TODO: draw random value */ + fprintf (stderr, "random_params: type not implemented.\n"); + exit (1); + break; + + case GMP_Z: + /* TODO: draw random value */ + fprintf (stderr, "random_params: type not implemented.\n"); + exit (1); + break; + case GMP_Q: + /* TODO: draw random value */ + fprintf (stderr, "random_params: type not implemented.\n"); + exit (1); + break; + case GMP_F: + /* TODO: draw random value */ + fprintf (stderr, "random_params: type not implemented.\n"); + exit (1); + break; + + case MPFR: + if (base_index <= special + && special - base_index < SPECIAL_COUNT) + special_mpfr (params->P[i].mpfr, special - base_index); + else + test_random_mpfr (params->P[i].mpfr, exp_min, exp_max, 128); + base_index += SPECIAL_COUNT; + break; + + case MPC: + if (base_index <= special + && special - base_index < 2 * SPECIAL_COUNT) + special_random_mpc (params->P[i].mpc, exp_min, exp_max, + special - base_index); + else + test_random_mpc (params->P[i].mpc, exp_min, exp_max, 128); + base_index += 2 * SPECIAL_COUNT; + break; + + case NATIVE_STRING: + case MPFR_INEX: + case MPC_INEX: + /* unsupported types */ + fprintf (stderr, "random_params: unsupported type.\n"); + exit (1); + break; + + case MPFR_RND: + case MPC_RND: + /* just skip rounding mode(s) */ + break; + } + } +} diff --git a/tests/timag.c b/tests/timag.c index 47cf52c..3d427ba 100644 --- a/tests/timag.c +++ b/tests/timag.c @@ -1,6 +1,6 @@ /* timag -- test file for mpc_imag. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,14 +20,17 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpfr_inex = mpc_imag (P[1].mpfr, P[2].mpc, P[3].mpfr_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (FC, f, mpc_imag); - test_start (); - tgeneric (f, 2, 1024, 1, 4096); + tgeneric_template ("imag.dsc", 2, 1024, 1, 4096); test_end (); diff --git a/tests/tio_str.c b/tests/tio_str.c index 26ca8ff..b4e0c34 100644 --- a/tests/tio_str.c +++ b/tests/tio_str.c @@ -1,6 +1,6 @@ /* tio_str-- Test file for mpc_inp_str and mpc_out_str. -Copyright (C) 2009, 2014 INRIA +Copyright (C) 2009, 2011, 2013, 2014 INRIA This file is part of GNU MPC. @@ -33,7 +33,7 @@ along with this program. If not, see http://www.gnu.org/licenses/ . extern unsigned long line_number; /* character appearing next in the file, may be EOF */ extern int nextchar; -extern const char *rnd_mode[]; +extern const char *mpc_rnd_mode[]; static void check_file (const char* file_name) @@ -87,7 +87,7 @@ check_file (const char* file_name) || size != expected_size) { printf ("mpc_inp_str failed (line %lu) with rounding mode %s\n", - line_number, rnd_mode[rnd]); + line_number, mpc_rnd_mode[rnd]); if (inex != expected_inex) printf(" got inexact value: %d\nexpected inexact value: %d\n", inex, expected_inex); diff --git a/tests/tlog.c b/tests/tlog.c index 83f528d..1bb3cbe 100644 --- a/tests/tlog.c +++ b/tests/tlog.c @@ -1,6 +1,6 @@ /* tlog -- test file for mpc_log. -Copyright (C) 2008, 2009 INRIA +Copyright (C) 2008, 2009, 2013 INRIA This file is part of GNU MPC. @@ -18,18 +18,24 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see http://www.gnu.org/licenses/ . */ -#include #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_log (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_log (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_log); - test_start (); - data_check (f, "log.dat"); - tgeneric (f, 2, 512, 7, 128); + data_check_template ("log.dsc", "log.dat"); + + tgeneric_template ("log.dsc", 2, 512, 7, 128); test_end (); diff --git a/tests/tlog10.c b/tests/tlog10.c index 5591b06..73c8580 100644 --- a/tests/tlog10.c +++ b/tests/tlog10.c @@ -1,6 +1,6 @@ /* tlog10 -- test file for mpc_log10. -Copyright (C) 2012 INRIA +Copyright (C) 2012, 2013 INRIA This file is part of GNU MPC. @@ -18,18 +18,24 @@ You should have received a copy of the GNU Lesser General Public License along with this program. If not, see http://www.gnu.org/licenses/ . */ -#include #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_log10 (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_log10 (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_log10); - test_start (); - data_check (f, "log10.dat"); - tgeneric (f, 2, 512, 7, 128); + data_check_template ("log10.dsc", "log10.dat"); + + tgeneric_template ("log10.dsc", 2, 512, 7, 128); test_end (); diff --git a/tests/tmul.c b/tests/tmul.c index 225cf0e..4331ba9 100644 --- a/tests/tmul.c +++ b/tests/tmul.c @@ -1,6 +1,6 @@ /* tmul -- test file for mpc_mul. -Copyright (C) 2002, 2005, 2008, 2009, 2010, 2011, 2012 INRIA +Copyright (C) 2002, 2005, 2008, 2009, 2010, 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -178,13 +178,21 @@ timemul (void) } #endif +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_mul (P[1].mpc, P[2].mpc, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_SYMMETRIC \ + P[0].mpc_inex = mpc_mul (P[1].mpc, P[3].mpc, P[2].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_mul (P[1].mpc, P[1].mpc, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP2 \ + P[0].mpc_inex = mpc_mul (P[1].mpc, P[2].mpc, P[1].mpc, P[4].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" int main (void) { - DECL_FUNC (C_CC, f, mpc_mul); - f.properties = FUNC_PROP_SYMETRIC; - test_start (); #ifdef TIMING @@ -193,9 +201,11 @@ main (void) check_regular (); - data_check (f, "mul.dat"); - tgeneric (f, 2, 4096, 41, 100); + data_check_template ("mul.dsc", "mul.dat"); + + tgeneric_template ("mul.dsc", 2, 4096, 41, 1024); test_end (); + return 0; } diff --git a/tests/tmul_2si.c b/tests/tmul_2si.c index bf86f18..7829cdb 100644 --- a/tests/tmul_2si.c +++ b/tests/tmul_2si.c @@ -1,6 +1,6 @@ /* tmul_2si -- test file for mpc_mul_2si. -Copyright (C) 2012 INRIA +Copyright (C) 2012, 2013 INRIA This file is part of GNU MPC. @@ -20,14 +20,19 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_mul_2si (P[1].mpc, P[2].mpc, P[3].si, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_mul_2si (P[1].mpc, P[1].mpc, P[3].si, P[4].mpc_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCS, f, mpc_mul_2si); - test_start (); - tgeneric (f, 2, 1024, 7, -1); + tgeneric_template ("mul_2si.dsc", 2, 1024, 7, 1024); test_end (); diff --git a/tests/tmul_2ui.c b/tests/tmul_2ui.c index 97073db..6d5ea70 100644 --- a/tests/tmul_2ui.c +++ b/tests/tmul_2ui.c @@ -1,6 +1,6 @@ /* tmul_2ui -- test file for mpc_mul_2ui. -Copyright (C) 2008, 2012 INRIA +Copyright (C) 2008, 2012, 2013 INRIA This file is part of GNU MPC. @@ -20,14 +20,19 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_mul_2ui (P[1].mpc, P[2].mpc, P[3].ui, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_mul_2ui (P[1].mpc, P[1].mpc, P[3].ui, P[4].mpc_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCU, f, mpc_mul_2ui); - test_start (); - tgeneric (f, 2, 1024, 7, -1); + tgeneric_template ("mul_2ui.dsc", 2, 1024, 7, 1024); test_end (); diff --git a/tests/tmul_fr.c b/tests/tmul_fr.c index 796ab28..32d6f86 100644 --- a/tests/tmul_fr.c +++ b/tests/tmul_fr.c @@ -1,6 +1,6 @@ /* tmul_fr -- test file for mpc_mul_fr. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,22 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_mul_fr (P[1].mpc, P[2].mpc, P[3].mpfr, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_mul_fr (P[1].mpc, P[1].mpc, P[3].mpfr, P[4].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCF, f, mpc_mul_fr); - test_start (); - data_check (f, "mul_fr.dat"); - tgeneric (f, 2, 1024, 7, -1); + data_check_template ("mul_fr.dsc", "mul_fr.dat"); + + tgeneric_template ("mul_fr.dsc", 2, 1024, 7, -1); test_end (); diff --git a/tests/tmul_i.c b/tests/tmul_i.c index 863ed5f..87ae2ce 100644 --- a/tests/tmul_i.c +++ b/tests/tmul_i.c @@ -1,6 +1,6 @@ /* tmul_i -- test file for mpc_mul_i. -Copyright (C) 2008, 2009, 2010, 2011, 2012 INRIA +Copyright (C) 2008, 2009, 2010, 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -80,15 +80,22 @@ check_different_precisions(void) mpc_clear (got); } + +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_mul_i (P[1].mpc, P[2].mpc, P[3].i, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_mul_i (P[1].mpc, P[1].mpc, P[3].i, P[4].mpc_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCI, f, mpc_mul_i); - test_start (); check_different_precisions (); - tgeneric (f, 2, 1024, 7, -1); + + tgeneric_template ("mul_i.dsc", 2, 1024, 7, 1024); test_end (); diff --git a/tests/tmul_si.c b/tests/tmul_si.c index 1d0e0d7..9aba11a 100644 --- a/tests/tmul_si.c +++ b/tests/tmul_si.c @@ -1,6 +1,6 @@ /* tmul_si -- test file for mpc_mul_si. -Copyright (C) 2002, 2005, 2008 INRIA +Copyright (C) 2002, 2005, 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,13 +20,19 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_mul_si (P[1].mpc, P[2].mpc, P[3].si, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_mul_si (P[1].mpc, P[1].mpc, P[3].si, P[4].mpc_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCS, f, mpc_mul_si); test_start (); - tgeneric (f, 2, 1024, 7, -1); + tgeneric_template ("mul_si.dsc", 2, 1024, 7, 1024); test_end (); diff --git a/tests/tmul_ui.c b/tests/tmul_ui.c index e7f62f2..f9a9d87 100644 --- a/tests/tmul_ui.c +++ b/tests/tmul_ui.c @@ -1,6 +1,6 @@ /* tmul_ui -- test file for mpc_mul_ui. -Copyright (C) 2002, 2005, 2008 INRIA +Copyright (C) 2002, 2005, 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,14 +20,19 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_mul_ui (P[1].mpc, P[2].mpc, P[3].si, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_mul_ui (P[1].mpc, P[1].mpc, P[3].si, P[4].mpc_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCU, f, mpc_mul_ui); - test_start (); - tgeneric (f, 2, 1024, 7, -1); + tgeneric_template ("mul_ui.dsc", 2, 1024, 7, 1024); test_end (); diff --git a/tests/tneg.c b/tests/tneg.c index be1c90a..53ed67f 100644 --- a/tests/tneg.c +++ b/tests/tneg.c @@ -1,6 +1,6 @@ /* tneg -- test file for mpc_neg. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,14 +20,22 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_neg (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_neg (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_neg); test_start (); - data_check (f, "neg.dat"); - tgeneric (f, 2, 1024, 1, 0); + data_check_template ("neg.dsc", "neg.dat"); + + tgeneric_template ("neg.dsc", 2, 1024, 1, 0); test_end (); diff --git a/tests/tnorm.c b/tests/tnorm.c index 1dba939..30651ac 100644 --- a/tests/tnorm.c +++ b/tests/tnorm.c @@ -1,6 +1,6 @@ /* tnorm -- test file for mpc_norm. -Copyright (C) 2008, 2011, 2012 INRIA +Copyright (C) 2008, 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -93,15 +93,21 @@ test_underflow (void) mpfr_set_emin (emin); } +#define MPC_FUNCTION_CALL \ + P[0].mpfr_inex = mpc_norm (P[1].mpfr, P[2].mpc, P[3].mpfr_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (FC, f, mpc_norm); - test_start (); - data_check (f, "norm.dat"); - tgeneric (f, 2, 1024, 1, 4096); + data_check_template ("norm.dsc", "norm.dat"); + + tgeneric_template ("norm.dsc", 2, 1024, 1, 4096); + test_underflow (); test_end (); diff --git a/tests/tpl_gmp.c b/tests/tpl_gmp.c new file mode 100644 index 0000000..9899584 --- /dev/null +++ b/tests/tpl_gmp.c @@ -0,0 +1,53 @@ +/* tpl_gmp.c -- Helper functions for mpfr data. + +Copyright (C) 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +void +tpl_read_mpz (mpc_datafile_context_t* datafile_context, mpz_t mpz) +{ + if (datafile_context->nextchar == EOF) { + printf ("Error: Unexpected EOF when reading mpz " + "in file '%s' line %lu\n", + datafile_context->pathname, datafile_context->line_number); + exit (1); + } + ungetc (datafile_context->nextchar, datafile_context->fd); + if (mpz_inp_str (mpz, datafile_context->fd, 0) == 0) { + printf ("Error: Impossible to read mpz " + "in file '%s' line %lu\n", + datafile_context->pathname, datafile_context->line_number); + exit (1); + } + datafile_context->nextchar = getc (datafile_context->fd); + tpl_skip_whitespace_comments (datafile_context); +} + +int +tpl_same_mpz_value (mpz_ptr z1, mpz_ptr z2) +{ + return mpz_cmp (z1, z2) == 0; +} + +void +tpl_copy_mpz (mpz_ptr dest, mpz_srcptr src) +{ + mpz_set (dest, src); +} diff --git a/tests/tpl_mpc.c b/tests/tpl_mpc.c new file mode 100644 index 0000000..395d737 --- /dev/null +++ b/tests/tpl_mpc.c @@ -0,0 +1,65 @@ +/* tpl_mpc.c -- Helper functions for mpc data. + +Copyright (C) 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +void +tpl_read_mpc_rnd (mpc_datafile_context_t* datafile_context, mpc_rnd_t* rnd) +{ + mpfr_rnd_t re, im; + tpl_read_mpfr_rnd (datafile_context, &re); + tpl_read_mpfr_rnd (datafile_context, &im); + *rnd = MPC_RND (re, im); +} + +void +tpl_read_mpc (mpc_datafile_context_t* datafile_context, mpc_data_t* z) +{ + tpl_read_mpfr (datafile_context, mpc_realref (z->mpc), &z->known_sign_real); + tpl_read_mpfr (datafile_context, mpc_imagref (z->mpc), &z->known_sign_imag); +} + +void +tpl_read_mpc_inex (mpc_datafile_context_t* datafile_context, + mpc_inex_data_t *ternarypair) +{ + tpl_read_ternary(datafile_context, &ternarypair->real); + tpl_read_ternary(datafile_context, &ternarypair->imag); +} + + +void +tpl_copy_mpc (mpc_ptr dest, mpc_srcptr src) +{ + /* source and destination are assumed to be of the same precision , so the + copy is exact (no rounding) */ + mpc_set (dest, src, MPC_RNDNN); +} + +int +tpl_check_mpc_data (mpc_ptr got, mpc_data_t expected) +{ + return tpl_same_mpfr_value (mpc_realref (got), + mpc_realref (expected.mpc), + expected.known_sign_real) + && tpl_same_mpfr_value (mpc_imagref (got), + mpc_imagref (expected.mpc), + expected.known_sign_imag); +} diff --git a/tests/tpl_mpfr.c b/tests/tpl_mpfr.c new file mode 100644 index 0000000..d5329ec --- /dev/null +++ b/tests/tpl_mpfr.c @@ -0,0 +1,158 @@ +/* tpl_mpfr.c -- Helper functions for mpfr data. + +Copyright (C) 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + +static mpfr_prec_t +tpl_read_mpfr_prec (mpc_datafile_context_t* datafile_context) +{ + unsigned long prec; + int n; + + if (datafile_context->nextchar == EOF) { + printf ("Error: Unexpected EOF when reading mpfr precision " + "in file '%s' line %lu\n", + datafile_context->pathname, datafile_context->line_number); + exit (1); + } + ungetc (datafile_context->nextchar, datafile_context->fd); + n = fscanf (datafile_context->fd, "%lu", &prec); + if (ferror (datafile_context->fd)) /* then also n == EOF */ + perror ("Error when reading mpfr precision"); + if (n == 0 || n == EOF || prec < MPFR_PREC_MIN || prec > MPFR_PREC_MAX) { + printf ("Error: Impossible mpfr precision in file '%s' line %lu\n", + datafile_context->pathname, datafile_context->line_number); + exit (1); + } + datafile_context->nextchar = getc (datafile_context->fd); + tpl_skip_whitespace_comments (datafile_context); + return (mpfr_prec_t) prec; +} + +static void +tpl_read_mpfr_mantissa (mpc_datafile_context_t* datafile_context, mpfr_ptr x) +{ + if (datafile_context->nextchar == EOF) { + printf ("Error: Unexpected EOF when reading mpfr mantissa " + "in file '%s' line %lu\n", + datafile_context->pathname, datafile_context->line_number); + exit (1); + } + ungetc (datafile_context->nextchar, datafile_context->fd); + if (mpfr_inp_str (x, datafile_context->fd, 0, GMP_RNDN) == 0) { + printf ("Error: Impossible to read mpfr mantissa " + "in file '%s' line %lu\n", + datafile_context->pathname, datafile_context->line_number); + exit (1); + } + datafile_context->nextchar = getc (datafile_context->fd); + tpl_skip_whitespace_comments (datafile_context); +} + +void +tpl_read_mpfr (mpc_datafile_context_t* datafile_context, mpfr_ptr x, + int* known_sign) +{ + int sign; + mpfr_set_prec (x, tpl_read_mpfr_prec (datafile_context)); + sign = datafile_context->nextchar; + tpl_read_mpfr_mantissa (datafile_context, x); + + /* the sign always matters for regular values ('+' is implicit), + but when no sign appears before 0 or Inf in the data file, it means + that only absolute value must be checked. */ + MPC_ASSERT(known_sign != NULL); + *known_sign = + (!mpfr_zero_p (x) && !mpfr_inf_p (x)) || sign == '+' || sign == '-'; +} + +void +tpl_read_mpfr_rnd (mpc_datafile_context_t* datafile_context, mpfr_rnd_t* rnd) +{ + switch (datafile_context->nextchar) + { + case 'n': case 'N': + *rnd = GMP_RNDN; + break; + case 'z': case 'Z': + *rnd = GMP_RNDZ; + break; + case 'u': case 'U': + *rnd = GMP_RNDU; + break; + case 'd': case 'D': + *rnd = GMP_RNDD; + break; + default: + printf ("Error: Unexpected rounding mode '%c' in file '%s' line %lu\n", + datafile_context->nextchar, + datafile_context->pathname, + datafile_context->line_number); + exit (1); + } + + datafile_context->nextchar = getc (datafile_context->fd); + if (datafile_context->nextchar != EOF + && !isspace (datafile_context->nextchar)) { + printf ("Error: Rounding mode not followed by white space " + "in file '%s' line %lu\n", + datafile_context->pathname, datafile_context->line_number); + exit (1); + } + tpl_skip_whitespace_comments (datafile_context); +} + + +void +tpl_read_mpfr_inex (mpc_datafile_context_t* datafile_context, int *ternary) +{ + tpl_read_ternary(datafile_context, ternary); +} + +int +tpl_same_mpfr_value (mpfr_ptr x1, mpfr_ptr x2, int known_sign) +{ + /* The sign of zeroes and infinities is checked only when known_sign is + true. */ + if (mpfr_nan_p (x1)) + return mpfr_nan_p (x2); + if (mpfr_inf_p (x1)) + return mpfr_inf_p (x2) && + (!known_sign || mpfr_signbit (x1) == mpfr_signbit (x2)); + if (mpfr_zero_p (x1)) + return mpfr_zero_p (x2) && + (!known_sign || mpfr_signbit (x1) == mpfr_signbit (x2)); + return mpfr_cmp (x1, x2) == 0; +} + +int +tpl_check_mpfr_data (mpfr_t got, mpfr_data_t expected) +{ + return tpl_same_mpfr_value (got, expected.mpfr, expected.known_sign); +} + +void +tpl_copy_mpfr (mpfr_ptr dest, mpfr_srcptr src) +{ + /* source and destination are assumed to be of the same precision , so the + copy is exact (no rounding) */ + MPC_ASSERT(mpfr_get_prec (dest) == mpfr_get_prec (src)); + mpfr_set (dest, src, GMP_RNDN); +} diff --git a/tests/tpl_native.c b/tests/tpl_native.c new file mode 100644 index 0000000..4b8f48c --- /dev/null +++ b/tests/tpl_native.c @@ -0,0 +1,127 @@ +/* tpl_mpfr.c -- Helper functions for data with native types. + +Copyright (C) 2012, 2013 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +#include "mpc-tests.h" + + +/* int */ + +void +tpl_read_int (mpc_datafile_context_t* datafile_context, int *nread, const char *name) +{ + int n = 0; + + if (datafile_context->nextchar == EOF) + { + printf ("Error: Unexpected EOF when reading int " + "in file '%s' line %lu\n", + datafile_context->pathname, datafile_context->line_number); + exit (1); + } + ungetc (datafile_context->nextchar, datafile_context->fd); + n = fscanf (datafile_context->fd, "%i", nread); + if (ferror (datafile_context->fd) || n == 0 || n == EOF) + { + printf ("Error: Cannot read %s in file '%s' line %lu\n", + name, datafile_context->pathname, datafile_context->line_number); + exit (1); + } + datafile_context->nextchar = getc (datafile_context->fd); + tpl_skip_whitespace_comments (datafile_context); +} + +void +tpl_copy_int (int *dest, const int * const src) +{ + *dest = *src; +} + +/* unsigned long int */ + +void +tpl_read_ui (mpc_datafile_context_t* datafile_context, unsigned long int *ui) +{ + int n = 0; + + if (datafile_context->nextchar == EOF) + { + printf ("Error: Unexpected EOF when reading uint " + "in file '%s' line %lu\n", + datafile_context->pathname, datafile_context->line_number); + exit (1); + } + ungetc (datafile_context->nextchar, datafile_context->fd); + n = fscanf (datafile_context->fd, "%lu", ui); + if (ferror (datafile_context->fd) || n == 0 || n == EOF) + { + printf ("Error: Cannot read uint in file '%s' line %lu\n", + datafile_context->pathname, datafile_context->line_number); + exit (1); + } + datafile_context->nextchar = getc (datafile_context->fd); + tpl_skip_whitespace_comments (datafile_context); +} + +void +tpl_copy_ui (unsigned long int *dest, const unsigned long int * const src) +{ + *dest = *src; +} + + +/* long int */ + +void +tpl_read_si (mpc_datafile_context_t* datafile_context, long int *si) +{ + int n = 0; + + if (datafile_context->nextchar == EOF) + { + printf ("Error: Unexpected EOF when reading sint " + "in file '%s' line %lu\n", + datafile_context->pathname, datafile_context->line_number); + exit (1); + } + ungetc (datafile_context->nextchar, datafile_context->fd); + n = fscanf (datafile_context->fd, "%li", si); + if (ferror (datafile_context->fd) || n == 0 || n == EOF) + { + printf ("Error: Cannot read sint in file '%s' line %lu\n", + datafile_context->pathname, datafile_context->line_number); + exit (1); + } + datafile_context->nextchar = getc (datafile_context->fd); + tpl_skip_whitespace_comments (datafile_context); +} + +void +tpl_copy_si (long int *dest, const long int * const src) +{ + *dest = *src; +} + +/* double */ + +void +tpl_copy_d (double *dest, const double * const src) +{ + *dest = *src; +} diff --git a/tests/tpow.c b/tests/tpow.c index 31ac1ca..7cfcd3c 100644 --- a/tests/tpow.c +++ b/tests/tpow.c @@ -1,6 +1,6 @@ /* tpow -- test file for mpc_pow. -Copyright (C) 2009, 2011, 2012 INRIA +Copyright (C) 2009, 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -52,18 +52,26 @@ reuse_bug (void) } } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_pow (P[1].mpc, P[2].mpc, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_pow (P[1].mpc, P[1].mpc, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP2 \ + P[0].mpc_inex = mpc_pow (P[1].mpc, P[2].mpc, P[1].mpc, P[4].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" int main (void) { - DECL_FUNC (C_CC, f, mpc_pow); - test_start (); reuse_bug (); - data_check (f, "pow.dat"); - tgeneric (f, 2, 1024, 7, 10); + data_check_template ("pow.dsc", "pow.dat"); + + tgeneric_template ("pow.dsc", 2, 1024, 7, 10); test_end (); diff --git a/tests/tpow_d.c b/tests/tpow_d.c index 22de27e..eeb7791 100644 --- a/tests/tpow_d.c +++ b/tests/tpow_d.c @@ -1,6 +1,6 @@ /* tpow_d -- test file for mpc_pow_d. -Copyright (C) 2009 INRIA +Copyright (C) 2009, 2013 INRIA This file is part of GNU MPC. @@ -20,13 +20,11 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" -int -main (void) +static void +test_integer_values (void) { mpc_t z; - test_start (); - mpc_init2 (z, 11); mpc_set_ui_ui (z, 2, 3, MPC_RNDNN); @@ -54,6 +52,23 @@ main (void) } mpc_clear (z); +} + +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_pow_d (P[1].mpc, P[2].mpc, P[3].d, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_pow_d (P[1].mpc, P[1].mpc, P[3].d, P[4].mpc_rnd) + +#include "tgeneric.tpl" + +int +main (void) +{ + test_start (); + + tgeneric_template ("pow_d.dsc", 2, 1024, 15, 20); + + test_integer_values (); /* FIXME: should be in a data file */ test_end (); diff --git a/tests/tpow_fr.c b/tests/tpow_fr.c index 99274af..a19c95f 100644 --- a/tests/tpow_fr.c +++ b/tests/tpow_fr.c @@ -1,6 +1,6 @@ /* tpow_fr -- test file for mpc_pow_fr. -Copyright (C) 2009, 2011, 2012 INRIA +Copyright (C) 2009, 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -47,15 +47,24 @@ test_reuse (void) mpc_clear (z); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_pow_fr (P[1].mpc, P[2].mpc, P[3].mpfr, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_pow_fr (P[1].mpc, P[1].mpc, P[3].mpfr, P[4].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCF, f, mpc_pow_fr); test_start (); - test_reuse (); - data_check (f, "pow_fr.dat"); - tgeneric (f, 2, 1024, 7, 10); + test_reuse (); /* FIXME: remove it, already checked by tgeneric */ + + data_check_template ("pow_fr.dsc", "pow_fr.dat"); + + tgeneric_template ("pow_fr.dsc", 2, 1024, 7, 10); test_end (); diff --git a/tests/tpow_si.c b/tests/tpow_si.c index a3cbfb7..75f01ef 100644 --- a/tests/tpow_si.c +++ b/tests/tpow_si.c @@ -1,6 +1,6 @@ /* tpow_si -- test file for mpc_pow_si. -Copyright (C) 2009, 2010, 2011 INRIA +Copyright (C) 2009, 2010, 2011, 2012 INRIA This file is part of GNU MPC. @@ -74,12 +74,19 @@ compare_mpc_pow (mpfr_prec_t pmax, int iter, unsigned long nbits) mpc_clear (y); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_pow_si (P[1].mpc, P[2].mpc, P[3].si, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_pow_si (P[1].mpc, P[1].mpc, P[3].si, P[4].mpc_rnd) + +#include "data_check.tpl" + int main (void) { - DECL_FUNC (CCS, f, mpc_pow_si); test_start (); - data_check (f, "pow_si.dat"); + + data_check_template ("pow_si.dsc", "pow_si.dat"); compare_mpc_pow (100, 5, 19); diff --git a/tests/tpow_ui.c b/tests/tpow_ui.c index 1c7cc6b..9956d0d 100644 --- a/tests/tpow_ui.c +++ b/tests/tpow_ui.c @@ -1,6 +1,6 @@ /* tpow_ui -- test file for mpc_pow_ui. -Copyright (C) 2009, 2010, 2012 INRIA +Copyright (C) 2009, 2010, 2012, 2013 INRIA This file is part of GNU MPC. @@ -73,13 +73,18 @@ compare_mpc_pow (mpfr_prec_t pmax, int iter, unsigned long nbits) mpc_clear (y); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_pow_ui (P[1].mpc, P[2].mpc, P[3].ui, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_pow_ui (P[1].mpc, P[1].mpc, P[3].ui, P[4].mpc_rnd) + +#include "data_check.tpl" + int main (int argc, char *argv[]) { mpc_t z; - DECL_FUNC (CCU, f, mpc_pow_ui); - if (argc != 1) { mpfr_prec_t p; @@ -108,7 +113,8 @@ main (int argc, char *argv[]) } test_start (); - data_check (f, "pow_ui.dat"); + + data_check_template ("pow_ui.dsc", "pow_ui.dat"); compare_mpc_pow (100, 5, 19); diff --git a/tests/tpow_z.c b/tests/tpow_z.c index 2a897e6..9d1e9c6 100644 --- a/tests/tpow_z.c +++ b/tests/tpow_z.c @@ -1,6 +1,6 @@ /* tpow_z -- test file for mpc_pow_z. -Copyright (C) 2009, 2011 INRIA +Copyright (C) 2009, 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -21,42 +21,45 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include /* for CHAR_BIT */ #include "mpc-tests.h" +static void +test_large (void) +{ + mpc_t z; + mpz_t t; + + mpc_init2 (z, 5); + mpz_init_set_ui (t, 1ul); + + mpz_set_ui (t, 1ul); + mpz_mul_2exp (t, t, sizeof (long) * CHAR_BIT); + mpc_set_ui_ui (z, 0ul, 1ul, MPC_RNDNN); + mpc_pow_z (z, z, t, MPC_RNDNN); + if (mpc_cmp_si_si (z, 1l, 0l) != 0) { + printf ("Error for mpc_pow_z (4*large)\n"); + exit (1); + } + + mpc_clear (z); + mpz_clear (t); +} + +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_pow_z (P[1].mpc, P[2].mpc, P[3].mpz, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_pow_z (P[1].mpc, P[1].mpc, P[3].mpz, P[4].mpc_rnd) + +#include "data_check.tpl" + int main (void) { - mpc_t z; - mpz_t t; - - test_start (); - - mpc_init2 (z, 5); - mpz_init_set_ui (t, 1ul); - mpc_set_ui_ui (z, 17ul, 42ul, MPC_RNDNN); - mpc_pow_z (z, z, t, MPC_RNDNN); - if (mpc_cmp_si_si (z, 17l, 42l) != 0) { - printf ("Error for mpc_pow_z (1)\n"); - exit (1); - } - mpz_set_si (t, -1l); - mpc_set_ui_ui (z, 1ul, 1ul, MPC_RNDNN); - mpc_pow_z (z, z, t, MPC_RNDNN); - mpc_mul_ui (z, z, 2ul, MPC_RNDNN); - if (mpc_cmp_si_si (z, 1l, -1l) != 0) { - printf ("Error for mpc_pow_z (-1)\n"); - exit (1); - } - mpz_set_ui (t, 1ul); - mpz_mul_2exp (t, t, sizeof (long) * CHAR_BIT); - mpc_set_ui_ui (z, 0ul, 1ul, MPC_RNDNN); - mpc_pow_z (z, z, t, MPC_RNDNN); - if (mpc_cmp_si_si (z, 1l, 0l) != 0) { - printf ("Error for mpc_pow_z (4*large)\n"); - exit (1); - } - mpc_clear (z); - mpz_clear (t); - - test_end (); - - return 0; + test_start (); + + data_check_template ("pow_z.dsc", "pow_z.dat"); + + test_large (); + + test_end (); + + return 0; } diff --git a/tests/tproj.c b/tests/tproj.c index 222b697..c63e5b0 100644 --- a/tests/tproj.c +++ b/tests/tproj.c @@ -1,6 +1,6 @@ /* tproj -- test file for mpc_proj. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,22 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_proj (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_proj (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_proj); - test_start (); - tgeneric (f, 2, 1024, 1, 4096); - data_check (f, "proj.dat"); + data_check_template ("proj.dsc", "proj.dat"); + + tgeneric_template ("proj.dsc", 2, 1024, 1, 4096); test_end (); diff --git a/tests/treal.c b/tests/treal.c index c3ab95f..9b13e78 100644 --- a/tests/treal.c +++ b/tests/treal.c @@ -1,6 +1,6 @@ /* treal -- test file for mpc_real. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,14 +20,17 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpfr_inex = mpc_imag (P[1].mpfr, P[2].mpc, P[3].mpfr_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (FC, f, mpc_real); - test_start (); - tgeneric (f, 2, 1024, 1, 4096); + tgeneric_template ("real.dsc", 2, 1024, 1, 4096); test_end (); diff --git a/tests/tsin.c b/tests/tsin.c index 3b09c78..e69baf1 100644 --- a/tests/tsin.c +++ b/tests/tsin.c @@ -1,6 +1,6 @@ /* tsin -- test file for mpc_sin. -Copyright (C) 2007, 2008, 2010 INRIA +Copyright (C) 2007, 2008, 2010, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,22 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_sin (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_sin (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_sin); - test_start (); - data_check (f, "sin.dat"); - tgeneric (f, 2, 512, 7, 7); + data_check_template ("sin.dsc", "sin.dat"); + + tgeneric_template ("sin.dsc", 2, 512, 7, 7); test_end (); diff --git a/tests/tsin_cos.c b/tests/tsin_cos.c index a1e7424..73791e6 100644 --- a/tests/tsin_cos.c +++ b/tests/tsin_cos.c @@ -1,6 +1,6 @@ /* tsin_cos -- test file for mpc_sin_cos. -Copyright (C) 2011 INRIA +Copyright (C) 2011, 2013 INRIA This file is part of GNU MPC. @@ -20,14 +20,269 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +static void random_params (mpc_fun_param_t *params, + mpfr_exp_t exp_min, mpfr_exp_t exp_max, + int special); +static void check_against_quadruple_precision (mpc_fun_param_t *params, + mpc_fun_param_t *params_sin, + mpc_fun_param_t *params_cos, + mpfr_prec_t prec, + mpfr_exp_t exp_min, + mpfr_exp_t exp_max, + int special); + +/* tgeneric(desc, prec_min, prec_max, step, exp_max) checks rounding with + random numbers: + - with precision ranging from prec_min to prec_max with an increment of + step, + - with exponent between -exp_max and exp_max. + - for pure real, pure imaginary and infinite random parameters. + + It also checks parameter reuse. +*/ +static void +tgeneric_custom (mpfr_prec_t prec_min, mpfr_prec_t prec_max, mpfr_prec_t step, + mpfr_exp_t exp_max) +{ + int special = 0; + const int last_special = 8; + mpfr_prec_t prec; + mpfr_exp_t exp_min; + mpc_fun_param_t params; + mpc_fun_param_t params_sin; + mpc_fun_param_t params_cos; + + read_description (¶ms, "sin_cos.dsc"); + init_parameters (¶ms); + read_description (¶ms_sin, "sin.dsc"); + init_parameters (¶ms_sin); + read_description (¶ms_cos, "cos.dsc"); + init_parameters (¶ms_cos); + + /* ask for enough memory */ + set_output_precision (¶ms, 4 * prec_max); + set_input_precision (¶ms, prec_max); + set_reference_precision (¶ms, prec_max); + set_output_precision (¶ms_sin, 4 * prec_max); + set_input_precision (¶ms_sin, prec_max); + set_reference_precision (¶ms_sin, prec_max); + set_output_precision (¶ms_cos, 4 * prec_max); + set_input_precision (¶ms_cos, prec_max); + set_reference_precision (¶ms_cos, prec_max); + + /* sanity checks */ + exp_min = mpfr_get_emin (); + if (exp_max <= 0 || exp_max > mpfr_get_emax ()) + exp_max = mpfr_get_emax(); + if (-exp_max > exp_min) + exp_min = - exp_max; + if (step < 1) + step = 1; + + /* check consistency with quadruple precision for random parameters */ + for (prec = prec_min; prec <= prec_max; prec += step) + check_against_quadruple_precision (¶ms, ¶ms_sin, ¶ms_cos, + prec, exp_min, exp_max, -1); + + /* check consistency with quadruple precision for special values: + pure real, pure imaginary, or infinite arguments */ + for (special = 0; special < last_special ; special++) + check_against_quadruple_precision (¶ms, ¶ms_sin, ¶ms_cos, + prec_max, exp_min, exp_max, + special); + + clear_parameters (¶ms); + clear_parameters (¶ms_sin); + clear_parameters (¶ms_cos); +} + +static void +filter_params (mpc_fun_param_t *params_sin_cos, + mpc_fun_param_t *params, + int index) +{ + /* inex */ + params->P[0].mpc_inex = (index == 0) ? + MPC_INEX1 (params_sin_cos->P[0].mpc_inex) + : MPC_INEX2 (params_sin_cos->P[0].mpc_inex); + + /* output */ + mpc_set (params->P[1].mpc, params_sin_cos->P[1 + index].mpc, MPC_RNDNN); + + /* input */ + mpc_set (params->P[2].mpc, params_sin_cos->P[3].mpc, MPC_RNDNN); + + /* rnd mode is already set */ +} + +static void +gather_params (mpc_fun_param_t *params_sin_cos, + mpc_fun_param_t *params_sin, + mpc_fun_param_t *params_cos) +{ + /* do not check inex value */ + params_sin_cos->P[6].mpc_inex_data.real = TERNARY_NOT_CHECKED; + params_sin_cos->P[6].mpc_inex_data.imag = TERNARY_NOT_CHECKED; + + mpc_set (params_sin_cos->P[7].mpc_data.mpc, + params_sin->P[5].mpc_data.mpc, + MPC_RNDNN); + params_sin_cos->P[7].mpc_data.known_sign_real = -1; + params_sin_cos->P[7].mpc_data.known_sign_imag = -1; + + mpc_set (params_sin_cos->P[8].mpc_data.mpc, + params_cos->P[5].mpc_data.mpc, + MPC_RNDNN); + params_sin_cos->P[8].mpc_data.known_sign_real = -1; + params_sin_cos->P[8].mpc_data.known_sign_imag = -1; +} + +static void +gather_rounding_modes (mpc_fun_param_t *params_sin_cos, + mpc_fun_param_t *params_sin, + mpc_fun_param_t *params_cos) +{ + params_sin_cos->P[4].mpc_rnd = params_sin->P[3].mpc_rnd; + params_sin_cos->P[5].mpc_rnd = params_cos->P[3].mpc_rnd; +} + +static void +check_against_quadruple_precision (mpc_fun_param_t *params, + mpc_fun_param_t *params_sin, + mpc_fun_param_t *params_cos, + mpfr_prec_t prec, + mpfr_exp_t exp_min, mpfr_exp_t exp_max, + int special) +{ + mpc_operand_t *P = params->P; /* developer-friendly alias, used in macros */ + + set_input_precision (params, prec); + set_reference_precision (params, prec); + set_output_precision (params, 4 * prec); + + set_input_precision (params_sin, prec); + set_reference_precision (params_sin, prec); + set_output_precision (params_sin, 4 * prec); + + set_input_precision (params_cos, prec); + set_reference_precision (params_cos, prec); + set_output_precision (params_cos, 4 * prec); + + + for (first_rnd_mode (params_sin); + is_valid_rnd_mode (params_sin); + next_rnd_mode (params_sin)) + { + for (first_rnd_mode (params_cos); + is_valid_rnd_mode (params_cos); + next_rnd_mode (params_cos)) + { + gather_rounding_modes (params, params_sin, params_cos); + do + { + random_params (params, exp_min, exp_max, special); + P[0].mpc_inex = mpc_sin_cos (P[1].mpc, P[2].mpc, P[3].mpc, + P[4].mpc_rnd, P[5].mpc_rnd); + filter_params (params, params_sin, 0); + filter_params (params, params_cos, 1); + } while (double_rounding (params_sin) + || double_rounding (params_cos)); + gather_params (params, params_sin, params_cos); + + set_output_precision (params, prec); + P[0].mpc_inex = mpc_sin_cos (P[1].mpc, P[2].mpc, P[3].mpc, + P[4].mpc_rnd, P[5].mpc_rnd); + check_data (NULL, params, 0); + + set_output_precision (params, 4 * prec); + } + } +} + + +/* special cases */ + +enum { + SPECIAL_MINF, + SPECIAL_MZERO, + SPECIAL_PZERO, + SPECIAL_PINF, + SPECIAL_COUNT, +} special_case; + +static void +special_mpfr (mpfr_ptr x, int special) +{ + switch (special) + { + case SPECIAL_MINF: + mpfr_set_inf (x, -1); + break; + case SPECIAL_MZERO: + mpfr_set_zero (x, -1); + break; + case SPECIAL_PZERO: + mpfr_set_zero (x, +1); + break; + case SPECIAL_PINF: + mpfr_set_inf (x, +1); + break; + } +} + +static void +special_random_mpc (mpc_ptr z, mpfr_exp_t exp_min, mpfr_exp_t exp_max, + int special) +{ + mpfr_ptr special_part; + mpfr_ptr random_part; + int mpfr_special; + + if (special < SPECIAL_COUNT) + { + mpfr_special = special; + special_part = mpc_realref (z); + random_part = mpc_imagref (z); + } + else + { + mpfr_special = special - SPECIAL_COUNT; + special_part = mpc_imagref (z); + random_part = mpc_realref (z); + } + + special_mpfr (special_part, mpfr_special); + test_random_mpfr (random_part, exp_min, exp_max, 128); +} + +static void +random_params (mpc_fun_param_t *params, + mpfr_exp_t exp_min, mpfr_exp_t exp_max, + int special) +{ + int i; + int base_index = 0; + const int start = params->nbout; + const int end = start + params->nbin - 2; + + for (i = start; i < end; i++) + { + if (base_index <= special + && special - base_index < 2 * SPECIAL_COUNT) + special_random_mpc (params->P[i].mpc, exp_min, exp_max, + special - base_index); + else + test_random_mpc (params->P[i].mpc, exp_min, exp_max, 128); + base_index += 2 * SPECIAL_COUNT; + } +} + int main (void) { - DECL_FUNC (CC_C, f, mpc_sin_cos); - test_start (); - tgeneric (f, 2, 512, 13, 7); + tgeneric_custom (2, 512, 13, 7); test_end (); diff --git a/tests/tsinh.c b/tests/tsinh.c index c12f036..48e362a 100644 --- a/tests/tsinh.c +++ b/tests/tsinh.c @@ -1,6 +1,6 @@ /* tsinh -- test file for mpc_sinh. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,22 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_sinh (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_sinh (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_sinh); - test_start (); - data_check (f, "sinh.dat"); - tgeneric (f, 2, 512, 7, 7); + data_check_template ("sinh.dsc", "sinh.dat"); + + tgeneric_template ("sinh.dsc", 2, 512, 7, 7); test_end (); diff --git a/tests/tsqr.c b/tests/tsqr.c index 2ec2099..fa4350a 100644 --- a/tests/tsqr.c +++ b/tests/tsqr.c @@ -1,6 +1,6 @@ /* tsqr -- test file for mpc_sqr. -Copyright (C) 2002, 2005, 2008, 2010, 2011, 2012 INRIA +Copyright (C) 2002, 2005, 2008, 2010, 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -164,10 +164,17 @@ reuse_bug (void) mpc_clear (z1); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_sqr (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_sqr (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_sqr); test_start (); testsqr (247, -65, 8, 24); @@ -180,8 +187,9 @@ main (void) testsqr (0, 1816, 8, 24); testsqr (145, 0, 8, 24); - data_check (f, "sqr.dat"); - tgeneric (f, 2, 1024, 1, 0); + data_check_template ("sqr.dsc", "sqr.dat"); + + tgeneric_template ("sqr.dsc", 2, 1024, 1, 1024); reuse_bug (); diff --git a/tests/tsqrt.c b/tests/tsqrt.c index 2da6842..17d05c3 100644 --- a/tests/tsqrt.c +++ b/tests/tsqrt.c @@ -1,6 +1,6 @@ /* tsqrt -- test file for mpc_sqrt. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,22 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_sqrt (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_sqrt (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_sqrt); - test_start (); - data_check (f, "sqrt.dat"); - tgeneric (f, 2, 1024, 7, 256); + data_check_template ("sqrt.dsc", "sqrt.dat"); + + tgeneric_template ("sqrt.dsc", 2, 1024, 7, 256); test_end (); diff --git a/tests/tstrtoc.c b/tests/tstrtoc.c index 77e34ee..fd1711c 100644 --- a/tests/tstrtoc.c +++ b/tests/tstrtoc.c @@ -28,7 +28,7 @@ extern int nextchar; extern char *pathname; /* names of rounding modes */ -extern const char *rnd_mode[]; +extern const char *mpc_rnd_mode[]; static void check_file (const char* file_name) @@ -103,7 +103,7 @@ check_file (const char* file_name) { printf ("mpc_strtoc(str) failed (line %lu)\nwith base=%d and " "rounding mode %s\n", test_line_number, base, - rnd_mode[rnd]); + mpc_rnd_mode[rnd]); if (inex != MPC_INEX (inex_re, inex_im)) printf ("ternary value: got %s, expected (%s, %s)\n", MPC_INEX_STR (inex), diff --git a/tests/tsub.c b/tests/tsub.c index 658c81e..f9e6e74 100644 --- a/tests/tsub.c +++ b/tests/tsub.c @@ -1,6 +1,6 @@ /* tsub -- test file for mpc_sub. -Copyright (C) 2008, 2011 INRIA +Copyright (C) 2008, 2011, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,24 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_sub (P[1].mpc, P[2].mpc, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_sub (P[1].mpc, P[1].mpc, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP2 \ + P[0].mpc_inex = mpc_sub (P[1].mpc, P[2].mpc, P[1].mpc, P[4].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (C_CC, f, mpc_sub); - test_start (); - data_check (f, "sub.dat"); - tgeneric (f, 2, 1024, 7, -1); + data_check_template ("sub.dsc", "sub.dat"); + + tgeneric_template ("sub.dsc", 2, 1024, 7, 128); test_end (); diff --git a/tests/tsub_fr.c b/tests/tsub_fr.c index 495fdee..6158c65 100644 --- a/tests/tsub_fr.c +++ b/tests/tsub_fr.c @@ -1,6 +1,6 @@ /* tsub_fr -- test file for mpc_sub_fr. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,22 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_sub_fr (P[1].mpc, P[2].mpc, P[3].mpfr, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_sub_fr (P[1].mpc, P[1].mpc, P[3].mpfr, P[4].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCF, f, mpc_sub_fr); - test_start (); - data_check (f, "sub_fr.dat"); - tgeneric (f, 2, 1024, 7, -1); + data_check_template ("sub_fr.dsc", "sub_fr.dat"); + + tgeneric_template ("sub_fr.dsc", 2, 1024, 7, 128); test_end (); diff --git a/tests/tsub_ui.c b/tests/tsub_ui.c index 567ead5..153b5db 100644 --- a/tests/tsub_ui.c +++ b/tests/tsub_ui.c @@ -1,6 +1,6 @@ /* tsub_ui -- test file for mpc_sub_ui. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,14 +20,19 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_sub_ui (P[1].mpc, P[2].mpc, P[3].ui, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_sub_ui (P[1].mpc, P[1].mpc, P[3].ui, P[4].mpc_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CCU, f, mpc_sub_ui); - test_start (); - tgeneric (f, 2, 1024, 7, -1); + tgeneric_template ("sub_ui.dsc", 2, 1024, 7, 1024); test_end (); diff --git a/tests/ttan.c b/tests/ttan.c index c7c672c..db2d3f9 100644 --- a/tests/ttan.c +++ b/tests/ttan.c @@ -1,6 +1,6 @@ /* ttan -- test file for mpc_tan. -Copyright (C) 2008, 2011, 2012 INRIA +Copyright (C) 2008, 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -197,16 +197,24 @@ pure_imaginary_argument (void) mpfr_clear (y); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_tan (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_tan (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_tan); - test_start (); - data_check (f, "tan.dat"); - tgeneric (f, 2, 512, 7, 4); + data_check_template ("tan.dsc", "tan.dat"); + + tgeneric_template ("tan.dsc", 2, 512, 7, 4); + /* FIXME: remove them? */ pure_real_argument (); pure_imaginary_argument (); diff --git a/tests/ttanh.c b/tests/ttanh.c index 26d9fbe..2312b9e 100644 --- a/tests/ttanh.c +++ b/tests/ttanh.c @@ -1,6 +1,6 @@ /* ttanh -- test file for mpc_tanh. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,15 +20,22 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_tanh (P[1].mpc, P[2].mpc, P[3].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP1 \ + P[0].mpc_inex = mpc_tanh (P[1].mpc, P[1].mpc, P[3].mpc_rnd) + +#include "data_check.tpl" +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CC, f, mpc_tanh); - test_start (); - data_check (f, "tanh.dat"); - tgeneric (f, 2, 512, 7, 4); + data_check_template ("tanh.dsc", "tanh.dat"); + + tgeneric_template ("tanh.dsc", 2, 512, 7, 4); test_end (); diff --git a/tests/tui_div.c b/tests/tui_div.c index 40c740a..f63711a 100644 --- a/tests/tui_div.c +++ b/tests/tui_div.c @@ -1,6 +1,6 @@ /* tui_div -- test file for mpc_ui_div. -Copyright (C) 2008, 2011, 2012 INRIA +Copyright (C) 2008, 2011, 2012, 2013 INRIA This file is part of GNU MPC. @@ -21,7 +21,7 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" static void -special (void) +test_special (void) { mpc_t a, b; @@ -85,16 +85,21 @@ special (void) mpc_clear (b); } +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_ui_div (P[1].mpc, P[2].ui, P[3].mpc, P[4].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP2 \ + P[0].mpc_inex = mpc_ui_div (P[1].mpc, P[2].ui, P[1].mpc, P[4].mpc_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CUC, f, mpc_ui_div); - test_start (); - special (); + test_special (); - tgeneric (f, 2, 1024, 7, 4096); + tgeneric_template ("ui_div.dsc", 2, 1024, 7, 4096); test_end (); diff --git a/tests/tui_ui_sub.c b/tests/tui_ui_sub.c index 67c9071..d2a91eb 100644 --- a/tests/tui_ui_sub.c +++ b/tests/tui_ui_sub.c @@ -1,6 +1,6 @@ /* tui_ui_sub -- test file for mpc_ui_ui_sub. -Copyright (C) 2008 INRIA +Copyright (C) 2008, 2013 INRIA This file is part of GNU MPC. @@ -20,14 +20,19 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #include "mpc-tests.h" +#define MPC_FUNCTION_CALL \ + P[0].mpc_inex = mpc_ui_ui_sub (P[1].mpc, P[2].ui, P[3].ui, P[4].mpc, P[5].mpc_rnd) +#define MPC_FUNCTION_CALL_REUSE_OP3 \ + P[0].mpc_inex = mpc_ui_ui_sub (P[1].mpc, P[2].ui, P[3].ui, P[4].mpc, P[5].mpc_rnd) + +#include "tgeneric.tpl" + int main (void) { - DECL_FUNC (CUUC, f, mpc_ui_ui_sub); - test_start (); - tgeneric (f, 2, 1024, 7, -1); + tgeneric_template ("ui_ui_sub.dsc", 2, 1024, 7, 1024); test_end (); diff --git a/tests/ui_div.dsc b/tests/ui_div.dsc new file mode 100644 index 0000000..5bd3a4b --- /dev/null +++ b/tests/ui_div.dsc @@ -0,0 +1,29 @@ +# Description file for mpc_ui_div +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_ui_div +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + unsigned long int + mpc_srcptr + mpc_rnd_t diff --git a/tests/ui_ui_sub.dsc b/tests/ui_ui_sub.dsc new file mode 100644 index 0000000..13b803f --- /dev/null +++ b/tests/ui_ui_sub.dsc @@ -0,0 +1,30 @@ +# Description file for mpc_ui_ui_sub +# +# Copyright (C) 2013 INRIA +# +# This file is part of GNU MPC. +# +# GNU MPC is free software; you can redistribute it and/or modify it under +# the terms of the GNU Lesser General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +#o ption) any later version. +# +# GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +# more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +NAME: + mpc_ui_ui_sub +RETURN: + mpc_inex +OUTPUT: + mpc_ptr +INPUT: + unsigned long int + unsigned long int + mpc_srcptr + mpc_rnd_t -- cgit v1.2.1