mpz_wrapper.H

Go to the documentation of this file.
00001 #ifndef mpz_wrapper_dot_H_header
00002 #define mpz_wrapper_dot_H_header
00003 
00004 
00010 #include <cstdlib>
00011 #include <iomanip>
00012 #include <iostream>
00013 #include <string>
00014 #include <gmp.h>
00015 
00017 namespace my_mpz_wrapper
00018 {
00019 
00020 using std::cerr;
00021 using std::endl;
00022 
00023 
00024 inline unsigned long int mpz_remainder_ui_(const mpz_t n, const unsigned long int d)
00025 {
00026   // should speedup some easy cases...
00027   if (d==1 || d==2 || d==4 || d==8 || d==16 || d==32 || d==64 || d==128)
00028    {
00029      unsigned long int h = (n->_mp_d[0]);
00030      return (n->_mp_size > 0) ? h&(d-1)
00031                               : (n->_mp_size < 0) ? d-(h&(d-1)) : 0;
00032    }
00033   else
00034    return mpz_fdiv_ui(n,d);
00035 }
00036 
00037 
00038 inline unsigned long int mpz_remainder_ui(const mpz_t n, const unsigned long int d)
00039 {
00040   // refer gmp manual:
00041   // "unsigned long int mpz_fdiv_ui(mpz_t n, unsigned long int d)" returns
00042   // the remainder of the division; except for not needing any mpz_t result
00043   // value it is identical to
00044   // "unsigned long int mpz_mod_ui(mpz_t t, mpz_t n, unsigned long int d)".
00045   
00046   // I find the name "mpz_fdiv_ui" too much ambiguous.
00047   // Defining "unsigned long int mpz_mod_ui(mpz_t n, unsigned long int d)"
00048   // would be somewhat more straight forward, but it is also risky, because
00049   // one might assume a real gmp-function and not a wrapper function.
00050   // mpz_remainder_ui can easily be detected as a wrapper function just
00051   // by grepping the sources...
00052 
00053   // As this is a wrapper, we can add some optimizations, too
00054  
00055   return (__builtin_constant_p(d)) ? mpz_remainder_ui_(n,d) : mpz_fdiv_ui(n,d);
00056 }
00057 
00058 
00059 #if defined(mpz_odd_p)
00060  // replace mpz_odd_p / mpz_even_p macros with inline-C++
00061  // (better type checking + more explicit casts) 
00062 
00063 #undef mpz_odd_p
00064 #undef mpz_even_p
00065 
00067 inline int mpz_odd_p(const mpz_t z)
00068 {
00069   return static_cast<int>(z->_mp_size != 0) & static_cast<int>(z->_mp_d[0]);
00070 }
00071 
00073 inline int mpz_even_p(const mpz_t z)
00074 {
00075   return !mpz_odd_p(z);
00076 }
00077 
00078 #endif
00079 
00080 
00081 const int probab_prime_checks = 25; // #rounds for mpz_probab_prime, needed at various places
00082 
00083 const int mpzbase_f = 32; // mpz-I/O format for fileoperations
00084 // remark:
00085 // mpzbase_f=36: highest allowed base (refer gmp manual),
00086 //               compatible with former versions (up to V2.95),
00087 //               less space, but also computational less efficient.
00088 // mpzbase_f=32: is a power of two (and therefore computational more efficient
00089 //               since conversion routines can use shifts instead of expensive
00090 //               divisions; refer gmp source).
00091 
00092 // For human readable input and output we use decimal system
00093 
00094 
00096 inline std::ostream& operator << (std::ostream& ostr, const mpz_t value)
00097 { 
00098   size_t size = mpz_sizeinbase(value,10); 
00099   char* str = new char [size+2];
00100   str[size]='\1'; // to suppress warnings about uninitialised value(s) issued by valgrind 
00101   mpz_get_str(str, 10, value);
00102   if (str[size])
00103    {
00104      if (str[size-1]=='\0') --size;
00105      else if (str[size+1]=='\0') ++size;
00106      else
00107       {
00108         MARK; exit(1);
00109       }
00110    }
00111 #if 1
00112   ostr << str << " (" << size << ")";
00113 #else
00114   ostr << str;
00115   if (size>6) ostr << " (" << size << ")";
00116 #endif
00117   delete [] str;              
00118   return ostr;
00119 }
00120 
00122 inline std::istream& operator >> (std::istream& istr, mpz_t value)
00123 { 
00124   
00125   std::string s;
00126   istr >> s;
00127   if (mpz_set_str(value, s.c_str(), 10))
00128    {
00129      MARK;
00130      cerr << "invalid number read." << endl;
00131      cerr << "given: *" << s << "*" << endl;
00132      cerr << "mpz_t: *" << value << "*" << endl;
00133      istr.setstate(std::ios::failbit);
00134      //exit(1);
00135    } else  istr >> s; // read over Sizeinbase
00136   return istr;
00137 }
00138 
00139 } // end of namespace my_mpz_wrapper
00140 
00141 #endif /* of mpz_wrapper_dot_H_header */

Generated on Wed Nov 7 23:29:25 2007 for Qsieve by  doxygen 1.5.4