fbpx
维基百科

汉明权重

汉明权重是一串符号中非零符号的个数。因此它等同于同样长度的全零符号串的汉明距离。在最为常见的数据位符号串中,它是1的个数。

字符 字符串 汉明权重
0,1 11101 4
0,1 11101000 4
0,1 00000000 0
' ',a-z hello world 11

历史及应用 编辑

汉明权重是以理查德·衛斯里·漢明的名字命名的,它在包括信息论编码理论密码学等多个领域都有应用。

高效实现 编辑

在密码学以及其它应用中经常需要计算数据位中1的个数,针对如何高效地实现人们已经广泛地进行了研究。一些处理器使用单个的命令进行计算,另外一些根据数据位向量使用并行运算进行处理。对于没有这些特性的处理器来说,已知的最好解决办法是按照树状进行相加。例如,要计算二进制数A=0110110010111010中1的个数,这些运算可以表示为:

符号 二进制 十进制 注释
A 01 10 11 00 10 11 10 10 原始数据
B = A & 01 01 01 01 01 01 01 01 01 00 01 00 00 01 00 00 1,0,1,0,0,1,0,0 A隔一位检验
C = (A >> 1) & 01 01 01 01 01 01 01 01 00 01 01 00 01 01 01 01 0,1,1,0,1,1,1,1 A中剩余的数据位
D = B + C 01 01 10 00 01 10 01 01 1,1,2,0,1,2,1,1 A中每个双位段中1的个数列表
E = D & 0011 0011 0011 0011 00 01 00 00 00 10 00 01 1,0,2,1 D中数据隔一位检验
F = (D >> 2) & 0011 0011 0011 0011 00 01 00 10 00 01 00 01 1,2,1,1 D中剩余数据的计算
G = E + F 00 10 00 10 00 11 00 10 2,2,3,2 A中4位数据段中1的个数列表
H = G & 00001111 00001111 00 00 00 10 00 00 00 10 2,2 G中数据隔一位检验
I = (G >> 4) & 00001111 00001111 00 00 00 10 00 00 00 11 2,3 G中剩余数据的计算
J = H + I 00 00 01 00 00 00 01 01 4,5 A中8位数据段中1的个数列表
K = J & 0000000011111111 00 00 00 00 00 00 01 01 5 J中隔一位检验
L = (J >> 8) & 0000000011111111 00 00 00 00 00 00 01 00 4 J中剩余数据的检验
M = K + L 00 00 00 00 00 00 10 01 9 最终答案

这里的运算是用C语言表示的,所以X >> Y表示X右移Y位,X & Y表示X与Y的位与,+表示普通的加法。基于上面所讨论的思想的这个问题的最好算法列在这里:

