PrintCtrl.cpp

Go to the documentation of this file.
00001 /**
00002  * @file PrintCtrl.cpp
00003  *    Definitions for a simple class that augments the streams printing capabilities
00004  *   (see \ref Cantera::PrintCtrl).
00005  */
00006 /*
00007  * $Author: hkmoffa $
00008  * $Revision: 368 $
00009  * $Date: 2010-01-03 19:46:26 -0500 (Sun, 03 Jan 2010) $
00010  */
00011 /*
00012  * Copywrite 2004 Sandia Corporation. Under the terms of Contract
00013  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00014  * retains certain rights in this software.
00015  * See file License.txt for licensing information.
00016  */
00017 
00018 #include <cmath>
00019 
00020 #include <iostream>
00021 #include <fstream>
00022 
00023 #include "PrintCtrl.h"
00024 
00025 using namespace std;
00026 
00027 namespace Cantera {
00028 
00029 
00030   // Storage for the global crop flag
00031   PrintCtrl::CROP_TYPE_GLOBAL PrintCtrl::GlobalCrop = GCT_NOPREF;
00032 
00033 
00034   PrintCtrl::PrintCtrl(std::ostream &coutProxy, int Ndec,
00035                        CROP_TYPE ctlocal) :
00036     m_cout(coutProxy),
00037     m_Ndec(Ndec),
00038     m_precision(12),
00039     m_wMin(9),
00040     m_wMax(19),
00041     m_cropCntrl(ctlocal)
00042   {
00043 
00044   }
00045 
00046   // Print a double using scientific notation 
00047   /*
00048    * Prints a double using scientific notation in a
00049    * fixed number of spaces
00050    * 
00051    *
00052    *  @param d  double to be printed
00053    *  @param w  Number of spaces to use
00054    *  @param p  Precision 
00055    *
00056    *
00057    */
00058   void PrintCtrl::pr_de_c10(const double din, int p, const int wMin, 
00059                             const int wMax) {
00060     double d = cropAbs10(din, m_Ndec);
00061     pr_de(d, p, wMin, wMax);
00062   }
00063 
00064   // Print a double using scientific notation 
00065   /*
00066    * Prints a double using scientific notation in a
00067    * fixed number of spaces. Rounding of the last digit is carried out
00068    * by the standard c++ printing utilities.
00069    *
00070    *  @param d  double to be printed
00071    *  @param w  Number of spaces to use
00072    *  @param p  Precision 
00073    */
00074   void PrintCtrl::pr_de(const double d, int sigDigIn, const int wMinIn,
00075                         const int wMaxIn) {
00076     int p = m_precision;
00077     if (sigDigIn != -1) {
00078       p = sigDigIn-1;
00079       if (p < 0) p = 0;
00080     }
00081 
00082     int wMin = m_wMin;
00083     if (wMinIn != -1) {
00084       wMin = wMinIn;
00085       if (wMin < 1) wMin = 1;
00086     }
00087     
00088     int wMax = m_wMax;
00089     if (wMaxIn != -1) {
00090       wMax = wMaxIn;
00091       if (wMax < 1) wMax = 1;
00092     }
00093 
00094     if (wMin > wMax) wMax = wMin;
00095 
00096     // Have to do the wMax ourselves, since C++ doesn't seem to 
00097     // have a streams manipulator to do this !?!
00098     double dfabs = fabs(d);
00099     // This is the normal length assuming no sign and an 1.0E+04
00100     // formated exponented
00101     int requestedLength = 6 + p;
00102     if (d < 0.0) {
00103       requestedLength++;
00104     }
00105     if (dfabs < 9.9999999999E-99) {
00106       requestedLength++;
00107     }
00108     if (dfabs > 9.9999999999E99) {
00109       requestedLength++;
00110     }
00111     if (requestedLength > wMax) {
00112       p -= (requestedLength - wMax);
00113       if (p < 0) p = 0;
00114     }
00115 
00116     // Set to upper case and scientific notation
00117     m_cout.setf(ios_base::scientific | ios_base::uppercase);
00118     int wold = m_cout.width(wMin); 
00119     int pold = m_cout.precision(p);
00120 
00121     m_cout << d;
00122     // Return the precision to the previous value;
00123     m_cout.precision(pold);
00124     m_cout.unsetf(ios_base::scientific); 
00125 
00126     // Return width to original
00127     m_cout.width(wold);
00128   }
00129 
00130   // Croup a double at a certain decade level
00131   /*
00132    *    This routine will crop a floating point number at a certain
00133    *  decade lvl. In other words everything below a power of 10^Ndec
00134    *  will be deleted.
00135    *  Note, it currently does not do rounding of the last digit.
00136    *
00137    *   @param d Double to be cropped
00138    *   @param nSig Number of significant digits
00139    *   example:
00140    *    d = 1.1305E-15;
00141    *    Ndec = -16;
00142    *   This routine will return 1.1E-15
00143    *   
00144    *    d = 8.0E-17
00145    *    Ndec = -16
00146    *   This routine will return 0.0
00147    */
00148   double PrintCtrl::cropAbs10(const double d, int Ndec) const {
00149     if (!doCrop()) {
00150       return d;
00151     }
00152     if (Ndec < -301 || Ndec > 301) {
00153       return d;
00154     }
00155     double sgn = 1.0;
00156     if (d < 0.0) sgn = -1.0;
00157     double dfabs = fabs(d);
00158     double  pdec = pow(10.0, (double) Ndec);
00159     if (dfabs < pdec) {
00160       return 0.0;
00161     }
00162     double dl10 = log10(dfabs);
00163     int N10 = (int) dl10;
00164     if (dl10 > -0.0) {
00165       N10 += 1;
00166     }
00167     int nsig = N10 - Ndec;
00168     double retn = cropSigDigits(d, nsig);
00169     return retn;
00170   }
00171 
00172   // Crop a double at a certain number of significant digits
00173   /*
00174    *  This routine will crop a floating point number at a certain
00175    *  number of significant digits. Note, it currently does 
00176    *  rounding up of the last digit.
00177    *
00178    *  example:
00179    *    d = 1.0305E-15;
00180    *    nsig = 3;
00181    *   This routine will return 1.03E-15
00182    */
00183   double PrintCtrl::cropSigDigits(const double d, int nSig) const {
00184     if (!doCrop()) {
00185       return d;
00186     }
00187     if (nSig <=0) nSig = 1;
00188     if (nSig >=9) nSig = 9;
00189     double sgn = 1.0;
00190     if (d < 0.0) sgn = -1.0;
00191     double dfabs = fabs(d);
00192     double dl10 = log10(dfabs);
00193     int N10 = (int) dl10;
00194     if (dl10 > -0.0) {
00195       N10 += 1;
00196     }
00197     int E10 = -N10 + nSig ;
00198     double pfabs = dfabs * pow(10.0, (double) E10);
00199     pfabs *= (1.0 + 1.0E-14);
00200     long int nfabs = (long int) pfabs;
00201     double remainder = pfabs - nfabs;
00202     if (remainder > 0.5) {
00203       nfabs++;
00204     }
00205     double paltabs = (double) nfabs;
00206     double daltabs = paltabs * pow(10.0, (double) -E10);
00207     return (sgn * daltabs);
00208   }
00209   
00210   // Set the default value of N decade
00211   /*
00212    * @param Ndec new value of Ndec
00213    *
00214    * @return returns the old value of Ndec
00215    */
00216   int PrintCtrl::setNdec(int Ndec) {
00217     int nold = m_Ndec;
00218     m_Ndec = Ndec;
00219     return nold;
00220   }
00221 
00222   // Set the default significant digits to output
00223   /*
00224    * @param nSigDigits new value of the sig digits
00225    *
00226    * @return returns the old value of Ndec
00227    */
00228   int PrintCtrl::setSigDigits(int nSigDigits) {
00229     int nold = m_precision + 1;
00230     m_precision = nSigDigits - 1;
00231     if (m_precision < 0) m_precision = 0;
00232     return nold;
00233   }
00234 
00235   // Set the default minimum width
00236   /*
00237    * @param wmin Default minimum width
00238    *
00239    * @return returns the old default
00240    */
00241   int PrintCtrl::setWmin(int wmin) {
00242     int nold = m_wMin;
00243     m_wMin = wmin;
00244     return nold;
00245   }
00246 
00247 
00248   // Set the default maximum width
00249   /*
00250    * @param wmin Default maximum width
00251    *
00252    * @return returns the old default
00253    */
00254   int PrintCtrl::setWmax(int wmax) {
00255     int nold = m_wMax;
00256     m_wMax = wmax;
00257     return nold;
00258   }
00259 
00260   bool PrintCtrl::doCrop() const {
00261     bool retn = ((m_cropCntrl == CT_ON) || (m_cropCntrl == CT_ON_GLOBALOBEY));
00262     if (m_cropCntrl ==  CT_ON_GLOBALOBEY) {
00263       if (GlobalCrop ==  GCT_NOCROP) {
00264         retn = false;
00265       }
00266     } else  if (m_cropCntrl == CT_OFF_GLOBALOBEY) {
00267       if (GlobalCrop == GCT_CROP) {
00268         retn = true;
00269       }
00270     }
00271     return retn;
00272   }
00273 
00274   void PrintCtrl:: setCropCntrl(CROP_TYPE ctlocal) {
00275     m_cropCntrl = ctlocal;
00276   }
00277 }
Generated by  doxygen 1.6.3