[英]C# getting upper 4 bits of uint32 starting with first significant bit
我的需求是 - 有一些(實際上偽)隨機數uint32
,我需要它的4個第一位用第1位表示,而不是0,例如
... 000100101 => 1001
1000 ... 0001 => 1000
... 0001 => 0001
... 0000 => 0000
等我知道我必須使用這樣的東西
uint num = 1157 (some random number)
uint high = num >> offset
問題是 - 我不知道第一位是哪里所以我不能使用>>
和常量變量。 有人可以解釋如何找到這個offset
嗎?
您可以先計算最高有效位(HSB)然后相應地移位。 你可以這樣:
int hsb = -4;
for(uint cnum = num; cnum != 0; cnum >>= 1, hsb++);
if(hsb < 0) {
hsb = 0;
}
uint result = num >> hsb;
所以我們首先要檢測最高設置位(或該指數減去4)的索引。 我們通過遞增hsb
並將cnum
( num
的副本)向右移位,直到cnum
中沒有設置位cnum
。
接下來我們確保有這樣的設置位,並且它至少具有索引4(如果沒有,則不執行任何操作)。 結果是原始num
由hsb
向右移動。
如果我在0x123
上運行它,我在csharp
交互式shell中得到0x9
:
csharp> uint num = 0x123;
csharp> int hsb = -4;
csharp> for(uint cnum = num; cnum != 0; cnum >>= 1, hsb++);
csharp> if(hsb < 0) {
> hsb = 0;
> }
csharp> uint result = num >> hsb;
csharp> result
9
0x123
是二進制的0001 0010 0011
。 所以:
0001 0010 0011
1 001
1001
是9
。
確定最重要的非零位的位置與計算基數2的對數相同。在現代CPU上有快速執行此操作的“位移技巧”:
int GetLog2Plus1(uint value)
{
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value -= value >> 1 & 0x55555555;
value = (value >> 2 & 0x33333333) + (value & 0x33333333);
value = (value >> 4) + value & 0x0F0F0F0F;
value += value >> 8;
value += value >> 16;
value &= 0x0000003F;
return (int) value;
}
這將返回0到32之間的數字:
Value | Log2 + 1 -------------------------------------------+--------- 0b0000_0000_0000_0000_0000_0000_0000_0000U | 0 0b0000_0000_0000_0000_0000_0000_0000_0001U | 1 0b0000_0000_0000_0000_0000_0000_0000_0010U | 2 0b0000_0000_0000_0000_0000_0000_0000_0011U | 2 0b0000_0000_0000_0000_0000_0000_0000_0100U | 3 ... 0b0111_1111_1111_1111_1111_1111_1111_1111U | 31 0b1000_0000_0000_0000_0000_0000_0000_0000U | 32 0b1000_0000_0000_0000_0000_0000_0000_0001U | 32 ... | 0b1111_1111_1111_1111_1111_1111_1111_1111U | 32
(Math nitpickers會注意到0的對數是未定義的。但是,我希望上面的表格能夠說明如何處理這個問題並對這個問題有意義。)
然后,如果值小於8(其中log2 + 1 <4),則可以計算最重要的非零位,同時考慮您需要4個最低有效位:
var log2Plus1 = GetLog2Plus1(value);
var bitsToShift = Math.Max(log2Plus1 - 4, 0);
var upper4Bits = value >> bitsToShift;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.