假设有两个数组a [N],b [N]只包含0和1的值,有没有办法计算c = a || b没有像下面这样的循环(在C中)?
#define N 10
char a[N];
char b[N];
char c[N];
// suppose to do some operations on a and b so that
// for each i a[i] == 0 or a[i] == 1
// and the same for b
// this is the loop i would want to avoid
int i;
for(i=0;i<N;i++)
c[i] = a[i] || b[i];
我想计算(a || b)直接比较两个内存区域的结果,但我不知道是否可能。 非常感谢你的关注。
答案 0 :(得分:4)
由于按位或是必须应用于单个值的操作,我认为没有。您是否有特殊原因要避免循环?如果这很麻烦,那就很容易做出一个功能。
编辑:问题现在已更改为逻辑OR,但我认为答案不同。
答案 1 :(得分:0)
怎么样:
#define c(index) (a(index) || b(index))
这为您提供了一个符号c阵列。只需删除c变量声明。
答案 2 :(得分:0)
您可以将字符数组强制转换为机器支持的最大整数,然后对整数执行OR运算,这样可以节省一些指令周期。请注意,您必须以您正在使用的整数大小的倍数选择数组大小。
#define LARGE_INTEGER unsigned long long
#define ACTUAL_SIZE 10
#define SIZEOF_LARGE_INT sizeof(LARGE_INTEGER)
#define N (ACTUAL_SIZE + (SIZEOF_LARGE_INT - (ACTUAL_SIZE % SIZEOF_LARGE_INT)))
char a[N] = {0,1,0,1,0,1,1,1,1,1};
char b[N] = {1,0,1,0,1,0,1,0,1,0};
char c[N];
LARGE_INTEGER *pa, *pb, *pc;
int i;
for(i = 0; i < N; i = i + SIZEOF_LARGE_INT)
{
pa = (LARGE_INTEGER*) &a[i];
pb = (LARGE_INTEGER*) &b[i];
pc = (LARGE_INTEGER*) &c[i];
*pc = (*pa) | (*pb);
}
答案 3 :(得分:0)
答案 4 :(得分:0)
如果是x86,则可以使用SSE一次处理16个数组元素:
// NB: we're assuming:
// - N is a multiple of 16
// - a[], b[], and c[] are 16 byte aligned
for (int i = 0; i < N; i += 16)
{
__m128i va = _mm_load_si128(&a[i]);
__m128i vb = _mm_load_si128(&b[i]);
__m128i vc;
#ifdef LOGICAL_OR // NB: only need these two lines if we are doing logical OR - omit for bitwise OR
va = _mm_add_epi8(_mm_cmpeq_epi8(va, _mm_set1_epi8(0)), _mm_set1_epi8(1));
vb = _mm_add_epi8(_mm_cmpeq_epi8(vb, _mm_set1_epi8(0)), _mm_set1_epi8(1));
#endif
vc = _mm_or_si128(va, vb);
_mm_store_si128(vc, &c[i]);
}
答案 5 :(得分:0)
我无法想象为什么你想要这样做,但你也可以把迭代变成尾递归:
int do_or(int n, int *a, int *b, int *c) {
if (0 == n)
return;
*c = *a || * b;
do_or(n-1, a+1, b+1, c+1);
}
可能更好的选择是将0和1编码为无符号数中的实际位,在这种情况下,您可以使用按位or
在单个操作中完成工作:
unsigned long a, b, c;
// code to set/clear bits in a and b elided
c = a | b;
您可以保证unsigned long
至少可以保留32位,而unsigned long long
至少可以保留64位。