//types and constants used in the functions below typedef unsigned __int64 uint64; //assume this gives 64-bits const uint64 m1 = 0x5555555555555555; //binary: 0101... const uint64 m2 = 0x3333333333333333; //binary: 00110011.. const uint64 m4 = 0x0f0f0f0f0f0f0f0f; //binary: 4 zeros, 4 ones ... const uint64 m8 = 0x00ff00ff00ff00ff; //binary: 8 zeros, 8 ones ... const uint64 m16 = 0x0000ffff0000ffff; //binary: 16 zeros, 16 ones ... const uint64 m32 = 0x00000000ffffffff; //binary: 32 zeros, 32 ones ... const uint64 hff = 0xffffffffffffffff; //binary: all ones const uint64 h01 = 0x0101010101010101; //the sum of 256 to the power of 0,1,2,3... //This is a naive implementation, shown for comparison, //and to help in understanding the better functions. //It uses 24 arithmetic operations (shift, add, and). int popcount_1(uint64 x) {  x = (x & m1 ) + ((x >> 1) & m1 ); //put count of each 2 bits into those 2 bits   x = (x & m2 ) + ((x >> 2) & m2 ); //put count of each 4 bits into those 4 bits   x = (x & m4 ) + ((x >> 4) & m4 ); //put count of each 8 bits into those 8 bits   x = (x & m8 ) + ((x >> 8) & m8 ); //put count of each 16 bits into those 16 bits   x = (x & m16) + ((x >> 16) & m16); //put count of each 32 bits into those 32 bits   x = (x & m32) + ((x >> 32) & m32); //put count of each 64 bits into those 64 bits   return x; } //This uses fewer arithmetic operations than any other known  //implementation on machines with slow multiplication. //It uses 17 arithmetic operations. int popcount_2(uint64 x) {  x -= (x >> 1) & m1; //put count of each 2 bits into those 2 bits  x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits   x = (x + (x >> 4)) & m4; //put count of each 8 bits into those 8 bits   x += x >> 8; //put count of each 16 bits into their lowest 8 bits  x += x >> 16; //put count of each 32 bits into their lowest 8 bits  x += x >> 32; //put count of each 64 bits into their lowest 8 bits  return x &0xff; } //This uses fewer arithmetic operations than any other known  //implementation on machines with fast multiplication. //It uses 12 arithmetic operations, one of which is a multiply. int popcount_3(uint64 x) {  x -= (x >> 1) & m1; //put count of each 2 bits into those 2 bits  x = (x & m2) + ((x >> 2) & m2); //put count of each 4 bits into those 4 bits   x = (x + (x >> 4)) & m4; //put count of each 8 bits into those 8 bits   return (x * h01)>>56; //returns left 8 bits of x + (x<<8) + (x<<16) + (x<<24) + ...  } 

在最坏的情况下,上面的实现是所有已知算法中表现最好的。但是,如果已知大多数数据位是0的话,那么还有更快的算法。这些更快的算法是基于这样一种事实即X与X-1相得到的最低位永远是0。例如:

Expression Value
X 0 1 0 0 0 1 0 0 0 1 0 0 0 0
X-1 0 1 0 0 0 1 0 0 0 0 1 1 1 1
X & (X-1) 0 1 0 0 0 1 0 0 0 0 0 0 0 0

减1操作将最右边的符号从0变到1,从1变到0,操作将会移除最右端的1。如果最初X有N个1,那么经过N次这样的迭代运算,X将减到0。下面的算法就是根据这个原理实现的。

//This is better when most bits in x are 0 //It uses 3 arithmetic operations and one comparison/branch per "1" bit in x. int popcount_4(uint64 x) {  uint64 count;  for (count=0; x; count++)  x &= x-1;  return count; } //This is better if most bits in x are 0. //It uses 2 arithmetic operations and one comparison/branch per "1" bit in x. //It is the same as the previous function, but with the loop unrolled. #define f(y) if ((x &= x-1) == 0) return y; int popcount_5(uint64 x) {  if (x == 0) return 0;  f( 1) f( 2) f( 3) f( 4) f( 5) f( 6) f( 7) f( 8)  f( 9) f(10) f(11) f(12) f(13) f(14) f(15) f(16)  f(17) f(18) f(19) f(20) f(21) f(22) f(23) f(24)  f(25) f(26) f(27) f(28) f(29) f(30) f(31) f(32)  f(33) f(34) f(35) f(36) f(37) f(38) f(39) f(40)  f(41) f(42) f(43) f(44) f(45) f(46) f(47) f(48)  f(49) f(50) f(51) f(52) f(53) f(54) f(55) f(56)  f(57) f(58) f(59) f(60) f(61) f(62) f(63)  return 64; } //Use this instead if most bits in x are 1 instead of 0 #define f(y) if ((x |= x+1) == hff) return 64-y; 

参见 编辑

外部链接 编辑

  • Aggregate Magic Algorithms (页面存档备份,存于互联网档案馆).优化汉明重量算法及其它算法解释(附源代码)。
  • HACKMEM item 169 (页面存档备份,存于互联网档案馆). Population count assembly code for the PDP/6-10.
  • Bit Twiddling Hacks (页面存档备份,存于互联网档案馆)带有源代码的几种汉明重量计算方法

