按位操作。这个代码安全可移植吗? [英] Bitwise operations. Is this code safe and portable?
问题描述
我需要计算表示为 char
的数组之间的汉明距离。这是一个核心操作,因此它必须尽可能快。我有这样的:
const int N = 32 ; // 32 always
//返回char中的位数
int countOnes_uchar8(unsigned char v);
// pa和pb指向N个数组的数组
int hamming(const unsigned char * pa,const unsigned char * pb)
{
int ret = 0;
for(int i = 0; i {
ret + = countOnes_uchar8(* pa ^ * pb);
}
return ret;在配置之后,我注意到操作在 int <$ c $ b>
$ b s更快,所以我写道:
const int N = 32 ; // 32 always
//返回在32位int中的位数
int countOnes_int32(unsigned int v);
// pa和pb指向N个数组的数组
int hamming(const unsigned char * pa,const unsigned char * pb)
{
const unsigned int * qa = reinterpret_cast< const unsigned int *>(pa);
const unsigned int * qb = reinterpret_cast< const unsigned int *>(pb);
int ret = 0;
for(int i = 0; i {
ret + = countOnes_int32 ^ * qb);
}
return ret;
}
问题
1)从 unsigned char *
到 unsigned int *
p>
2)我在32位机器上工作,但我希望代码在64位机器上工作。 sizeof(unsigned int)
在两台机器上都返回4,还是64位的8?
3)如果在64位机器中 sizeof(unsigned int)
返回4,以 long long
是从
unsigned char *
转换为unsigned int *
安全吗?
正式地,它给出了未定义的行为。实际上,它将在任何平台上工作如果 unsigned int
适当地对齐指针。
sizeof(unsigned int)
在两台机器上都返回4,或者是64位的8?
依靠。一些平台具有64位 int
,有些具有32位。不管平台如何,使用 uint64_t
可能是有意义的;在32位平台上,您将有效地展开循环(每次迭代处理两个32位值),这可能会略微改善。
如何使用64位类型,
long long
?
uint64_t
,如果你有一个C ++ 11或C99库。 long long
至少为64位,但在2011年之前的实现中可能不存在。
I need to compute the Hamming distance between bitsets that are represented as char
arrays. This is a core operation, so it must be as fast as possible. I have something like this:
const int N = 32; // 32 always
// returns the number of bits that are ones in a char
int countOnes_uchar8(unsigned char v);
// pa and pb point to arrays of N items
int hamming(const unsigned char *pa, const unsigned char *pb)
{
int ret = 0;
for(int i = 0; i < N; ++i, ++pa, ++pb)
{
ret += countOnes_uchar8(*pa ^ *pb);
}
return ret;
}
After profiling, I noticed that operating on int
s is faster, so I wrote:
const int N = 32; // 32 always
// returns the number of bits that are ones in a int of 32 bits
int countOnes_int32(unsigned int v);
// pa and pb point to arrays of N items
int hamming(const unsigned char *pa, const unsigned char *pb)
{
const unsigned int *qa = reinterpret_cast<const unsigned int*>(pa);
const unsigned int *qb = reinterpret_cast<const unsigned int*>(pb);
int ret = 0;
for(int i = 0; i < N / sizeof(unsigned int); ++i, ++qa, ++qb)
{
ret += countOnes_int32(*qa ^ *qb);
}
return ret;
}
Questions
1) Is that cast from unsigned char *
to unsigned int *
safe?
2) I work on a 32-bit machine, but I would like the code to work on a 64-bit machine. Does sizeof(unsigned int)
returns 4 in both machines, or is it 8 on a 64-bit one?
3) If sizeof(unsigned int)
returned 4 in a 64-bit machine, how would I be able to operate on a 64-bit type, with long long
?
Is that cast from
unsigned char *
tounsigned int *
safe?
Formally, it gives undefined behaviour. Practically, it will work on just about any platform if the pointer is suitably aligned for unsigned int
. On some platforms, it may fail, or perform poorly, if the alignment is wrong.
Does
sizeof(unsigned int)
returns 4 in both machines, or is it 8 on a 64-bit one?
It depends. Some platforms have 64-bit int
, and some have 32-bit. It would probably make sense to use uint64_t
regardless of platform; on a 32-bit platform, you'd effectively be unrolling the loop (processing two 32-bit values per iteration), which might give a modest improvement.
how would I be able to operate on a 64-bit type, with
long long
?
uint64_t
, if you have a C++11 or C99 library. long long
is at least 64 bits, but might not exist on a pre-2011 implementation.
这篇关于按位操作。这个代码安全可移植吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!