File: lzham_math.h

package info (click to toggle)
p7zip 16.02%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 14,144 kB
  • sloc: cpp: 167,145; ansic: 14,992; python: 1,911; asm: 1,688; sh: 1,132; makefile: 701
file content (142 lines) | stat: -rw-r--r-- 3,324 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// File: lzham_math.h
// See Copyright Notice and license at the end of include/lzham.h
#pragma once

#if defined(LZHAM_USE_MSVC_INTRINSICS) && !defined(__MINGW32__)
   #include <intrin.h>
   #if defined(_MSC_VER)
      #pragma intrinsic(_BitScanReverse)
   #endif
#endif

namespace lzham
{
   namespace math
   {
      // Yes I know these should probably be pass by ref, not val:
      // http://www.stepanovpapers.com/notes.pdf
      // Just don't use them on non-simple (non built-in) types!
      template<typename T> inline T minimum(T a, T b) { return (a < b) ? a : b; }

      template<typename T> inline T minimum(T a, T b, T c) { return minimum(minimum(a, b), c); }

      template<typename T> inline T maximum(T a, T b) { return (a > b) ? a : b; }

      template<typename T> inline T maximum(T a, T b, T c) { return maximum(maximum(a, b), c); }

      template<typename T> inline T clamp(T value, T low, T high) { return (value < low) ? low : ((value > high) ? high : value); }

      inline bool is_power_of_2(uint32 x) { return x && ((x & (x - 1U)) == 0U); }
      inline bool is_power_of_2(uint64 x) { return x && ((x & (x - 1U)) == 0U); }

      template<typename T> inline T align_up_pointer(T p, uint alignment)
      {
         LZHAM_ASSERT(is_power_of_2(alignment));
         ptr_bits_t q = reinterpret_cast<ptr_bits_t>(p);
         q = (q + alignment - 1) & (~((uint_ptr)alignment - 1));
         return reinterpret_cast<T>(q);
      }

      // From "Hackers Delight"
      // val remains unchanged if it is already a power of 2.
      inline uint32 next_pow2(uint32 val)
      {
         val--;
         val |= val >> 16;
         val |= val >> 8;
         val |= val >> 4;
         val |= val >> 2;
         val |= val >> 1;
         return val + 1;
      }

      // val remains unchanged if it is already a power of 2.
      inline uint64 next_pow2(uint64 val)
      {
         val--;
         val |= val >> 32;
         val |= val >> 16;
         val |= val >> 8;
         val |= val >> 4;
         val |= val >> 2;
         val |= val >> 1;
         return val + 1;
      }

      inline uint floor_log2i(uint v)
      {
         uint l = 0;
         while (v > 1U)
         {
            v >>= 1;
            l++;
         }
         return l;
      }

      inline uint ceil_log2i(uint v)
      {
         uint l = floor_log2i(v);
         if ((l != cIntBits) && (v > (1U << l)))
            l++;
         return l;
      }

      // Returns the total number of bits needed to encode v.
      inline uint total_bits(uint v)
      {
         unsigned long l = 0;
#if defined(__MINGW32__)
         if (v)
         {
            l = 32 -__builtin_clz(v);
         }
#elif defined(LZHAM_USE_MSVC_INTRINSICS)
         if (_BitScanReverse(&l, v))
         {
            l++;
         }
         else
         {
            l = 0;
         }
#else
         while (v > 0U)
         {
            v >>= 1;
            l++;
         }
#endif
         return static_cast<uint>(l);
      }

		inline uint compute_mask_size(uint x)
		{
			uint l = 0;
			while (x)
			{
				x &= (x - 1);
				l++;
			}
			return l;
		}

		inline uint compute_mask_shift(uint x)
		{
			if (!x)
				return 0;

			uint l = 0;
			while ((x & 1) == 0)
			{
				x >>= 1;
				l++;
			}

			return l;
		}

   }

} // namespace lzham