MetaProgramming 求π源代码

类别:编程语言 点击:0 评论:0 推荐:

/* 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;
}

本文地址:http://com.8s8s.com/it/it24422.htm