Implémenter Pi avec un template
L’idée est d’utiliser acos(-1) qui donne pour résultat le nombre pi. Pour ce faire -1 sera converti en type T. J’utilise acos de l’en-tête cmath. On remarquera que acos est défini pour les types float, double et long double, en c++11 il peut prendre en entré des types entiers pour retourner des doubles.
template<typename T>
T Pi()
{
return acos(static_cast<T>(-1.0));
}
Vous pouvez aussi utiliser boost pour ce faire il vous faudra inclure constant.hpp.
#include boost/math/constants/constants.hpp
boost::math::constants::pi();
A savoir que boost défini manuellement les valeurs de pi. Ce qui permet de comprendre que la précision avec boost sera meilleur si on va au-delà de la précision du type long double, par exemple si vous utilisez la librairie GMP.
BOOST_DEFINE_MATH_CONSTANT(pi, 3.141592653589793238462643383279502884e+00, "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651e+00")
Voici un exemple de code à exécuter sur C++ Shell.
A noter que j’utilise std::numeric_limits()::digits10. Cette variable permet d’obtenir le nombre de décimal après la virgule qui ne varieront pas selon la précision du type et l’appel de Pi().
// Pi example
#include <iostream> // std::cout
#include <cmath> // std::acos(double)
#include <limits> // std::numeric_limits<T>::digits10
namespace Math
{
template < typename T >
T Pi()
{
return acos(static_cast<T>(-1.0));
}
}
int main ()
{
std::cout << "pi integer:" << Math::Pi<int>() << std::endl;
std::cout.precision(std::numeric_limits<float>::digits10);
std::cout << "pi float:" << Math::Pi<float>() << std::endl;
std::cout.precision(std::numeric_limits<double>::digits10);
std::cout << "pi double:" << Math::Pi<double>() << std::endl;
std::cout.precision(std::numeric_limits<long double>::digits10);
std::cout << "pi long double:" << Math::Pi<long double>() << std::endl;
return 0;
}
Résultats:
pi integer:3
pi float:3.14159
pi double:3.14159265358979
pi long double:3.14159265358979312
Laisser un commentaire