c++ - 按位运算。此代码安全且可移植吗?

标签 c++

我需要计算表示为 char 数组的位集之间的汉明距离。这是一个核心操作,所以它必须尽可能快。我有这样的东西:

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;
}

分析后,我注意到对 int 的操作速度更快,所以我写道:

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;
}

问题

1) 从 unsigned char *unsigned int * 的转换安全吗?

2) 我在 32 位机器上工作,但我希望代码在 64 位机器上工作。 sizeof(unsigned int) 在两台机器上都返回 4,还是在 64 位机器上返回 8?

3) 如果 sizeof(unsigned int) 在 64 位机器上返回 4,我将如何使用 long long 对 64 位类型进行操作>?

最佳答案

Is that cast from unsigned char * to unsigned int * safe?

形式上,它给出了未定义的行为。实际上,如果指针适合 unsigned int 对齐,它几乎可以在任何平台上工作。在某些平台上,如果对齐错误,它可能会失败或性能不佳。

Does sizeof(unsigned int) returns 4 in both machines, or is it 8 on a 64-bit one?

这取决于。有些平台有 64 位 int,有些平台有 32 位。无论平台如何,使用 uint64_t 可能是有意义的;在 32 位平台上,您将有效地展开循环(每次迭代处理两个 32 位值),这可能会带来适度的改进。

how would I be able to operate on a 64-bit type, with long long?

uint64_t,如果您有 C++11 或 C99 库。 long long 至少为 64 位,但在 2011 年之前的实现中可能不存在。

关于c++ - 按位运算。此代码安全且可移植吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18658615/

相关文章:

c++ - 如何将代码点转换为 utf-8?

c++ - 为什么我不能在同一个文件中定义已经前向声明的成员函数?

c++ - 求 vector 的平均值

使用 std::move 时由于 move 构造函数与其他非 move 构造函数之间的冲突而导致 C++ 编译错误

c++ - 如何在 OpenGL(使用 GLUT)上绘制像圆锥体一样的填充包络?

c++ - 使用 CMake 编译 OpenCV 项目时出错

c++ - 使用类成员的C++函数回调并在main中运行它

c++: RedrawWindow() 闪烁

c++ - 如何编写使用临时容器的范围管道?

c++ - 我的 C++ 代码有什么问题?