GteBitHacks.cpp
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #include <GTEnginePCH.h>
10 
11 namespace gte
12 {
13 
14 static int32_t const gsLeadingBitTable[32] =
15 {
16  0, 9, 1, 10, 13, 21, 2, 29,
17  11, 14, 16, 18, 22, 25, 3, 30,
18  8, 12, 20, 28, 15, 17, 24, 7,
19  19, 27, 23, 6, 26, 5, 4, 31
20 };
21 
22 static int32_t const gsTrailingBitTable[32] =
23 {
24  0, 1, 28, 2, 29, 14, 24, 3,
25  30, 22, 20, 15, 25, 17, 4, 8,
26  31, 27, 13, 23, 21, 19, 16, 7,
27  26, 12, 18, 6, 11, 5, 10, 9
28 };
29 
30 
31 bool IsPowerOfTwo(uint32_t value)
32 {
33  return (value > 0) && ((value & (value - 1)) == 0);
34 }
35 
36 bool IsPowerOfTwo(int32_t value)
37 {
38  return (value > 0) && ((value & (value - 1)) == 0);
39 }
40 
41 uint32_t Log2OfPowerOfTwo(uint32_t powerOfTwo)
42 {
43  uint32_t log2 = (powerOfTwo & 0xAAAAAAAAu) != 0;
44  log2 |= ((powerOfTwo & 0xFFFF0000u) != 0) << 4;
45  log2 |= ((powerOfTwo & 0xFF00FF00u) != 0) << 3;
46  log2 |= ((powerOfTwo & 0xF0F0F0F0u) != 0) << 2;
47  log2 |= ((powerOfTwo & 0xCCCCCCCCu) != 0) << 1;
48  return log2;
49 }
50 
51 int32_t Log2OfPowerOfTwo(int32_t powerOfTwo)
52 {
53  uint32_t log2 = (powerOfTwo & 0xAAAAAAAAu) != 0;
54  log2 |= ((powerOfTwo & 0xFFFF0000u) != 0) << 4;
55  log2 |= ((powerOfTwo & 0xFF00FF00u) != 0) << 3;
56  log2 |= ((powerOfTwo & 0xF0F0F0F0u) != 0) << 2;
57  log2 |= ((powerOfTwo & 0xCCCCCCCCu) != 0) << 1;
58  return static_cast<int32_t>(log2);
59 }
60 
61 int32_t GetLeadingBit(uint32_t value)
62 {
63  value |= value >> 1;
64  value |= value >> 2;
65  value |= value >> 4;
66  value |= value >> 8;
67  value |= value >> 16;
68  uint32_t key = (value * 0x07C4ACDDu) >> 27;
69  return gsLeadingBitTable[key];
70 }
71 
72 int32_t GetLeadingBit(int32_t value)
73 {
74  value |= value >> 1;
75  value |= value >> 2;
76  value |= value >> 4;
77  value |= value >> 8;
78  value |= value >> 16;
79  uint32_t key = (value * 0x07C4ACDDu) >> 27;
80  return gsLeadingBitTable[key];
81 }
82 
83 int32_t GetLeadingBit(uint64_t value)
84 {
85  uint32_t v1 = GTE_GET_HI_U64(value);
86  if (v1 != 0)
87  {
88  return GetLeadingBit(v1) + 32;
89  }
90 
91  uint32_t v0 = GTE_GET_LO_U64(value);
92  return GetLeadingBit(v0);
93 }
94 
95 int32_t GetLeadingBit(int64_t value)
96 {
97  int32_t v1 = GTE_GET_HI_I64(value);
98  if (v1 != 0)
99  {
100  return GetLeadingBit(v1) + 32;
101  }
102 
103  int32_t v0 = GTE_GET_LO_I64(value);
104  return GetLeadingBit(v0);
105 }
106 
107 int32_t GetTrailingBit(uint32_t value)
108 {
109 #pragma warning(push)
110 #pragma warning(disable : 4146) // Do not warn on negation of uint32_t.
111  uint32_t key = ((uint32_t)((value & -value) * 0x077CB531u)) >> 27;
112  return gsTrailingBitTable[key];
113 #pragma warning(pop)
114 }
115 
116 int32_t GetTrailingBit(int32_t value)
117 {
118  uint32_t key = ((uint32_t)((value & -value) * 0x077CB531u)) >> 27;
119  return gsTrailingBitTable[key];
120 }
121 
122 int32_t GetTrailingBit(uint64_t value)
123 {
124  uint32_t v0 = GTE_GET_LO_U64(value);
125  if (v0 != 0)
126  {
127  return GetTrailingBit(v0);
128  }
129 
130  uint32_t v1 = GTE_GET_HI_U64(value);
131  return GetTrailingBit(v1) + 32;
132 }
133 
134 int32_t GetTrailingBit(int64_t value)
135 {
136  int32_t v0 = GTE_GET_LO_I64(value);
137  if (v0 != 0)
138  {
139  return GetTrailingBit(v0);
140  }
141 
142  int32_t v1 = GTE_GET_HI_I64(value);
143  return GetTrailingBit(v1) + 32;
144 }
145 
146 uint64_t RoundUpToPowerOfTwo(uint32_t value)
147 {
148  if (value > 0)
149  {
150  int32_t leading = GetLeadingBit(value);
151  uint32_t mask = (1 << leading);
152  if ((value & ~mask) == 0)
153  {
154  // value is a power of two
155  return static_cast<uint64_t>(value);
156  }
157  else
158  {
159  // round up to a power of two
160  return (static_cast<uint64_t>(mask) << 1);
161  }
162 
163  }
164  else
165  {
166  return GTE_U64(1);
167  }
168 }
169 
170 uint32_t RoundDownToPowerOfTwo(uint32_t value)
171 {
172  if (value > 0)
173  {
174  int32_t leading = GetLeadingBit(value);
175  uint32_t mask = (1 << leading);
176  return mask;
177  }
178  else
179  {
180  return 0;
181  }
182 }
183 
184 }
GTE_IMPEXP int32_t GetTrailingBit(uint32_t value)
GTE_IMPEXP uint32_t RoundDownToPowerOfTwo(uint32_t value)
GLfloat GLfloat v1
Definition: glcorearb.h:812
GTE_IMPEXP int32_t GetLeadingBit(uint32_t value)
Definition: GteBitHacks.cpp:61
static int32_t const gsLeadingBitTable[32]
Definition: GteBitHacks.cpp:14
GLsizei const GLfloat * value
Definition: glcorearb.h:819
GLint GLuint mask
Definition: glcorearb.h:119
#define GTE_GET_HI_U64(v)
Definition: GteBitHacks.h:19
#define GTE_GET_HI_I64(v)
Definition: GteBitHacks.h:17
#define GTE_U64(v)
Definition: GteBitHacks.h:15
#define GTE_GET_LO_U64(v)
Definition: GteBitHacks.h:18
GLfloat v0
Definition: glcorearb.h:811
#define GTE_GET_LO_I64(v)
Definition: GteBitHacks.h:16
static int32_t const gsTrailingBitTable[32]
Definition: GteBitHacks.cpp:22
GTE_IMPEXP bool IsPowerOfTwo(uint32_t value)
Definition: GteBitHacks.cpp:31
GTE_IMPEXP uint64_t RoundUpToPowerOfTwo(uint32_t value)
GTE_IMPEXP uint32_t Log2OfPowerOfTwo(uint32_t powerOfTwo)
Definition: GteBitHacks.cpp:41


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 03:59:59