Conversion example for the ARPREC library
Here we show that the precompiler is also suitable for other C++ libraries such as ARPREC. We take the following example code, this converges a to the value 3 as described in the paper ARPREC: An Arbitrary Precision Computation Package:#include <iostream> using namespace std; int main() { double a=1.0, b=9.03, c=6.01; for( int i=0; i < 80000; i++ ){ a=((a*a)+b)/c; } cout << "a=" << a << endl; double d=3.0; cout << "3.0-a="<<d-a<<endl; return 0; }This is standard c++ code using double precision and when we run it we get the following output:
wschrep@pascal:~/arprec/cpp> g++ -O2 -Wall arprec_example.cpp -o arprec_example wschrep@pascal:~/arprec/cpp> ./arprec_example a=3 3.0-a=1.33227e-13Using an appropriate configuration file aprec.xml we can convert this example to multi-precision automatically:
wschrep@pascal:~/arprec/cpp> precompile -x arprec.xml arprec_example.cpp arprec_example_pre.cpp wschrep@pascal:~/arprec/cpp> cat arpec_example_pre.cpp #include <iostream> #include <iomanip> using namespace std; #include <arprec/mp_real.h> #include <iostream> using namespace std; int main() { mp::mp_init(400); mp_real a= mp_real( 1.0 );mp_real b= mp_real( 9.03 );mp_real c= mp_real( 6.01 ); for( int i=0; i < 80000; i++ ){ a=((a*a)+b)/c; } cout << "a=" << a << endl; mp_real d= mp_real( 3.0 ); cout << "3.0-a="<<d-a<<endl; return 0; }Now we can compile and run our converted example which will now run in 400 requested digits precision and get this as output:
wschrep@pascal:~/arprec/cpp> g++ -I ../include/ -O2 -Wall arprec_example_pre.cpp -o arprec_example_pre ../src/libarprec.a wschrep@pascal:~/arprec/cpp> ./arprec_example_pre a=10 ^ 0 x 3., 3.0-a=10 ^ -60 x 1.36805748486673986331724833453095150520711486802840120545,
As future work we could add an extra <exit> tag so that the insertion of mp::mp_finalize(); before the return statement is also automated (for this short example we just left it out and it seems to run fine without it).