00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef MLN_METAL_MATH_ROOT_HH
00027 # define MLN_METAL_MATH_ROOT_HH
00028
00036 # include <mln/metal/math/pow.hh>
00037
00038
00039 # define mlc_root(N,X) mln::metal::math::root<( N ),( X )>
00040
00041
00042 namespace mln
00043 {
00044
00045 namespace metal
00046 {
00047
00048 namespace math
00049 {
00050
00051 namespace impl
00052 {
00053
00054 template <unsigned n, unsigned x,
00055 unsigned lo = 1, unsigned hi = x>
00056 struct root
00057 {
00058 enum {
00059 mid = (lo + hi + 1) / 2,
00060 val_lo = root<n, x, lo, mid-1>::value,
00061 val_hi = root<n, x, mid, hi>::value
00062 };
00063 enum { value = x < mlc_pow_int(mid, n) ? val_lo : val_hi };
00064 };
00065
00066 template<unsigned n, unsigned x, unsigned m>
00067 struct root<n, x, m, m>
00068 {
00069 enum { value = m };
00070 };
00071
00072 }
00073
00074 template <unsigned n, unsigned x>
00075 struct root : bool_<(n != 0)>::check_t
00076 {
00077 enum { value = impl::root<n,x>::value,
00078 reminder = x - mlc_pow_int(value, n) };
00079 };
00080
00081 template <unsigned n>
00082 struct root<n, 0> : bool_<(n != 0)>::check_t
00083 {
00084 enum { value = 0,
00085 reminder = 0};
00086 };
00087
00088 }
00089
00090 }
00091
00092 }
00093
00094
00095 #endif // ! MLN_METAL_MATH_ROOT_HH