按位操作。这个代码安全可移植吗? [英] Bitwise operations. Is this code safe and portable?

查看:157
本文介绍了按位操作。这个代码安全可移植吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要计算表示为 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 ints 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 * to unsigned 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