/* struct Place : 求 N 有多少位数字 */ template <long long N> struct Place;
template <long long N> struct Place { static const int value = Place<N / 10>::value + 1; static const int place = value; };
template <> struct Place<0> { static const int value = 0; static const int place = 1; };
/* struct Sqrt : 开平方,结果为 value */ template <long long N> struct Sqrt;
/* struct Exp10 : 10 的 N 次方幂,也就是 1 后加 N 个零 */ template <int N> struct Exp10 { static const long long value = Exp10<N-1>::value * 10; };
template <> struct Exp10<0> { static const long long value = 1; };
/* struct SqrtTwoPlace : 求两位数以下的整数的平方根 */ template <long long N> struct SqrtTwoPlace { static const long long value = SqrtTwoPlace<N-1>::value; };
#define SqrtTwoPlaceDef(NN, N) template <> struct SqrtTwoPlace<NN> \ { static const long long value = N; }
SqrtTwoPlaceDef (0, 0); SqrtTwoPlaceDef (1, 1); SqrtTwoPlaceDef (4, 2); SqrtTwoPlaceDef (9, 3); SqrtTwoPlaceDef (16, 4); SqrtTwoPlaceDef (25, 5); SqrtTwoPlaceDef (36, 6); SqrtTwoPlaceDef (49, 7); SqrtTwoPlaceDef (64, 8); SqrtTwoPlaceDef (81, 9);
/* struct SqrtDiv : 求 N 开平方的结果 */ template <bool finish, long long N, long long x> struct SqrtDiv;
template <long long N, long long x0> struct SqrtDiv<false, N, x0> { private: static const long long x = (N / x0 + x0) / 2; static const bool finish = (x*x <= N) && ((x+1)*(x+1) > N);
public: static const long long value = SqrtDiv<finish, N, x>::value; };
template <long long N, long long x> struct SqrtDiv<true, N, x> { static const long long value = x; };
/* struct Sqrt : 开平方 */ template <long long N> struct Sqrt { private: static const int place = Place<N>::value; static const int zero = (place % 2 == 1) ? place - 1 : place - 2; static const long long head = N / Exp10<zero>::value;
static const long long x0 = SqrtTwoPlace<head>::value * Exp10<zero / 2>::value;
public: static const long long value = SqrtDiv<false, N, x0>::value; };
template <> struct Sqrt<0> { static const long long value = 0; };
/* struct Fraction : 分数,first 为分子,second 为分母。value 为 double 值 */ template <long long M, long long N> struct Fraction;
template <long long M, long long N> struct Fraction { static const long long first = M; static const long long second = N;
static const double value = static_cast<double>(first) / second; };
/* struct FractionSqrt : 开平方。分子、分母同时开方 */ template <typename FractionType> struct FractionSqrt { private: static const long long first1 = FractionType::first; static const long long second1 = FractionType::second;
static const long long first = Sqrt<first1>::value; static const long long second = Sqrt<second1>::value; public: typedef Fraction<first, second> ValueType; };
/* struct FractionSqrt2 : 开平方,但保持分母不变 */ template <typename FractionType> struct FractionSqrt2 { private: static const long long first1 = FractionType::first;
static const long long second = FractionType::second; static const long long first = Sqrt<first1 * second>::value; public: typedef Fraction<first, second> ValueType; };
/* struct FractionAdd : 加法,结果为 ValueType */ template <typename FractionType1, typename FractionType2> struct FractionAdd { private: static const long long first1 = FractionType1::first; static const long long second1 = FractionType1::second; static const long long first2 = FractionType2::first; static const long long second2 = FractionType2::second; static const long long first = first1 * second2 + first2 * second1; static const long long second = second1 * second2; public: typedef Fraction<first, second> ValueType; };
template <long long First1, long long First2, long long Second> struct FractionAdd<Fraction<First1, Second>, Fraction<First2, Second> > { private: static const long long first = First1 + First2; static const long long second = Second; public: typedef Fraction<first, second> ValueType; };
/* struct FractionSub : 减法,结果为 ValueType */ template <typename FractionType1, typename FractionType2> struct FractionSub { private: static const long long first1 = FractionType1::first; static const long long second1 = FractionType1::second; static const long long first2 = FractionType2::first; static const long long second2 = FractionType2::second; static const long long first = first1 * second2 - first2 * second1; static const long long second = second1 * second2; public: typedef Fraction<first, second> ValueType; };
template <long long First1, long long First2, long long Second> struct FractionSub<Fraction<First1, Second>, Fraction<First2, Second> > { private: static const long long first = First1 - First2; static const long long second = Second; public: typedef Fraction<first, second> ValueType; };
/* struct FractionMul : 乘法,结果在 ValueType */ template <typename FractionType1, typename FractionType2> struct FractionMul { private: static const long long first1 = FractionType1::first; static const long long second1 = FractionType1::second; static const long long first2 = FractionType2::first; static const long long second2 = FractionType2::second; static const long long first = first1 * first2; static const long long second = second1 * second2; public: typedef Fraction<first, second> ValueType; };
template <long long First1, long long First2, long long Second1> struct FractionMul<Fraction<First1, Second1>, Fraction<First2, First1> > { private: static const long long first = First2; static const long long second = Second1; public: typedef Fraction<first, second> ValueType; };
template <long long First1, long long First2, long long Second1> struct FractionMul<Fraction<First2, First1>, Fraction<First1, Second1> > { private: static const long long first = First2; static const long long second = Second1; public: typedef Fraction<first, second> ValueType; };
template <long long First, long long Second> struct FractionMul<Fraction<First, Second>, Fraction<Second, First> > { private: static const long long first = 1; static const long long second = 1; public: typedef Fraction<first, second> ValueType; };
/* struct FractionDiv : 除法,结果为 ValueType */ template <typename FractionType1, typename FractionType2> struct FractionDiv { private: static const long long first1 = FractionType1::first; static const long long second1 = FractionType1::second; static const long long first2 = FractionType2::first; static const long long second2 = FractionType2::second; static const long long first = first1 * second2; static const long long second = first2 * second1; public: typedef Fraction<first, second> ValueType; };
template <long long First1, long long First2, long long Second> struct FractionDiv<Fraction<First1, Second>, Fraction<First2, Second> > { private: static const long long first = First1; static const long long second = First2; public: typedef Fraction<first, second> ValueType; };
template <long long First, long long Second1, long long Second2> struct FractionDiv<Fraction<First, Second1>, Fraction<First, Second2> > { private: static const long long first = Second2; static const long long second = Second1; public: typedef Fraction<first, second> ValueType; };
template <long long First, long long Second> struct FractionDiv<Fraction<First, Second>, Fraction<First, Second> > { private: static const long long first = 1; static const long long second = 1; public: typedef Fraction<first, second> ValueType; };
/* struct FractionAdjust : 调整分母,使分母的大小为 SECOND */ template <typename FractionType, long long SECOND = 100000000LL> struct FractionAdjust { private: static const long long first1 = FractionType::first; static const long long second1 = FractionType::second;
static const long long first2 = ((second1 < SECOND) ? SECOND * first1 : first1); static const long long second2 = ((second1 < SECOND) ? SECOND * second1 : second1);
static const long long div = second2 / SECOND; static const long long first = first2 / div; static const long long second = second2 / div; public: typedef Fraction<first, second> ValueType; };
/* struct PI : 是一个 Fraction, */ struct PI;
static const long long BASE = 100000000LL; typedef Fraction<2, 1> Two; // 常量 2
/* struct PIItem : 是 Pi 的一项 */ template <int N> struct PIItem { private: typedef typename PIItem<N-1>::ValueType Value1; typedef typename PIItem<N-1>::ItemType Item1;
typedef typename FractionAdd<Item1, Two>::ValueType ItemAddTwo; public: typedef typename FractionSqrt2<ItemAddTwo>::ValueType ItemType; private: typedef typename FractionDiv<Two, ItemType>::ValueType TwoDivItem; typedef typename FractionMul<Value1, TwoDivItem>::ValueType ValueResult; public: typedef typename FractionAdjust<ValueResult, BASE>::ValueType ValueType; };
template <> struct PIItem<0> { typedef Two ValueType; typedef Fraction<0, BASE> ItemType; };
struct PI : public PIItem<50>::ValueType { };
#include <iostream> #include <cstdlib> using namespace std;
int main () { cout.precision (10); cout << PIItem<0>::ItemType::value << endl; cout.precision (10); cout << PIItem<1>::ItemType::value << endl; cout.precision (10); cout << PIItem<2>::ItemType::value << endl; cout.precision (10); cout << PIItem<4>::ItemType::value << endl; cout.precision (10); cout << PIItem<8>::ItemType::value << endl; cout.precision (10); cout << PIItem<16>::ItemType::value << endl; cout.precision (10); cout << PIItem<32>::ItemType::value << endl; cout.precision (10); cout << PIItem<64>::ItemType::value << endl; cout.precision (10); cout << PIItem<128>::ItemType::value << endl; cout.precision (10); cout << PI::value << endl; system ("Pause"); return 0; } 
|