从数学角度未发现在不约定位数情况下解决此问题的方法。
本方法基于迭代缩位思想,对于n位2进制数,首先将每2位数的1个数保存在此2位上(),然后将每4位数的1个数保存在此4位上,以此类推直到将每n/2位数的1个数保存结束,最终所得的2进制数即为原数的1个数。
关键在于,每一轮中分别将2位、4位……等看作一个digit来处理,即多个数位同时参与加法运算。
实现方法,设原数据为binary : long(约定8位);
binary = ( binary & 01010101 ) /*奇数位1个数*/+ ( binary >> 1 & 01010101 )/*偶数位1个数*/;
binary = ( binary & 00110011 )/*每两位为一位,奇数位1个数*/ + ( binary >> 2 & 00110011 )/*偶数位1个数*/;
binary = ( binary & 00001111 ) /*每四位为一位,奇数位1个数*/ + ( binary >> 4 & 00001111 ) /*偶数位1个数*/;
return binary;
测试数据,8位二进制数10110101。
第一轮:10110101 & 01010101 == 00010101, 11011010 & 01010101 == 01010000, 00100101 + 01010000 == 01100101; 观察所得值01110101,一二位01代表原数据一二位有1个1,三四位一样,五六位10==十进制2即原数据五六位共有2个1,七八位也是01;
第二轮:01100101 & 00110011 == 00100001, 01011001 & 00110011 == 00010001, 00100001 + 00010001 == 00110010;
第三轮:00110010 & 00001111 == 00000010, 00100011 & 00001111 == 00000011, 00000010 + 00000011 == 00000101;即十进制的5,对应原数据有5个1。
若未约定位数,则无法在不使用循环条件下确定步骤及与运算数据。