我正在尝试计算数组中有多少个数字 1。
首先我有一个 C lenguaje 代码(工作正常):
int popcount2(int* array, int len){
int i;
unsigned x;
int result=0;
for (i=0; i<len; i++){
x = array[i];
do{
result+= x & 0x1;
x>>= 1;
} while(x);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
现在我需要使用 3-6 行代码将 do-while 循环转换为汇编。我写了一些代码,但结果不正确。(我是汇编世界的新手)
int popcount3(int* array, int len){
int i;
unsigned x;
int result=0;
for (i=0; i<len; i++){
x = array[i];
asm(
"ini3: \n"
"adc $0,%[r] \n"
"shr %[x] \n"
"jnz ini3 \n"
: [r]"+r" (result)
: [x] "r" (x) ); …Run Code Online (Sandbox Code Playgroud) 我想知道在Perl中计算二进制文件中设置位数(1)的最快方法是什么我需要它来快速,因为我正在读取10个文件,每个文件大约有5千万位.
我现在这样做的方式太慢了,运行10-15个文件需要几个小时.
这就是我现在这样做的方式(我知道它的效率很慢,但是过去文件要小得多,而且这个方法还不错):
#count number of 1's in binary vector
sub get_DET_fault_count {
my $bin_vec = shift;
my $tmp_vec = generate_tmp_path("bin_vec");
io($tmp_vec)->println( unpack( "B*", $bin_vec ) );
my $fault_count = `grep -o -E '1' $tmp_vec | wc -l`;
chomp $fault_count;
`rm $tmp_vec`;
return $fault_count;
}
Run Code Online (Sandbox Code Playgroud) 我有一个32位随机值(比方说631).
0...0000001001110111
每个位都是一个标志.如果可能的话,我想从这些位返回一个随机标志,进行O(1)操作.如何从给定值中选择位位置0,1,2,4,5,6或9(或它的对应值1,2,4,16,32,64,512)631?优选地,对于某些位具有至少可能的偏置.
我提出的事情:
上面不是O(1),如果我们碰巧只"击中"0位,可能需要多次迭代.
同样,不幸的是,上面不是O(1).
我很确定这必须是可能的,有些bithisfting/masking /魔法......
编辑:
正如CodeCaster建议的那样 ; 这将给我所有设置位值:
int myvalue = 631;
var matchingmasks = Enumerable.Range(0, 32)
.Select(i => 1 << i)
.Where(i => (myvalue & i) == i)
.ToArray();
Run Code Online (Sandbox Code Playgroud)
从结果数组中我可以选择一个随机元素,我将从给定值中找到我的"随机"位(标志).但是,这仍然需要一个(隐藏的,因为Linq)for循环,"强制"每个可能的位,结果数组的内存分配等.
是否有一种简单的方法可以将单个数字的所有位进行XOR运算,即C中的一元XOR?
具有以下作用的东西:
result = ^(0x45); // ( 0 ^ 1 ^ 0 ^ 0 ^ 0 ^ 1 ^ 0 ^ 1 = 1)
result = ^(0x33); // ( 0 ^ 0 ^ 1 ^ 1 ^ 0 ^ 0 ^ 1 ^ 1 = 0)
Run Code Online (Sandbox Code Playgroud) 我知道我们可以做这样的事情来将一个字符移动到一个 xmm 寄存器:
movaps xmm1, xword [.__0x20]
align 16
.__0x20 db 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20
Run Code Online (Sandbox Code Playgroud)
但由于这是一个记忆过程,我想知道是否有更好的方法?(另外,我在谈论 SSE2 而不是其他 SIMD 类型......)
我希望 xmm1 寄存器的每个字节都是 0x20,而不仅仅是一个字节..
(编者注:这可以称为广播或 splat。
这是_mm_set1_epi8(0x20)内在函数的作用。)
为了节省 Oracle SQL 中非常特殊的用例的空间,我正在尝试使用位图方法来表示随时间变化的布尔状态(当天发生或未发生事件),每个位都以二进制形式表示代表当天是/否的数字。这样,例如,一个 32 位数字可以让我代表连续 32 天是否每天都发生某事。我只需要计算设置的位数 (=1) 即可获取事件发生的 32 天期间的天数,而无需为每一天存储单独的日期行。
这是我每天测试更新值的示例(滚出最旧的位并设置最新的位):
SELECT testbitmap original_bitmap,
BITAND((testbitmap * POWER(2,/*rolloff the nbr of days since last event*/1)) + /*the event happened today*/1,POWER(2,32)-1) new_bitmap
FROM (SELECT BIN_TO_NUM(1,1,0,0,1,1,0,0,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0) testbitmap
FROM dual)
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很好。但现在我需要查询结果,这意味着计算结果位图的设置位。BIN_TO_NUM据我所知,Oracle 中没有相反的情况。如果不使用循环遍历每个位并单独测试它的函数,是否有一种方法可以对 Oracle 中的设置位进行计数(例如,数字 9 应该导致 2 ( 1001),而数字 7 将导致 3 ( 0111)?也许是数学公式返回表示二进制数所需的 1 的数量?
可能的重复:
计算整数中的设置位数
最佳算法来计算32位整数中的设置位数?
这是一个考试问题,这就是我所有的 - "计算"在一个字节中"的数量""开"意味着1,我假设.我是否需要创建一个BitArray,随机填充它然后迭代它或者有不同的方式吗?
可能重复:
n位整数中有多少1?
你好
如何计算有多少位?
1100110 -> 4
101 -> 2
Run Code Online (Sandbox Code Playgroud)
第二个问题:
如何反转位?
1100110 -> 0011001
101 -> 010
Run Code Online (Sandbox Code Playgroud)
谢谢
可能重复:
计算32位整数中设置位数的最佳算法?
计算设置的位数
如果允许循环遍历循环的次数与设置的位数相同,如何找到无符号整数中设置的位数(如果设置了3位,则只能迭代循环3次)
以下for循环有什么作用?程序何时会脱离循环?
for (c = 0; n; c++) {
/* . . . */
}
Run Code Online (Sandbox Code Playgroud)
这是SO上这个答案的这种for循环的一个例子.