汉明权重, 是一串符号中非零符号的个数, 因此它等同于同样长度的全零符号串的汉明距离, 在最为常见的数据位符号串中, 它是1的个数, 字符, 字符串, 11101, 11101000, 00000000, hello, world, 11目录, 历史及应用, 高效实现, 参见, 外部链接历史及应用, 编辑是以理查德, 衛斯里, 漢明的名字命名的, 它在包括信息论, 编码理论, 密码学等多个领域都有应用, 高效实现, 编辑在密码学以及其它应用中经常需要计算数据位中1的个数, 针对如何高效地实现人们已经广泛地进行了研究. 汉明权重是一串符号中非零符号的个数 因此它等同于同样长度的全零符号串的汉明距离 在最为常见的数据位符号串中 它是1的个数 字符 字符串 汉明权重0 1 11101 40 1 11101000 40 1 00000000 0 a z hello world 11目录 1 历史及应用 2 高效实现 3 参见 4 外部链接历史及应用 编辑汉明权重是以理查德 衛斯里 漢明的名字命名的 它在包括信息论 编码理论 密码学等多个领域都有应用 高效实现 编辑在密码学以及其它应用中经常需要计算数据位中1的个数 针对如何高效地实现人们已经广泛地进行了研究 一些处理器使用单个的命令进行计算 另外一些根据数据位向量使用并行运算进行处理 对于没有这些特性的处理器来说 已知的最好解决办法是按照树状进行相加 例如 要计算二进制数A 0110110010111010中1的个数 这些运算可以表示为 符号 二进制 十进制 注释A 01 10 11 00 10 11 10 10 原始数据B A amp 01 01 01 01 01 01 01 01 01 00 01 00 00 01 00 00 1 0 1 0 0 1 0 0 A隔一位检验C A gt gt 1 amp 01 01 01 01 01 01 01 01 00 01 01 00 01 01 01 01 0 1 1 0 1 1 1 1 A中剩余的数据位D B C 01 01 10 00 01 10 01 01 1 1 2 0 1 2 1 1 A中每个双位段中1的个数列表E D amp 0011 0011 0011 0011 00 01 00 00 00 10 00 01 1 0 2 1 D中数据隔一位检验F D gt gt 2 amp 0011 0011 0011 0011 00 01 00 10 00 01 00 01 1 2 1 1 D中剩余数据的计算G E F 00 10 00 10 00 11 00 10 2 2 3 2 A中4位数据段中1的个数列表H G amp 00001111 00001111 00 00 00 10 00 00 00 10 2 2 G中数据隔一位检验I G gt gt 4 amp 00001111 00001111 00 00 00 10 00 00 00 11 2 3 G中剩余数据的计算J H I 00 00 01 00 00 00 01 01 4 5 A中8位数据段中1的个数列表K J amp 0000000011111111 00 00 00 00 00 00 01 01 5 J中隔一位检验L J gt gt 8 amp 0000000011111111 00 00 00 00 00 00 01 00 4 J中剩余数据的检验M K L 00 00 00 00 00 00 10 01 9 最终答案这里的运算是用C语言表示的 所以X gt gt Y表示X右移Y位 X amp Y表示X与Y的位与 表示普通的加法 基于上面所讨论的思想的这个问题的最好算法列在这里 types and constants used in the functions below typedef unsigned int64 uint64 assume this gives 64 bits const uint64 m1 0x5555555555555555 binary 0101 const uint64 m2 0x3333333333333333 binary 00110011 const uint64 m4 0x0f0f0f0f0f0f0f0f binary 4 zeros 4 ones const uint64 m8 0x00ff00ff00ff00ff binary 8 zeros 8 ones const uint64 m16 0x0000ffff0000ffff binary 16 zeros 16 ones const uint64 m32 0x00000000ffffffff binary 32 zeros 32 ones const uint64 hff 0xffffffffffffffff binary all ones const uint64 h01 0x0101010101010101 the sum of 256 to the power of 0 1 2 3 This is a naive implementation shown for comparison and to help in understanding the better functions It uses 24 arithmetic operations shift add and int popcount 1 uint64 x x x amp m1 x gt gt 1 amp m1 put count of each 2 bits into those 2 bits x x amp m2 x gt gt 2 amp m2 put count of each 4 bits into those 4 bits x x amp m4 x gt gt 4 amp m4 put count of each 8 bits into those 8 bits x x amp m8 x gt gt 8 amp m8 put count of each 16 bits into those 16 bits x x amp m16 x gt gt 16 amp m16 put count of each 32 bits into those 32 bits x x amp m32 x gt gt 32 amp m32 put count of each 64 bits into those 64 bits return x This uses fewer arithmetic operations than any other known implementation on machines with slow multiplication It uses 17 arithmetic operations int popcount 2 uint64 x x x gt gt 1 amp m1 put count of each 2 bits into those 2 bits x x amp m2 x gt gt 2 amp m2 put count of each 4 bits into those 4 bits x x x gt gt 4 amp m4 put count of each 8 bits into those 8 bits x x gt gt 8 put count of each 16 bits into their lowest 8 bits x x gt gt 16 put count of each 32 bits into their lowest 8 bits x x gt gt 32 put count of each 64 bits into their lowest 8 bits return x amp 0xff This uses fewer arithmetic operations than any other known implementation on machines with fast multiplication It uses 12 arithmetic operations one of which is a multiply int popcount 3 uint64 x x x gt gt 1 amp m1 put count of each 2 bits into those 2 bits x x amp m2 x gt gt 2 amp m2 put count of each 4 bits into those 4 bits x x x gt gt 4 amp m4 put count of each 8 bits into those 8 bits return x h01 gt gt 56 returns left 8 bits of x x lt lt 8 x lt lt 16 x lt lt 24 在最坏的情况下 上面的实现是所有已知算法中表现最好的 但是 如果已知大多数数据位是0的话 那么还有更快的算法 这些更快的算法是基于这样一种事实即X与X 1相与得到的最低位永远是0 例如 Expression ValueX 0 1 0 0 0 1 0 0 0 1 0 0 0 0X 1 0 1 0 0 0 1 0 0 0 0 1 1 1 1X amp X 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0减1操作将最右边的符号从0变到1 从1变到0 与操作将会移除最右端的1 如果最初X有N个1 那么经过N次这样的迭代运算 X将减到0 下面的算法就是根据这个原理实现的 This is better when most bits in x are 0 It uses 3 arithmetic operations and one comparison branch per 1 bit in x int popcount 4 uint64 x uint64 count for count 0 x count x amp x 1 return count This is better if most bits in x are 0 It uses 2 arithmetic operations and one comparison branch per 1 bit in x It is the same as the previous function but with the loop unrolled define f y if x amp x 1 0 return y int popcount 5 uint64 x if x 0 return 0 f 1 f 2 f 3 f 4 f 5 f 6 f 7 f 8 f 9 f 10 f 11 f 12 f 13 f 14 f 15 f 16 f 17 f 18 f 19 f 20 f 21 f 22 f 23 f 24 f 25 f 26 f 27 f 28 f 29 f 30 f 31 f 32 f 33 f 34 f 35 f 36 f 37 f 38 f 39 f 40 f 41 f 42 f 43 f 44 f 45 f 46 f 47 f 48 f 49 f 50 f 51 f 52 f 53 f 54 f 55 f 56 f 57 f 58 f 59 f 60 f 61 f 62 f 63 return 64 Use this instead if most bits in x are 1 instead of 0 define f y if x x 1 hff return 64 y 参见 编辑汉明距离外部链接 编辑Aggregate Magic Algorithms 页面存档备份 存于互联网档案馆 优化汉明重量算法及其它算法解释 附源代码 HACKMEM item 169 页面存档备份 存于互联网档案馆 Population count assembly code for the PDP 6 10 Bit Twiddling Hacks 页面存档备份 存于互联网档案馆 带有源代码的几种汉明重量计算方法 取自 https zh wikipedia org w index php title 汉明权重 amp oldid 70330132, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。