math_functions.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Stephen Cleary 2000.
  4. // (C) Copyright Ion Gaztanaga 2007-2012.
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // (See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. // See http://www.boost.org/libs/container for documentation.
  11. //
  12. // This file is a slightly modified file from Boost.Pool
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. #ifndef BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
  16. #define BOOST_CONTAINER_DETAIL_MATH_FUNCTIONS_HPP
  17. #include "config_begin.hpp"
  18. #include <climits>
  19. #include <boost/static_assert.hpp>
  20. namespace boost {
  21. namespace container {
  22. namespace container_detail {
  23. // Greatest common divisor and least common multiple
  24. //
  25. // gcd is an algorithm that calculates the greatest common divisor of two
  26. // integers, using Euclid's algorithm.
  27. //
  28. // Pre: A > 0 && B > 0
  29. // Recommended: A > B
  30. template <typename Integer>
  31. inline Integer gcd(Integer A, Integer B)
  32. {
  33. do
  34. {
  35. const Integer tmp(B);
  36. B = A % B;
  37. A = tmp;
  38. } while (B != 0);
  39. return A;
  40. }
  41. //
  42. // lcm is an algorithm that calculates the least common multiple of two
  43. // integers.
  44. //
  45. // Pre: A > 0 && B > 0
  46. // Recommended: A > B
  47. template <typename Integer>
  48. inline Integer lcm(const Integer & A, const Integer & B)
  49. {
  50. Integer ret = A;
  51. ret /= gcd(A, B);
  52. ret *= B;
  53. return ret;
  54. }
  55. template <typename Integer>
  56. inline Integer log2_ceil(const Integer & A)
  57. {
  58. Integer i = 0;
  59. Integer power_of_2 = 1;
  60. while(power_of_2 < A){
  61. power_of_2 <<= 1;
  62. ++i;
  63. }
  64. return i;
  65. }
  66. template <typename Integer>
  67. inline Integer upper_power_of_2(const Integer & A)
  68. {
  69. Integer power_of_2 = 1;
  70. while(power_of_2 < A){
  71. power_of_2 <<= 1;
  72. }
  73. return power_of_2;
  74. }
  75. //This function uses binary search to discover the
  76. //highest set bit of the integer
  77. inline std::size_t floor_log2 (std::size_t x)
  78. {
  79. const std::size_t Bits = sizeof(std::size_t)*CHAR_BIT;
  80. const bool Size_t_Bits_Power_2= !(Bits & (Bits-1));
  81. BOOST_STATIC_ASSERT(((Size_t_Bits_Power_2)== true));
  82. std::size_t n = x;
  83. std::size_t log2 = 0;
  84. for(std::size_t shift = Bits >> 1; shift; shift >>= 1){
  85. std::size_t tmp = n >> shift;
  86. if (tmp)
  87. log2 += shift, n = tmp;
  88. }
  89. return log2;
  90. }
  91. } // namespace container_detail
  92. } // namespace container
  93. } // namespace boost
  94. #include <boost/container/detail/config_end.hpp>
  95. #endif