簡體   English   中英

使用僅按位運算符創建一個標記最重要設置位的掩碼

[英]Create a mask that marks the most significant set bit, using only bitwise operators

這是昨晚應該給我的一個更大的編程任務的一部分。 無法弄清楚這個問題,但我很好奇它是如何解決的。

函數int greatestBitPos(int x)應返回一個int掩碼,用於標記最高位的位置。 如果x == 0,則返回0.不允許控制結構(if,while,?:)。

示例: greatestBitPos(96) = 0x40

合法經營者:! 〜&^ | + << >> =

這個關於位雜亂的網站是我用作起點的東西,特別是第二種算法。 但是,它使用<比較,這個問題不允許。

歡迎所有的想法,謝謝!

編輯:請假設2的補碼,32位整數。 對於所有負數,它們的最高位設置,因此返回值應為0x80000000

更新為負數工作(假設這應該返回0x80000000因為這些數字的頂部位設置)

int gbp(int n) {
 // return log(2) of n
 unsigned int m;
 m = n;
 m = m | m >> 1;
 m = m | m >> 2;
 m = m | m >> 4;
 m = m | m >> 8;
 m = m | m >> 16;
 m = m & ((~m >> 1)^0x80000000);
printf("m is now %d\n", m);
return m;
}

說明:

從任何位模式開始,當我們向右移動1並取OR時,相鄰位將變為1

00010100
00001010
--------
00011110

你重復這個,直到你在前導數字的右邊有所有的,通過連續移動2,4,8,16(如果你有32位數字;對於更大的int你繼續前進)。

最后你需要通過反轉數字來“去除所有其他的”,右移1,然后取AND:

00011111 AND 11110000 = 00010000

你有它。

對於負數,最終操作可確保您不會殺死最高位(如果存在)。 如果你想用負數做其他事情,請告訴我它是什么。

通過移位和OR'ing將所有位填充到最重要的位:

0b 0010 0000 0000 0000 0100 0000 0000 0000
0b 0011 0000 0000 0000 0110 0000 0000 0000
0b 0011 1100 0000 0000 0111 1000 0000 0000
0b 0011 1111 1100 0000 0111 1111 1000 0000
0b 0011 1111 1111 1111 1111 1111 1111 1111

然后向右移動並添加1以留下最重要的一個:

0b 0001 1111 1111 1111 1111 1111 1111 1111
0b 0010 0000 0000 0000 0000 0000 0000 0000

碼:

int greatestBitPos(int x) {
  int is_nonzero = (x != 0);
  x = x | (x >> 1);
  x = x | (x >> 2);
  x = x | (x >> 4);
  x = x | (x >> 18);
  x = x | (x >> 16);
  return (is_nonzero * ((x >> 1) + 1));
}

我仍然有興趣看看其他人能想出什么,但是一位朋友已經找到了答案。

int greatestBitPos(int x) {
  int a = x | (x >> 1);
  a = a | (a >> 2);
  a = a | (a >> 4);
  a = a | (a >> 8);
  a = a | (a >> 16);
  return ((a ^ (a >> 1)) | 0x80 << 24) & a;
}

知道如果我們可以將MSB右邊的所有位設置為1,那么只需設置MSB就可以了,而不是其他位。 這個答案也適用於否定(關於二元補語)。

實際上,你可以使用那里提到的第二個算法,稍作修改:

b的特殊情況下,形式為0 n 1 m

(a > b) == !!(a & ~b)

成立。

assign a_reversed = {<<{a}};
assign a_2s_compl = (~a_reversed) + 1'b1;
assign a_lsb_set  = a_reversed & a_2s_compl;
assign a_msb_set  = {<<{a_lsb_set}};

這可以在一行和一個可參數化的函數中完成,但我已經把所有步驟都明確地顯示了每一步發生了什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM