Useless code: a template device to calculate e

Post by Nico Brailovsky @ 2013-06-27 | Permalink | Leave a comment

Recently I needed to flex a bit my template metaprogrammingfooness, so I decided to go back and review and old article I wrote about it (C++11 made some parts of those articles obsolete, but I'm surprised of how well it's aged). To practice a bit I decided to tackle a problem I'm sure no one ever had before: defining a mathematical const on compile time. This is what I ended up with, do you have a better version? Shouldn't be to hard.

template <int N, int D> struct Frak {
    static const long Num = N;
    static const long Den = D;
};
template <class X, int N> struct MultEscalar {
    typedef Frak< N*X::Num, N*X::Den > result;
};
template <class X1, class Y1> struct IgualBase {
    typedef typename MultEscalar< X1, Y1::Den >::result X;
    typedef typename MultEscalar< Y1, X1::Den >::result Y;
};
template <int X, int Y> struct MCD {
    static const long result = MCD<Y, X % Y>::result;
};
template <int X> struct MCD<X, 0> {
    static const long result = X;
};
template <class F> struct Simpl {
    static const long mcd = MCD<F::Num, F::Den>::result;
    typedef Frak< F::Num / mcd, F::Den / mcd > result;
};
template <class X, class Y> struct Suma {
    typedef IgualBase<X, Y> B;
    static const long Num = B::X::Num + B::Y::Num;
    static const long Den = B::Y::Den; // == B::X::Den
    typedef typename Simpl< Frak<Num, Den> >::result result;
};
template <int N> struct Fact {
    static const long result = N * Fact<N-1>::result;
};
template <> struct Fact<0> {
    static const long result = 1;
};
template <int N> struct E {
    // e = S(1/n!) = 1/0! + 1/1! + 1/2! + ...
    static const long Den = Fact<N>::result;
    typedef Frak< 1, Den > term;
    typedef typename E<N-1>::result next_term;
    typedef typename Suma< term, next_term >::result result;
};
template <> struct E<0> {
    typedef Frak<1, 1> result;
};
#include <iostream>
int main() {
    typedef E<8>::result X;
    std::cout << "e = " << (1.0 * X::Num / X::Den) << "\n";
    std::cout << "e = " << X::Num <<"/"<< X::Den << "\n";
    return 0;
}