CoCoALib-0.9905 date: 23 May 2007


SmallFpDoubleImpl.H

Go to the documentation of this file.
00001 #ifndef CoCoA_SmallFpDoubleImpl_H
00002 #define CoCoA_SmallFpDoubleImpl_H
00003 
00004 //   Copyright (c)  2005  John Abbott
00005 
00006 //   This file is part of the source of CoCoALib, the CoCoA Library.
00007 
00008 //   CoCoALib is free software; you can redistribute it and/or modify
00009 //   it under the terms of the GNU General Public License (version 2)
00010 //   as published by the Free Software Foundation.  A copy of the full
00011 //   licence may be found in the file COPYING in this directory.
00012 
00013 //   CoCoALib is distributed in the hope that it will be useful,
00014 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 //   GNU General Public License for more details.
00017 
00018 //   You should have received a copy of the GNU General Public License
00019 //   along with CoCoA; if not, write to the Free Software
00020 //   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 
00022 
00023 // Header file for the class SmallFpDoubleImpl
00024 
00025 
00026 #include "CoCoA/assert.H"
00027 #include "CoCoA/ZZ.H"
00028 
00029 #include <cstddef>
00030 //using std::size_t;
00031 #include <iosfwd>
00032 // using std::ostream;
00033 #include <cmath>
00034 //using std::floor;
00035 
00036 
00037 namespace CoCoA
00038 {
00039 
00040   class OpenMathOutput; // forward declaration -- defined in OpenMath.H
00041 
00042   /*-----------------------------------------------------------------*/
00043   /** \include SmallFpDoubleImpl.txt  */
00044   /*-----------------------------------------------------------------*/
00045    class SmallFpDoubleImpl
00046     {
00047     public:
00048       SmallFpDoubleImpl(unsigned long p);
00049       SmallFpDoubleImpl(const ZZ& P);      // complains if P is too big or negative
00050     private:
00051       SmallFpDoubleImpl(const SmallFpDoubleImpl&);            // NEVER DEFINED -- copy ctor disabled
00052       SmallFpDoubleImpl& operator=(const SmallFpDoubleImpl&); // NEVER DEFINED -- assignment disabled
00053 
00054     public:
00055       typedef double value_t;
00056       static const std::size_t DatumSize = sizeof(value_t);
00057 
00058       void myAssignZero(value_t& lhs) const;                        ///< lhs = 0
00059       void myAssign(value_t& lhs, value_t x) const;                 ///< lhs = x
00060       void myAssign(value_t& lhs, long n) const;                    ///< lhs = n
00061       void myAssign(value_t& lhs, const ZZ& N) const;               ///< lhs = N
00062       void myNegate(value_t& lhs, value_t x) const;                 ///< lhs = -x
00063       void myAdd(value_t& lhs, value_t x, value_t y) const;         ///< lhs = x+y
00064       void mySub(value_t& lhs, value_t x, value_t y) const;         ///< lhs = x-y
00065       void myMul(value_t& lhs, value_t x, value_t y) const;         ///< lhs = x*y
00066       void myDiv(value_t& lhs, value_t x, value_t y) const;         ///< lhs = x/y
00067       bool myIsDivisible(value_t& lhs, value_t x, value_t y) const; ///< lhs = x/y, if y is non-zero
00068       void myPower(value_t& lhs, value_t x, unsigned long n) const; ///< lhs = x^n
00069       void myOutput(std::ostream& out, value_t x) const;            ///< out << x
00070       void myOutput(OpenMathOutput& OMOut, value_t x) const;        ///< OMOut << x
00071       bool myIsPrintAtom(value_t x) const;
00072       bool myIsPrintedWithMinus(value_t x) const;
00073 
00074       bool myIsZero(value_t x) const;                        ///< x == 0
00075       bool myIsOne(value_t x) const;                         ///< x == 1
00076       bool myIsMinusOne(value_t x) const;                    ///< x == -1
00077       bool myIsInteger(ZZ& N, value_t x) const;  ///< copy value of x into n, result is always true
00078       bool myIsZeroAddMul(value_t& lhs, value_t y, value_t z) const;// lhs += y*z, result says whether lhs == 0.
00079       bool myIsEqual(value_t x, value_t y) const;  // x == y
00080 
00081     private: // Data members
00082       const value_t myModulus;
00083       const value_t myDrop;     // PUBLIC???
00084       const value_t myIterLimit;// PUBLIC???
00085 
00086     private: // auxiliary functions
00087       static value_t CheckCtorArg(unsigned long p);
00088       static value_t CheckCtorArg(const ZZ& P);
00089       static value_t CalcDrop(value_t p);
00090       static value_t CalcIterLimit(value_t p);
00091       static value_t MaxInt();
00092       value_t myReduceMod(value_t n) const; // Assumes n >= 0.
00093     };  // end of class SmallFpDoubleImpl
00094 
00095 
00096   //------------------------------------------------------------
00097   // SmallFpDoubleImpl inline functions
00098   //------------------------------------------------------------
00099 
00100   inline SmallFpDoubleImpl::value_t SmallFpDoubleImpl::myReduceMod(value_t n) const
00101   {
00102     // Can this be usefully improved?
00103     return n - myModulus*std::floor(n/myModulus);
00104   }
00105 
00106 
00107   inline void SmallFpDoubleImpl::myAssignZero(value_t& lhs) const
00108   {
00109     lhs = 0;
00110   }
00111 
00112 
00113   inline void SmallFpDoubleImpl::myAssign(value_t& lhs, value_t x) const
00114   {
00115     CoCoA_ASSERT(x == myReduceMod(x));
00116     lhs = x;
00117   }
00118 
00119 
00120   inline void SmallFpDoubleImpl::myAssign(value_t& lhs, long n) const
00121   {
00122     if (n > 0) { lhs = n%long(myModulus); return; }
00123     lhs = myModulus - (-n)%long(myModulus);
00124     if (lhs == myModulus) lhs = 0;
00125   }
00126 
00127 
00128   inline void SmallFpDoubleImpl::myAssign(value_t& lhs, const ZZ& N) const
00129   {
00130     lhs = mpz_fdiv_ui(mpzref(N), long(myModulus));
00131   }
00132 
00133 
00134   inline void SmallFpDoubleImpl::myNegate(value_t& lhs, value_t x) const
00135   {
00136     CoCoA_ASSERT(lhs == myReduceMod(lhs));
00137     if (x == 0) lhs = x;
00138     else lhs = myModulus-x;
00139   }
00140 
00141 
00142   inline void SmallFpDoubleImpl::myAdd(value_t& lhs, value_t x, value_t y) const
00143   {
00144     CoCoA_ASSERT(x == myReduceMod(x));
00145     CoCoA_ASSERT(y == myReduceMod(y));
00146     lhs = x+y;
00147     if (lhs >= myModulus) lhs -= myModulus;
00148   }
00149 
00150 
00151   inline void SmallFpDoubleImpl::mySub(value_t& lhs, value_t x, value_t y) const
00152   {
00153     CoCoA_ASSERT(x == myReduceMod(x));
00154     CoCoA_ASSERT(y == myReduceMod(y));
00155     if (x < y) lhs = x + (myModulus-y);  // avoid trying to create a negative value
00156     else lhs = x-y;
00157   }
00158 
00159 
00160   inline void SmallFpDoubleImpl::myMul(value_t& lhs, value_t x, value_t y) const
00161   {
00162     CoCoA_ASSERT(x == myReduceMod(x));
00163     CoCoA_ASSERT(y == myReduceMod(y));
00164     lhs = myReduceMod(x*y);
00165   }
00166 
00167 
00168   inline bool SmallFpDoubleImpl::myIsDivisible(value_t& lhs, value_t x, value_t y) const
00169   {
00170     CoCoA_ASSERT(x == myReduceMod(x));
00171     CoCoA_ASSERT(y == myReduceMod(y));
00172     if (y == 0) return false; // cannot call myIsZero here: it is defined below.
00173     myDiv(lhs, x, y);
00174     return true;
00175   }
00176 
00177 
00178   inline bool SmallFpDoubleImpl::myIsPrintAtom(value_t x) const
00179   {
00180     CoCoA_ASSERT(x == myReduceMod(x));
00181     return true;
00182   }
00183 
00184 
00185   inline bool SmallFpDoubleImpl::myIsPrintedWithMinus(value_t x) const
00186   {
00187     CoCoA_ASSERT(x == myReduceMod(x));
00188     return false;
00189   }
00190 
00191 
00192   inline bool SmallFpDoubleImpl::myIsZero(value_t x) const
00193   {
00194     CoCoA_ASSERT(x == myReduceMod(x));
00195     return x == 0;
00196   }
00197 
00198 
00199   inline bool SmallFpDoubleImpl::myIsOne(value_t x) const
00200   {
00201     CoCoA_ASSERT(x == myReduceMod(x));
00202     return x == 1;
00203   }
00204 
00205 
00206   inline bool SmallFpDoubleImpl::myIsMinusOne(value_t x) const
00207   {
00208     CoCoA_ASSERT(x == myReduceMod(x));
00209     return x == myModulus-1;
00210   }
00211 
00212 
00213   inline bool SmallFpDoubleImpl::myIsInteger(ZZ& N, value_t x) const
00214   {
00215     N = long(x); // Would cause trouble if x were greater than the biggest signed long.
00216     return true;
00217   }
00218 
00219 
00220   inline bool SmallFpDoubleImpl::myIsZeroAddMul(value_t& lhs, value_t y, value_t z) const
00221   {
00222     CoCoA_ASSERT(y == myReduceMod(y));
00223     CoCoA_ASSERT(z == myReduceMod(z));
00224     lhs = myReduceMod(lhs+y*z);
00225     return myIsZero(lhs);
00226   }
00227 
00228 
00229   inline bool SmallFpDoubleImpl::myIsEqual(value_t x, value_t y) const
00230   {
00231     CoCoA_ASSERT(x == myReduceMod(x));
00232     CoCoA_ASSERT(y == myReduceMod(y));
00233     return x==y;
00234   }
00235 
00236 
00237 } // end of namespace CoCoA
00238 
00239 
00240 // RCS header/log in the next few lines
00241 // $Header: /Volumes/Home/cocoa/cvs-repository/CoCoALib-0.99/include/CoCoA/SmallFpDoubleImpl.H,v 1.1.1.1 2007/03/09 15:16:11 abbott Exp $
00242 // $Log: SmallFpDoubleImpl.H,v $
00243 // Revision 1.1.1.1  2007/03/09 15:16:11  abbott
00244 // Imported files
00245 //
00246 // Revision 1.7  2007/03/08 18:42:05  cocoa
00247 // Cleaned up whitespace.
00248 //
00249 // Revision 1.6  2007/01/11 14:07:42  cocoa
00250 // -- changed names to arguments called "rsh"
00251 //
00252 // Revision 1.5  2006/12/06 17:27:29  cocoa
00253 // -- removed #include "config.H"
00254 //
00255 // Revision 1.4  2006/11/24 17:22:05  cocoa
00256 // -- removed OpenMathFwd.H
00257 //
00258 // Revision 1.3  2006/11/02 13:25:44  cocoa
00259 // Simplification of header files: the OpenMath classes have been renamed.
00260 // Many minor consequential changes.
00261 //
00262 // Revision 1.2  2006/10/06 14:04:15  cocoa
00263 // Corrected position of #ifndef in header files.
00264 // Separated CoCoA_ASSERT into assert.H from config.H;
00265 // many minor consequential changes (have to #include assert.H).
00266 // A little tidying of #include directives (esp. in Max's code).
00267 //
00268 // Revision 1.1.1.1  2006/05/30 11:39:37  cocoa
00269 // Imported files
00270 //
00271 // Revision 1.4  2006/05/12 16:10:58  cocoa
00272 // Added OpenMathFwd.H, and tidied OpenMath.H.
00273 // Many consequential but trivial changes.
00274 //
00275 // Revision 1.3  2006/03/27 12:21:26  cocoa
00276 // Minor silly changes to reduce number of complaints from some compiler or other.
00277 //
00278 // Revision 1.2  2006/03/12 21:28:34  cocoa
00279 // Major check in after many changes
00280 //
00281 // Revision 1.1.1.1  2005/10/17 10:46:54  cocoa
00282 // Imported files
00283 //
00284 // Revision 1.4  2005/10/14 15:25:07  cocoa
00285 // Major tidying and cleaning to small prime finite fields.
00286 // Several consequential changes.  Improved their documentation.
00287 //
00288 // Added Makefile and script to include/CoCoA/ directory to
00289 // keep library.H up to date.
00290 //
00291 // Revision 1.3  2005/10/12 15:52:09  cocoa
00292 // Completed test-RingFp1 and corrected/cleaned the SmallFp*
00293 // and RingFp* files.
00294 //
00295 // Some minor tidying elsewhere.
00296 //
00297 // Revision 1.2  2005/10/11 16:37:30  cocoa
00298 // Added new small prime finite field class (see RingFpDouble).
00299 //
00300 // Cleaned makefiles and configuration script.
00301 //
00302 // Tidied PPMonoid code (to eliminate compiler warnings).
00303 //
00304 // Fixed bug in RingFloat::myIsInteger.
00305 //
00306 // Revision 1.1  2005/09/22 18:04:17  cocoa
00307 // It compiles; the tests run OK.  The examples compile.
00308 // No documentation -- the mindless eurocrats have rendered
00309 // me mindless too.
00310 //
00311 
00312 #endif

Generated on Wed May 23 13:43:36 2007 for CoCoALib by  doxygen 1.4.6