Last active
August 29, 2015 14:07
-
-
Save aont/eeedc3c0d61d3fdb859f to your computer and use it in GitHub Desktop.
Compile Time sqrt(2)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <cstdio> | |
| #include <cstdlib> | |
| template<int x> | |
| struct from_int | |
| { | |
| const static double value; | |
| }; | |
| template<int x> | |
| const double from_int<x>::value = x; | |
| template< | |
| bool flag, | |
| typename T, | |
| typename F | |
| > | |
| struct ternary; | |
| template< | |
| typename T, | |
| typename F | |
| > | |
| struct ternary<true, T, F> | |
| { | |
| const static double value; | |
| }; | |
| template< | |
| typename T, | |
| typename F | |
| > | |
| const double ternary<true, T, F>::value = T::value; | |
| template< | |
| typename T, | |
| typename F | |
| > | |
| struct ternary<false, T, F> | |
| { | |
| const static double value; | |
| }; | |
| template< | |
| typename T, | |
| typename F | |
| > | |
| const double ternary<false, T, F>::value = F::value; | |
| namespace newton | |
| { | |
| template<typename X0, typename Y> | |
| struct advance | |
| { | |
| const static double value; | |
| }; | |
| template<typename X0, typename Y> | |
| const double advance<X0, Y>::value = | |
| X0::value - (X0::value*X0::value - Y::value) / (2*X0::value) ; | |
| template<typename X0, typename Y> | |
| struct is_converged | |
| { | |
| const static bool value; | |
| }; | |
| template<typename X0, typename Y> | |
| const bool is_converged<X0, Y>::value = | |
| X0::value*X0::value<Y::value*(1+1e-15) && | |
| X0::value*X0::value>Y::value*(1-1e-15) ; | |
| template<typename X0, typename Y> | |
| struct solve_impl | |
| { | |
| typedef advance<X0, Y> adv_t; | |
| const static double value; | |
| }; | |
| template<typename X0, typename Y> | |
| const double solve_impl<X0, Y>::value = | |
| ternary<is_converged<X0, Y>::value, X0, solve_impl<adv_t, Y> >::value; | |
| template<typename Y> | |
| struct solve : public solve_impl<from_int<1>, Y> { }; | |
| } | |
| int main() | |
| { | |
| typedef from_int<2> f2; | |
| printf("sqrt(2)=%.16g\n", newton::solve<f2>::value); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment