Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
BitOperations.cs
Go to the documentation of this file.
6
8
9public static class BitOperations
10{
11 private static ReadOnlySpan<byte> TrailingZeroCountDeBruijn => new byte[32]
12 {
13 0, 1, 28, 2, 29, 14, 24, 3, 30, 22,
14 20, 15, 25, 17, 4, 8, 31, 27, 13, 23,
15 21, 19, 16, 7, 26, 12, 18, 6, 11, 5,
16 10, 9
17 };
18
19 private static ReadOnlySpan<byte> Log2DeBruijn => new byte[32]
20 {
21 0, 9, 1, 10, 13, 21, 2, 29, 11, 14,
22 16, 18, 22, 25, 3, 30, 8, 12, 20, 28,
23 15, 17, 24, 7, 19, 27, 23, 6, 26, 5,
24 4, 31
25 };
26
27 [MethodImpl(MethodImplOptions.AggressiveInlining)]
28 public static bool IsPow2(int value)
29 {
30 if ((value & (value - 1)) == 0)
31 {
32 return value > 0;
33 }
34 return false;
35 }
36
37 [MethodImpl(MethodImplOptions.AggressiveInlining)]
38 [CLSCompliant(false)]
39 public static bool IsPow2(uint value)
40 {
41 if ((value & (value - 1)) == 0)
42 {
43 return value != 0;
44 }
45 return false;
46 }
47
48 [MethodImpl(MethodImplOptions.AggressiveInlining)]
49 public static bool IsPow2(long value)
50 {
51 if ((value & (value - 1)) == 0L)
52 {
53 return value > 0;
54 }
55 return false;
56 }
57
58 [MethodImpl(MethodImplOptions.AggressiveInlining)]
59 [CLSCompliant(false)]
60 public static bool IsPow2(ulong value)
61 {
62 if ((value & (value - 1)) == 0L)
63 {
64 return value != 0;
65 }
66 return false;
67 }
68
69 [MethodImpl(MethodImplOptions.AggressiveInlining)]
70 internal static bool IsPow2(nint value)
71 {
72 if ((value & (value - 1)) == 0)
73 {
74 return value > 0;
75 }
76 return false;
77 }
78
79 [MethodImpl(MethodImplOptions.AggressiveInlining)]
80 internal static bool IsPow2(nuint value)
81 {
82 if ((value & (value - 1)) == 0)
83 {
84 return value != 0;
85 }
86 return false;
87 }
88
89 [MethodImpl(MethodImplOptions.AggressiveInlining)]
90 [CLSCompliant(false)]
91 public static uint RoundUpToPowerOf2(uint value)
92 {
93 if (!Lzcnt.IsSupported)
94 {
97 {
98 value--;
99 value |= value >> 1;
100 value |= value >> 2;
101 value |= value >> 4;
102 value |= value >> 8;
103 value |= value >> 16;
104 return value + 1;
105 }
106 }
107 return (uint)(4294967296uL >> LeadingZeroCount(value - 1));
108 }
109
110 [MethodImpl(MethodImplOptions.AggressiveInlining)]
111 [CLSCompliant(false)]
112 public static ulong RoundUpToPowerOf2(ulong value)
113 {
115 {
116 int num = 64 - LeadingZeroCount(value - 1);
117 return (1uL ^ (ulong)(num >> 6)) << num;
118 }
119 value--;
120 value |= value >> 1;
121 value |= value >> 2;
122 value |= value >> 4;
123 value |= value >> 8;
124 value |= value >> 16;
125 value |= value >> 32;
126 return value + 1;
127 }
128
129 [MethodImpl(MethodImplOptions.AggressiveInlining)]
130 [CLSCompliant(false)]
131 public static int LeadingZeroCount(uint value)
132 {
133 if (Lzcnt.IsSupported)
134 {
135 return (int)Lzcnt.LeadingZeroCount(value);
136 }
138 {
139 }
140 if (value == 0)
141 {
142 return 32;
143 }
145 {
146 return (int)(0x1F ^ X86Base.BitScanReverse(value));
147 }
148 return 0x1F ^ Log2SoftwareFallback(value);
149 }
150
151 [MethodImpl(MethodImplOptions.AggressiveInlining)]
152 [CLSCompliant(false)]
153 public static int LeadingZeroCount(ulong value)
154 {
156 {
157 return (int)Lzcnt.X64.LeadingZeroCount(value);
158 }
160 {
161 }
163 {
164 if (value != 0L)
165 {
166 return 0x3F ^ (int)X86Base.X64.BitScanReverse(value);
167 }
168 return 64;
169 }
170 uint num = (uint)(value >> 32);
171 if (num == 0)
172 {
173 return 32 + LeadingZeroCount((uint)value);
174 }
175 return LeadingZeroCount(num);
176 }
177
178 [MethodImpl(MethodImplOptions.AggressiveInlining)]
179 [CLSCompliant(false)]
180 public static int Log2(uint value)
181 {
182 value |= 1u;
183 if (Lzcnt.IsSupported)
184 {
185 return (int)(0x1F ^ Lzcnt.LeadingZeroCount(value));
186 }
188 {
189 }
191 {
192 return (int)X86Base.BitScanReverse(value);
193 }
195 }
196
197 [MethodImpl(MethodImplOptions.AggressiveInlining)]
198 [CLSCompliant(false)]
199 public static int Log2(ulong value)
200 {
201 value |= 1;
203 {
204 return 0x3F ^ (int)Lzcnt.X64.LeadingZeroCount(value);
205 }
207 {
208 }
210 {
211 return (int)X86Base.X64.BitScanReverse(value);
212 }
213 uint num = (uint)(value >> 32);
214 if (num == 0)
215 {
216 return Log2((uint)value);
217 }
218 return 32 + Log2(num);
219 }
220
221 private static int Log2SoftwareFallback(uint value)
222 {
223 value |= value >> 1;
224 value |= value >> 2;
225 value |= value >> 4;
226 value |= value >> 8;
227 value |= value >> 16;
228 return Unsafe.AddByteOffset(ref MemoryMarshal.GetReference(Log2DeBruijn), (IntPtr)(int)(value * 130329821 >> 27));
229 }
230
231 [MethodImpl(MethodImplOptions.AggressiveInlining)]
232 internal static int Log2Ceiling(uint value)
233 {
234 int num = Log2(value);
235 if (PopCount(value) != 1)
236 {
237 num++;
238 }
239 return num;
240 }
241
242 [MethodImpl(MethodImplOptions.AggressiveInlining)]
243 internal static int Log2Ceiling(ulong value)
244 {
245 int num = Log2(value);
246 if (PopCount(value) != 1)
247 {
248 num++;
249 }
250 return num;
251 }
252
253 [MethodImpl(MethodImplOptions.AggressiveInlining)]
254 [Intrinsic]
255 [CLSCompliant(false)]
256 public static int PopCount(uint value)
257 {
259 {
260 return (int)Popcnt.PopCount(value);
261 }
263 {
264 }
265 return SoftwareFallback(value);
266 static int SoftwareFallback(uint value)
267 {
268 value -= (value >> 1) & 0x55555555;
269 value = (value & 0x33333333) + ((value >> 2) & 0x33333333);
270 value = ((value + (value >> 4)) & 0xF0F0F0F) * 16843009 >> 24;
271 return (int)value;
272 }
273 }
274
275 [MethodImpl(MethodImplOptions.AggressiveInlining)]
276 [Intrinsic]
277 [CLSCompliant(false)]
278 public static int PopCount(ulong value)
279 {
281 {
282 return (int)Popcnt.X64.PopCount(value);
283 }
285 {
286 }
287 return SoftwareFallback(value);
288 static int SoftwareFallback(ulong value)
289 {
290 value -= (value >> 1) & 0x5555555555555555L;
291 value = (value & 0x3333333333333333L) + ((value >> 2) & 0x3333333333333333L);
292 value = ((value + (value >> 4)) & 0xF0F0F0F0F0F0F0FL) * 72340172838076673L >> 56;
293 return (int)value;
294 }
295 }
296
297 [MethodImpl(MethodImplOptions.AggressiveInlining)]
298 public static int TrailingZeroCount(int value)
299 {
300 return TrailingZeroCount((uint)value);
301 }
302
303 [MethodImpl(MethodImplOptions.AggressiveInlining)]
304 [CLSCompliant(false)]
305 public static int TrailingZeroCount(uint value)
306 {
307 if (Bmi1.IsSupported)
308 {
309 return (int)Bmi1.TrailingZeroCount(value);
310 }
312 {
313 }
314 if (value == 0)
315 {
316 return 32;
317 }
319 {
320 return (int)X86Base.BitScanForward(value);
321 }
322 return Unsafe.AddByteOffset(ref MemoryMarshal.GetReference(TrailingZeroCountDeBruijn), (IntPtr)(int)((value & (0 - value)) * 125613361 >> 27));
323 }
324
325 [MethodImpl(MethodImplOptions.AggressiveInlining)]
326 public static int TrailingZeroCount(long value)
327 {
328 return TrailingZeroCount((ulong)value);
329 }
330
331 [MethodImpl(MethodImplOptions.AggressiveInlining)]
332 [CLSCompliant(false)]
333 public static int TrailingZeroCount(ulong value)
334 {
335 if (Bmi1.X64.IsSupported)
336 {
337 return (int)Bmi1.X64.TrailingZeroCount(value);
338 }
340 {
341 }
343 {
344 if (value != 0L)
345 {
346 return (int)X86Base.X64.BitScanForward(value);
347 }
348 return 64;
349 }
350 uint num = (uint)value;
351 if (num == 0)
352 {
353 return 32 + TrailingZeroCount((uint)(value >> 32));
354 }
355 return TrailingZeroCount(num);
356 }
357
358 [MethodImpl(MethodImplOptions.AggressiveInlining)]
359 [CLSCompliant(false)]
360 public static uint RotateLeft(uint value, int offset)
361 {
362 return (value << offset) | (value >> 32 - offset);
363 }
364
365 [MethodImpl(MethodImplOptions.AggressiveInlining)]
366 [CLSCompliant(false)]
367 public static ulong RotateLeft(ulong value, int offset)
368 {
369 return (value << offset) | (value >> 64 - offset);
370 }
371
372 [MethodImpl(MethodImplOptions.AggressiveInlining)]
373 [CLSCompliant(false)]
374 public static uint RotateRight(uint value, int offset)
375 {
376 return (value >> offset) | (value << 32 - offset);
377 }
378
379 [MethodImpl(MethodImplOptions.AggressiveInlining)]
380 [CLSCompliant(false)]
381 public static ulong RotateRight(ulong value, int offset)
382 {
383 return (value >> offset) | (value << 64 - offset);
384 }
385}
static int LeadingZeroCount(ulong value)
static int Log2SoftwareFallback(uint value)
static int TrailingZeroCount(int value)
static bool IsPow2(int value)
static int TrailingZeroCount(long value)
static int TrailingZeroCount(uint value)
static bool IsPow2(nint value)
static int PopCount(uint value)
static ReadOnlySpan< byte > TrailingZeroCountDeBruijn
static int TrailingZeroCount(ulong value)
static bool IsPow2(long value)
static int Log2Ceiling(ulong value)
static int Log2(uint value)
static bool IsPow2(nuint value)
static ulong RotateLeft(ulong value, int offset)
static uint RotateRight(uint value, int offset)
static ulong RoundUpToPowerOf2(ulong value)
static int LeadingZeroCount(uint value)
static int Log2(ulong value)
static uint RoundUpToPowerOf2(uint value)
static uint RotateLeft(uint value, int offset)
static int Log2Ceiling(uint value)
static bool IsPow2(uint value)
static ReadOnlySpan< byte > Log2DeBruijn
static ulong RotateRight(ulong value, int offset)
static bool IsPow2(ulong value)
static int PopCount(ulong value)
static ulong TrailingZeroCount(ulong value)
Definition Bmi1.cs:44
static new bool IsSupported
Definition Bmi1.cs:50
static uint TrailingZeroCount(uint value)
Definition Bmi1.cs:82
static ulong LeadingZeroCount(ulong value)
Definition Lzcnt.cs:14
static uint LeadingZeroCount(uint value)
Definition Lzcnt.cs:22
static ulong PopCount(ulong value)
Definition Popcnt.cs:14
static uint PopCount(uint value)
Definition Popcnt.cs:22
static ulong BitScanReverse(ulong value)
Definition X86Base.cs:19
static ulong BitScanForward(ulong value)
Definition X86Base.cs:14
static uint BitScanForward(uint value)
Definition X86Base.cs:30
static uint BitScanReverse(uint value)
Definition X86Base.cs:35