aimstil  5.0.5
misc_tools.tpp
Go to the documentation of this file.
1 
2 
3 namespace til
4 {
5 
6  //---------------------------------------------------------------------------
7 
8  template < typename T >
9  T IntegerRoot<T>::operator()(T n, std::size_t N)
10  {
11  // this split is just to avoid annoying warning that the n<0 test always fails for unsigned types.
12  return this->compute(n, N, cat2type<is_signed, T>());
13  }
14 
15  //---------------------------------------------------------------------------
16 
17  template < typename T >
18  T IntegerRoot<T>::compute(T n, std::size_t N, label::Passed<is_signed>)
19  {
20  if (n < 0)
21  {
22  if (N%2)
23  {
24  throw NoRoot();
25  }
26  else
27  {
28  return -this->solve(-n, N);
29  }
30  }
31  else
32  {
33  return this->solve(n, N);
34  }
35  }
36 
37  //---------------------------------------------------------------------------
38 
39  template < typename T >
40  T IntegerRoot<T>::compute(T n, std::size_t N, label::Failed<is_signed>)
41  {
42  return this->solve(n, N);
43  }
44 
45  //---------------------------------------------------------------------------
46 
47  template < typename T >
48  T IntegerRoot<T>::solve(T n, std::size_t N)
49  {
50  for (std::size_t i = 0;;++i)
51  {
52  T p = integer_pow(i, N);
53  if (p == n) return i;
54  else if (p > n) throw NoRoot();
55  }
56  // should never go here
57  throw NoRoot();
58  }
59 
60  //---------------------------------------------------------------------------
61 
62  /// Sort a, b, c in decreasing order (a>=b>=c).
63  template < typename T >
64  void sort(T & a, T & b, T & c)
65  {
66  if (a>=b) { // a >= b
67  if (a>=c) { // a >= b c
68  if (b>=c) { // a >= b >= c
69  return;
70  } else { // a >= c > b
71  std::swap(b,c);
72  }
73  } else { // c > a >= b
74  shift_right(a,b,c,a);
75  }
76  } else { // b > a
77  if (a<c) { // b c > a
78  if (b<=c) { // c > b > a
79  std::swap(a,c);
80  } else { // b > c > a
81  shift_right(c,b,a,c);
82  }
83  } else { // b > a > c
84  std::swap(b,a);
85  }
86  }
87  }
88 
89 } // namespace til
90