我有一个 64 位数(但只使用了 42 个低位),并且需要计算 4 位的总和, 和(注意n
:n+m
任何可以产生总和 >4 的东西都是无效的)对于一些固定的 m 和将所有位放入数字中的 n 的每个值n+m*2
n+m*3
作为一个例子,使用m=3
并给出 16 位数字
0010 1011 0110 0001
我需要计算
2, 3, 1, 2, 3, 0, 3
有没有人有任何(很酷)的想法来做到这一点?我没问题。
我目前的想法是制作输入的位移副本以对齐要求和的值,然后构建一个逻辑树来执行 4x 1bit 加法器。
v1 = In;
v2 = In<<3;
v3 = In<<6;
v4 = In<<9;
a1 = v1 ^ v2;
a2 = v1 & v2;
b1 = v3 ^ v4;
b2 = v3 & v4;
c2 = a1 & b1;
d2 = a2 ^ b2;
o1 = a1 ^ b1;
o2 = c2 ^ d2;
o4 = a2 & b2;
这最终会导致结果的位分布在 3 个不同的整数中,但是很好。
编辑:碰巧我需要总和的直方图,所以对 , 进行位计数,并o4
给我想要的。o2&o1
o2
o1
第二种解决方案使用完美的散列函数
arr = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4];
for(int i = 0; i < N; i++)
{
out[i] = arr[(In & 0b1001001001) % 30];
In >>= 1;
}
这通过注意到 4 个选定位只能采用 16 种模式并且(通过猜测和检查)可以使用 mod 30 将它们散列为 0-15。从那里,一个计算值表给出了所需的总和。碰巧只有 4 步中的 3 步我需要以这种方式工作。
ps
正确胜过快速。快胜于清。我预计会运行数百万次。