00001 ///////////////////////////////////////////////////////////////////////////// 00002 /// 00003 /// @file numberpi.h 00004 /// 00005 /// Rigorous bounds for the number pi. 00006 /// This file contains the definition of two numbers which bound 00007 /// the number pi from below and from above. 00008 /// These numbers are provided for two types: double and long double. 00009 /// 00010 /// @author Pawel Pilarczyk 00011 /// 00012 ///////////////////////////////////////////////////////////////////////////// 00013 00014 // Copyright (C) 2007-2010 by Pawel Pilarczyk. 00015 // 00016 // This file is part of my research program package. This is free software; 00017 // you can redistribute it and/or modify it under the terms of the GNU 00018 // General Public License as published by the Free Software Foundation; 00019 // either version 2 of the License, or (at your option) any later version. 00020 // 00021 // This software is distributed in the hope that it will be useful, 00022 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00024 // GNU General Public License for more details. 00025 // 00026 // You should have received a copy of the GNU General Public License along 00027 // with this software; see the file "license.txt". If not, write to the 00028 // Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 00029 // MA 02111-1307, USA. 00030 00031 // Started on December 23, 2008. Last revision: December 31, 2008. 00032 00033 00034 #ifndef _FINRESDYN_NUMBERPI_H_ 00035 #define _FINRESDYN_NUMBERPI_H_ 00036 00037 00038 // BOOST (this header must be included first) 00039 #include "boost/numeric/interval.hpp" 00040 00041 00042 // -------------------------------------------------- 00043 // -------- a class that holds the number pi -------- 00044 // -------------------------------------------------- 00045 00046 /// A class that holds the number pi. 00047 template <class numType> 00048 class tNumberPi 00049 { 00050 public: 00051 /// A function that returns a lower bound for the number Pi. 00052 static const numType &lowerBound (); 00053 00054 /// A function that returns an upper bound for the number Pi. 00055 static const numType &upperBound (); 00056 00057 private: 00058 /// A lower bound for the number pi. 00059 static numType theLowerPi; 00060 00061 /// An upper bound for the number pi. 00062 static numType theUpperPi; 00063 00064 /// Computation of a lower and an upper bound for the number pi. 00065 static void computeBoundsForPi (); 00066 00067 }; /* class tNumberPi */ 00068 00069 // -------------------------------------------------- 00070 00071 template <class numType> 00072 inline const numType &tNumberPi<numType>::lowerBound () 00073 { 00074 if (theLowerPi < 1) 00075 computeBoundsForPi (); 00076 return theLowerPi; 00077 } /* lowerBound */ 00078 00079 template <class numType> 00080 inline const numType &tNumberPi<numType>::upperBound () 00081 { 00082 if (theUpperPi < 1) 00083 computeBoundsForPi (); 00084 return theUpperPi; 00085 } /* upperBound */ 00086 00087 template <class numType> 00088 numType tNumberPi<numType>::theLowerPi = 0; 00089 00090 template <class numType> 00091 numType tNumberPi<numType>::theUpperPi = 0; 00092 00093 // -------------------------------------------------- 00094 00095 template <> 00096 inline void tNumberPi<float>::computeBoundsForPi () 00097 { 00098 theLowerPi = boost::numeric::interval_lib::constants:: 00099 pi_lower<float> (); 00100 theUpperPi = boost::numeric::interval_lib::constants:: 00101 pi_upper<float> (); 00102 return; 00103 } /* computeBoundsForPi */ 00104 00105 template <> 00106 inline void tNumberPi<double>::computeBoundsForPi () 00107 { 00108 theLowerPi = boost::numeric::interval_lib::constants:: 00109 pi_lower<double> (); 00110 theUpperPi = boost::numeric::interval_lib::constants:: 00111 pi_upper<double> (); 00112 return; 00113 } /* computeBoundsForPi */ 00114 00115 template <> 00116 inline void tNumberPi<long double>::computeBoundsForPi () 00117 { 00118 volatile long double approxPi = 3.141592653589793238462643383279\ 00119 502884197169399375105820974944592307816406286208998628034825342117067\ 00120 982148086513282306647093844609550582231725359408128481117450284102701\ 00121 9385211055596446229489549303820L; 00122 long double approxPi1 = approxPi; 00123 theLowerPi = tRounding<long double>::sub_down (approxPi1, 1e-198L); 00124 long double approxPi2 = approxPi; 00125 theUpperPi = tRounding<long double>::add_up (approxPi2, 1e-198L); 00126 if (theLowerPi == theUpperPi) 00127 throw "Wrong rounding for pi."; 00128 if (theLowerPi >= approxPi) 00129 throw "Wrong lower bound for pi."; 00130 if (theUpperPi <= approxPi) 00131 throw "Wrong upper bound for pi."; 00132 return; 00133 } /* computeBoundsForPi */ 00134 00135 00136 #endif // _FINRESDYN_NUMBERPI_H_ 00137
1.5.3