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