簡體   English   中英

Hamming的權重僅以二進制操作編寫?

[英]Hamming weight written only in binary operations?

我只需要根據二進制運算(&,^,>>)編寫一個字節漢明權重的表達式; 沒有任何循環,只是一個公式。

我知道有很多算法可以計算漢明權重,但是它們都使用算術運算或循環。

如果我們采用http://en.wikipedia.org/wiki/Hamming_weight的算法,則第一個和D = B + C可以寫成D = B ^ C ^(B&C << 1),但下面兩個和是比較復雜。

有人暗示嗎?

更新:謝謝您的幫助。 實際上,我需要以下內容:

int popcount_1(unsigned char in){

unsigned char m1  = 0x55;
unsigned char m2  = 0x33;
unsigned char m4  = 0x0f;
unsigned char B,C = 0;
unsigned char x = in;

x = (x & (x << 1) & (m1 << 1)) | (m1 & (x ^ (x >> 1)));

B = x & m2;
C = (x >>  2) & m2;
x = B ^ C ^ ((B & C) << 1);

B = (x & m4 ) ^ ((x >>  4) & m4);
C = (x & ((x >>  4) & m4)) << 1;
x = B ^ C ^ ((B & C) << 1);
return x;
}

該代碼將導致漢明權重的變量。 它不包含任何+,-或比較指令,並且可以在8位微控制器上工作。 盡管如此,它比大多數其他解決方案需要更多的操作。 現在,我正在嘗試簡化它。

UPDATE2:@Evgeny Kluev提出了另一種基於64位寄存器的解決方案

我認為您能做的最好是O(log n)。 這是32位整數的彈出計數的代碼(在Go中)。 如果需要,可以將其擴展到64位應該很明顯,希望這些注釋可以清楚說明實際情況:

func popCount(n uint32) int {
  // each bit in n is a one-bit integer that indicates how many bits are set
  // in that bit.

  n = ((n & 0xAAAAAAAA) >> 1) + (n & 0x55555555)
  // Now every two bits are a two bit integer that indicate how many bits were
  // set in those two bits in the original number

  n = ((n & 0xCCCCCCCC) >> 2) + (n & 0x33333333)
  // Now we're at 4 bits

  n = ((n & 0xF0F0F0F0) >> 4) + (n & 0x0F0F0F0F)
  // 8 bits

  n = ((n & 0xFF00FF00) >> 8) + (n & 0x00FF00FF)
  // 16 bits

  n = ((n & 0xFFFF0000) >> 16) + (n & 0x0000FFFF)
  // kaboom - 32 bits

  return int(n)
}

我不確定這是否是您要搜索的內容,但這只是一個僅使用shifts和bitwise和的公式:

int weight(unsigned char x)
{
  return ((0x876543210 >>
    (((0x4332322132212110 >> ((x & 0xF) << 2)) & 0xF) << 2)) >>
    ((0x4332322132212110 >> (((x & 0xF0) >> 2)) & 0xF) << 2))
    & 0xf;
}

在這里,移位操作兩次被用作數組索引的替代方法(以查找4位漢明權重)。 另外,移位操作使用數組索引執行加法。

暫無
暫無

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

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