C++ 按位操作。此代码是否安全且可移植?
我需要计算表示为C++ 按位操作。此代码是否安全且可移植?,c++,C++,我需要计算表示为char数组的位集之间的汉明距离。这是一个核心操作,因此必须尽可能快。我有这样的想法: const int N=32;//32总是 //返回字符中的位数 int countOnes_uchar8(无符号字符v); //pa和pb指向N个项目的数组 int-hamming(常量无符号字符*pa,常量无符号字符*pb) { int-ret=0; 对于(int i=0;i
char
数组的位集之间的汉明距离。这是一个核心操作,因此必须尽可能快。我有这样的想法:
const int N=32;//32总是
//返回字符中的位数
int countOnes_uchar8(无符号字符v);
//pa和pb指向N个项目的数组
int-hamming(常量无符号字符*pa,常量无符号字符*pb)
{
int-ret=0;
对于(int i=0;i
分析之后,我注意到在int
s上操作更快,所以我写了:
const int N=32;//32总是
//返回32位整数中的位数
int countOnes_int32(无符号int v);
//pa和pb指向N个项目的数组
int-hamming(常量无符号字符*pa,常量无符号字符*pb)
{
const unsigned int*qa=reinterpret_cast(pa);
const unsigned int*qb=重新解释强制转换(pb);
int-ret=0;
对于(整数i=0;i
问题
1) 从unsigned char*
到unsigned int*
的转换安全吗
2) 我在32位机器上工作,但我希望代码在64位机器上工作。sizeof(unsigned int)
在两台机器上都返回4,还是在64位机器上返回8
3) 如果在64位计算机中sizeof(unsigned int)
返回4,我如何能够在具有long
的64位类型上操作
从unsigned char*
到unsigned int*
的转换安全吗
形式上,它给出了未定义的行为。实际上,如果指针针对
unsigned int
进行适当对齐,它几乎可以在任何平台上工作。在某些平台上,如果对齐错误,它可能会失败或性能不佳
sizeof(unsigned int)
在两台机器上都返回4,还是在64位机器上返回8
视情况而定。有些平台具有64位int
,有些平台具有32位。无论平台如何,使用uint64\u t
可能是有意义的;在32位平台上,您可以有效地展开循环(每次迭代处理两个32位值),这可能会带来适度的改进
我如何才能在64位类型上使用long
uint64\u t
,如果您有C++11或C99库long-long
至少为64位,但在2011年之前的实现中可能不存在。1)不,它不安全/不可移植,是未定义的行为。在某些系统中,char
大于一个字节,并且不能保证char指针正确对齐
2) sizeof(int)
理论上可能是64位机器上的任何东西。实际上,它将是4或8
3) long-long
很可能是64位,但也不能保证有64位。如果需要担保,请使用uint64\u t
。但是,对于您的特定算法,我不明白数据块的重要性
考虑改用stdint.h中的类型,它们更适合于可移植代码。使用uint\u fast8\u t
代替char、int或long-long。这将让编译器以可移植的方式为您选择最快的整数
作为SeNoNoT,您应该考虑将“CONTRONS”作为查找表,以4, 8或32位级别进行工作,这取决于您的系统最适合什么。这将增加程序大小,但减少执行时间。也许可以尝试实现某种形式的自适应查找表,它取决于
sizeof(uint\u fast8\u t)
您无法保证未调整大小的int的最大大小,只能保证最小大小。如何计算这些大小?我发现在某些系统上,bitset::count可能比我自己的代码快,因为它利用了特殊的CPU指令。std::bitset
应该已经为此进行了优化(以及计数)。为什么要重新发明它?@Neil,对于uchar8,我使用查找表,而对于int32,其中的一个技巧就是std::bitset(v).count()
,其中位是8表示字符或其他。如果这是关键代码,我建议您尝试一下并分析一下它是否有帮助。*qa^*qb
读取int
,指针指向char
的位置。如果访问字节数组,代码将失败。“如果指针针对无符号int进行了适当对齐”。这是否意味着如果我写qa+=1
,而不是推进sizeof(unsigned int)
字节,它可以推进不同的字节数?@SergeyK.:你说的“失败”是什么意思?正如我的回答所说,它给出了形式上未定义的行为,但在大多数平台上,只要有合适的对齐方式,它就可以按要求工作。@ChronoTrigger:是的,指针应该对齐。但是,如果填充字节不是0,那么结果将是错误的。@ChronoTrigger:我不太确定你在问什么qa+=1
确实会前进sizeof(unsigned int)
字节,因为这是qa
所指向的类型。char
永远不会超过一个字节。一个字节可能大于8位。@CarlNorum计算机科学将字节定义为8位的集合。无论是C语言还是一些过时的、晦涩难懂的CPU类型都无法改变这一点。任何大于8位的定义都大于一个字节。严格地说,这些都不对。我当然同意这是吹毛求疵。有很多具有16位字节的DSP,所以它很难被忽略。存在CHAR_BIT宏是有原因的,也是语言标准努力避免使用Byte这个词的原因。