Object-oriented Scientific Computing Library: Version 0.910
format_float.h
00001 /*
00002   -------------------------------------------------------------------
00003 
00004   Copyright (C) 2006-2012, Andrew W. Steiner
00005 
00006   This file is part of O2scl.
00007   
00008   O2scl is free software; you can redistribute it and/or modify
00009   it under the terms of the GNU General Public License as published by
00010   the Free Software Foundation; either version 3 of the License, or
00011   (at your option) any later version.
00012   
00013   O2scl 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 O2scl. If not, see <http://www.gnu.org/licenses/>.
00020 
00021   -------------------------------------------------------------------
00022 */
00023 #ifndef O2SCL_FORMAT_FLOAT_H
00024 #define O2SCL_FORMAT_FLOAT_H
00025 
00026 #include <cstdio>
00027 #include <cstdlib>
00028 #include <iostream>
00029 #include <o2scl/err_hnd.h>
00030 #include <o2scl/misc.h>
00031 #include <o2scl/string_conv.h>
00032 
00033 #ifndef DOXYGENP
00034 namespace o2scl {
00035 #endif
00036 
00037   /** \brief Format a floating point number into a Latex or HTML string
00038       
00039       This class formats floating point strings into something 
00040       useful for HTML or Latex documents. For basic use,
00041       simply call either \ref html_mode() or \ref latex_mode() and 
00042       then use \ref convert().
00043 
00044       The base-10 logarithm of the smallest and largest numbers to be
00045       represented without a string akin to "times 10 to the nth power"
00046       can be specified in \ref set_exp_limits(). The number
00047       of significant figures can be specified with set_sig_figs() (the
00048       default is 5).
00049 
00050       To force \ref convert() to adds zeros to the right side of the
00051       mantissa to guarantee that the requested number of significant
00052       digits is given, call \ref set_pad_zeros() with a <tt>true</tt>
00053       argument.
00054 
00055       To force scientific notation for all numbers, set the maximum
00056       exponent to be smaller than the minimum exponent. 
00057 
00058       \note This function does not warn the user if the number
00059       of significant figures requested is larger than the machine 
00060       precision.
00061       \note If the absolute magnitude for either the minimum or
00062       maximum exponent is larger than or equal to the number of 
00063       significant figures, then rounding will automatically 
00064       occur. 
00065 
00066       The format for a normal number is
00067       \verbatim
00068       prefix (sign-string) number suffix
00069       \endverbatim
00070       and in scientific notation is
00071       \verbatim 
00072       sci-prefix (sci-sign-string) number times-string 
00073       exp-prefix (exp-sign-string) exponent exp-suffix sci-suffix
00074       \endverbatim
00075       
00076       \b Examples
00077 
00078       The code
00079       \code 
00080       format_float fd;
00081       fd.latex_mode();
00082       cout << fd.convert(-sqrt(2.0)*1.0e-5) << endl;
00083       cout << fd.convert(sqrt(2.0)*1.0e-2) << endl;
00084       cout << fd.convert(-sqrt(2.0)*1.0e-1) << endl;
00085       \endcode
00086       outputs
00087       \verbatim
00088       $-$1.4142 $\\times 10^{-5}$
00089       0.014142
00090       $-$0.14142
00091       \endverbatim
00092       and the code
00093       \code
00094       format_float fd;
00095       fd.html_mode();
00096       fd.set_sig_figs(7);
00097       fd.set_pad_zeros(true);
00098       cout << fd.convert(1.414e-5) << endl;
00099       cout << fd.convert(1.414e-2) << endl;
00100       \endcode
00101       outputs
00102       \verbatim
00103       1.414000 &times; 10<sup>-5</sup>
00104       0.01414000
00105       \endverbatim
00106 
00107       \future Handle inf's and nan's correctly.
00108       \future Allow change of string for the "+" sign for the exponent
00109   */
00110   class format_float {
00111     
00112   protected:
00113 
00114     /// \name Base text settings
00115     //@{
00116     /// Prefix (default "")
00117     std::string prefx;
00118     /// Suffix (default "")
00119     std::string suffx;
00120     /// Sign string (default "-")
00121     std::string sgn;
00122     /// Sign string in scientific mode (default "-")
00123     std::string sci_sgn;
00124     /// Sign string for exponent in scientific mode (default "-")
00125     std::string exp_sgn;
00126     /// Prefix in scientific mode (default "")
00127     std::string sci_prefx;
00128     /// Suffix in scientific mode (default "")
00129     std::string sci_suffx;
00130     /// Exponent prefix (default "")
00131     std::string exp_prefx;
00132     /// Exponent suffix (default "")
00133     std::string exp_suffx;
00134     /// Times symbol for scientific mode (default " x ")
00135     std::string tmes;
00136     /// String for numbers which are not finite (default "Nan")
00137     std::string not_finte;
00138     /// String for zeros (default "0")
00139     std::string zeros;
00140     //@}
00141     
00142     /// \name Other settings
00143     //@{
00144     /// Number of significant figures (default 5)
00145     size_t sig_fgs;
00146     /// Number of digits in exponent (default 0 which prints the minimum)
00147     size_t exp_dgs;
00148     /// Lower limit for automatic mode (default -2)
00149     int ex_mn;
00150     /// Upper limit for automatic mode (default 3)
00151     int ex_mx;
00152     /// If true, pad with zeros (default false)
00153     bool pad_zeros;
00154     /** \brief If true, show the sign of the exponent when 
00155         it's positive (default false)
00156     */
00157     bool show_exp_sgn;
00158     /// The decimal point (default <tt>'.'</tt>)
00159     std::string dpt;
00160     //@}
00161     
00162     /** \brief Remove extra zeros and decimal point from mantisaa
00163      */
00164     int remove_zeros_dpt(std::string &s);
00165 
00166   public:
00167 
00168     format_float();
00169 
00170     /// \name Basic usage
00171     //@{
00172     /** \brief Set HTML mode
00173         
00174         This function is equivalent to the settings:
00175         \code
00176         set_prefix("");
00177         set_sign("-");
00178         set_suffix("");
00179         set_sci_prefix("");
00180         set_times(" &times; ");
00181         set_exp_prefix("10<sup>");
00182         set_exp_sign("-");
00183         set_sci_sign("-");
00184         set_exp_suffix("</sup>");
00185         set_sci_suffix("");
00186         set_not_finite("Nan");
00187         set_zero("0");
00188         set_exp_digits(0);
00189         set_show_exp_sign(false);
00190         \endcode
00191     */
00192     int html_mode();
00193 
00194     /** \brief Set Latex mode
00195 
00196         This function is equivalent to the settings:
00197         \code
00198         set_prefix("");
00199         set_sign("$-$");
00200         set_suffix("");
00201         set_sci_prefix("");
00202         set_times(" $\\times ");
00203         set_exp_prefix("10^{");
00204         set_exp_sign("-");
00205         set_sci_sign("$-$");
00206         set_exp_suffix("}");
00207         set_sci_suffix("");
00208         set_not_finite("Nan");
00209         set_zero("0");
00210         set_exp_digits(0);
00211         set_show_exp_sign(false);
00212         \endcode
00213         
00214         \note This setting assumes that the user is not 
00215         in LaTeX's "math mode" already.
00216     */
00217     int latex_mode();
00218     
00219     /** \brief C-like mode
00220 
00221         This reproduces the default settings of \c cout in automatic
00222         mode. Obviously it is faster to use iostreams than to format
00223         numbers with this class. Nevertheless, this mode is very
00224         useful for testing to ensure that this class processes the
00225         numbers correctly at the requested precision.
00226 
00227         This function is equivalent to the settings:
00228         \code
00229         set_prefix("");
00230         set_sign("-");
00231         set_suffix("");
00232         set_sci_prefix("");
00233         set_times("e");
00234         set_exp_prefix("");
00235         set_exp_sign("-");
00236         set_sci_sign("-");
00237         set_exp_suffix("");
00238         set_sci_suffix("");
00239         set_not_finite("NaN");
00240         set_zero("0");
00241         set_exp_limits(-4,5);
00242         set_exp_digits(2);
00243         set_show_exp_sign(true);
00244         \endcode
00245     */
00246     int c_mode();
00247 
00248     /// Convert a floating point number to a string
00249     std::string convert(double x, bool debug=false);
00250     //@}
00251     
00252     /** \name Set text settings
00253 
00254         These are modified by the functions html_mode() and latex_mode()
00255     */
00256     //@{
00257     /// set prefix
00258     int set_prefix(std::string prefix) {
00259       prefx=prefix;
00260       return 0;
00261     }
00262 
00263     /// Set suffix
00264     int set_suffix(std::string suffix) {
00265       suffx=suffix;
00266       return 0;
00267     }
00268 
00269     /// Set prefix for scientific notation
00270     int set_sci_prefix(std::string sci_prefix) {
00271       sci_prefix=sci_prefx;
00272       return 0;
00273     }
00274 
00275     /// Set suffix for scientific notation
00276     int set_sci_suffix(std::string sci_suffix) {
00277       sci_suffx=sci_suffix;
00278       return 0;
00279     }
00280 
00281     /// Set prefix for exponent
00282     int set_exp_prefix(std::string exp_prefix) {
00283       exp_prefx=exp_prefix;
00284       return 0;
00285     }
00286 
00287     /// Set suffix for exponent
00288     int set_exp_suffix(std::string exp_suffix) {
00289       exp_suffx=exp_suffix;
00290       return 0;
00291     }
00292 
00293     /// Set sign
00294     int set_sign(std::string sign) {
00295       sgn=sign;
00296       return 0;
00297     }
00298 
00299     /// Set sign for exponent
00300     int set_exp_sign(std::string exp_sign) {
00301       exp_sgn=exp_sign;
00302       return 0;
00303     }
00304 
00305     /// Set policy for showing positive exponent sign
00306     int set_show_exp_sign(bool b) {
00307       show_exp_sgn=b;
00308       return 0;
00309     }
00310 
00311     /// Set sign for scientific notation
00312     int set_sci_sign(std::string sci_sign) {
00313       sci_sgn=sci_sign;
00314       return 0;
00315     }
00316 
00317     /// Set times
00318     int set_times(std::string times) {
00319       tmes=times;
00320       return 0;
00321     }
00322 
00323     /// Set zero
00324     int set_zero(std::string zero) {
00325       zeros=zero;
00326       return 0;
00327     }
00328 
00329     /// Set string for numbers which are not finite
00330     int set_not_finite(std::string not_finite) {
00331       not_finte=not_finite;
00332       return 0;
00333     }
00334     //@}
00335 
00336     /** \name Set other settings
00337 
00338         These are not modified by the functions html_mode() and latex_mode()
00339     */
00340     //@{
00341     /// Set the exponent limits
00342     int set_exp_limits(int min, int max) {
00343       ex_mn=min;
00344       ex_mx=max;
00345       return 0;
00346     }
00347     
00348     /** \brief Set the number of significant figures (argument has
00349         maximum of 15 and cannot be zero)
00350      */
00351     int set_sig_figs(size_t sig_figs) {
00352       if (sig_fgs==0 || sig_figs>15) {
00353         O2SCL_ERR2_RET("Argument must be less than or equal to 15",
00354                        "in format_float::set_sig_figs().",gsl_einval);
00355       }
00356       sig_fgs=sig_figs;
00357       return 0;
00358     }
00359 
00360     /// Set pad zeros
00361     int set_pad_zeros(bool pad) {
00362       pad_zeros=pad;
00363       return 0;
00364     }
00365 
00366     /// Set decimal point
00367     int set_dec_point(std::string dec_point) {
00368       dpt=dec_point;
00369       return 0;
00370     }
00371 
00372     /// Set minimum number of digits in the exponent
00373     int set_exp_digits(size_t d) {
00374       exp_dgs=d;
00375       return 0;
00376     }
00377     //@}
00378 
00379     /** \name Get text settings
00380 
00381         These are modified by the functions html_mode() and latex_mode()
00382     */
00383     //@{
00384     /// Get prefix
00385     std::string get_prefix() {
00386       return prefx;
00387     }
00388     
00389     /// Get suffix
00390     std::string get_suffix() {
00391       return suffx;
00392     }
00393     
00394     /// Get prefix for scientific notation
00395     std::string get_sci_prefix() {
00396       return sci_prefx;
00397     }
00398     
00399     /// Get suffix for scientific notation
00400     std::string get_sci_suffix() {
00401       return sci_suffx;
00402     }
00403     
00404     /// Get prefix for exponent
00405     std::string get_exp_prefix() {
00406       return exp_prefx;
00407     }
00408     
00409     /// Get suffix for exponent
00410     std::string get_exp_suffix() {
00411       return exp_suffx;
00412     }
00413     
00414     /// Get sign
00415     std::string get_sign() {
00416       return sgn;
00417     }
00418     
00419     /// Get sign for exponent
00420     std::string get_exp_sign() {
00421       return exp_sgn;
00422     }
00423     
00424     /// Get sign for scientific notation
00425     std::string get_sci_sign() {
00426       return sci_sgn;
00427     }
00428     
00429     /// Get times
00430     std::string get_times() {
00431       return tmes;
00432     }
00433     
00434     /// Get zero
00435     std::string get_zero() {
00436       return zeros;
00437     }
00438     
00439     /// Get string for numbers which are not finite
00440     std::string get_not_finite() {
00441       return not_finte;
00442     }
00443     //@}
00444 
00445     /** \name Get other settings
00446 
00447         These are not modified by the functions html_mode() and latex_mode()
00448     */
00449     //@{
00450     /// Get minimum exponent
00451     int get_exp_min() {
00452       return ex_mn;
00453     }
00454 
00455     /// Get maximum exponent
00456     int get_exp_max() {
00457       return ex_mx;
00458     }
00459     
00460     /// Get sig_figs
00461     size_t get_sig_figs() {
00462       return sig_fgs;
00463     }
00464     
00465     /// Get pad_zeros
00466     bool get_pad_zeros() {
00467       return pad_zeros;
00468     }
00469 
00470     /// Get decimal point
00471     std::string get_dec_point() {
00472       return dpt;
00473     }
00474     //@}
00475 
00476   };
00477 
00478 #ifndef DOXYGENP
00479 }
00480 #endif
00481 
00482 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.