考虑以下32位和64位值:
uint32_t iVal32 = 0x AB CD 12 34;
uint64_t iVal64 = 0x AB CD 12 34 56 78 CA BE;
iVal32
是否包含某个16位(字)值? 0xCD12
。iVal64
是否包含某个16位(字)值? 0x3456
。0xCD12
iVal32
的任意位置。0x3456
iVal64
的任意位置。我承认这个问题存在一个荒谬的错误。在我之前的示例中,要检查的单词值不在iVal32
和iVal64
的单词边界中。因此,我的更正是:
iVal32
,要检查的字词值可以是0xABCD
或0x1234
。因此,例如,0xCD12
中找不到iVal32
。iVal64
,要检查的字词值可以是以下之一:0xABCD
或0x1234
或0x5678
或0xCABE
。因此,例如,0xCD12
中找不到0x3456
或0x78CA
或iVal64
。答案 0 :(得分:1)
if
答案 1 :(得分:1)
不完全清楚OP想要的是什么,但是给出了描述和后续评论,其中包含以下内容:
#include <iostream>
#include <stdint.h>
using namespace std;
bool contains(uint16_t item, uint32_t source);
bool contains(uint16_t item, uint64_t source);
int main()
{
uint32_t iVal32 = 0xABCD1234;
uint64_t iVal64 = 0xABCD12345678CABELL;
cout << contains(0x1234, iVal32) << endl;
cout << contains(0xABCD, iVal32) << endl;
cout << contains(0xABCD, iVal64) << endl;
cout << contains(0x1234, iVal64) << endl;
cout << contains(0x5678, iVal64) << endl;
cout << contains(0xCABE, iVal64) << endl;
return 0;
}
bool contains(uint16_t item, uint32_t source)
{
for (int i = 16 ; i >= 0 ; i -= 16)
{
if (((source << i) >> 16) == item)
{
return true;
}
}
return false;
}
bool contains(uint16_t item, uint64_t source)
{
for(int i = 48 ; i >= 0 ; i -= 16)
{
if (((source << i) >> 48) == item)
{
return true;
}
}
return false;
}
答案 2 :(得分:1)
这是32位的可能解决方案。
-1
返回32位值中16位值的位位置,
如果32位值不包含16位值,则为#include <stdio.h>
#include <stdint.h>
uint32_t iVal32 = 0xABCD1234;
uint64_t iVal64 = 0xABCD12345678CABE;
int find_pos(uint32_t value, uint16_t pattern)
{
int i;
for (i = 0; i < 32; i+=4) {
uint32_t v = (value & (0xFFFF << i));
uint32_t p = (pattern << i);
if (v == p)
return i;
}
return -1;
}
int main ()
{
printf("i = %i\n", find_pos(iVal32, 0xCD12));
return 0;
}
。
#include <stdio.h>
#include <stdint.h>
uint32_t iVal32 = 0xABCD1234;
uint64_t iVal64 = 0xABCD12345678CABE;
#define find_pos(value, pattern, width) \
({ \
int i; \
int found = 0; \
\
for (i = 0; i < width; i+=4) { \
typeof(value) v = (value & (0xFFFF << i)); \
typeof(value) p = (pattern << i); \
if (v == p) { \
found = 1; \
break; \
} \
} \
\
if (!found) \
i = -1; \
i; \
})
#define find_pos32(value, pattern) \
find_pos(value, pattern, 32)
#define find_pos64(value, pattern) \
find_pos(value, pattern, 64)
int main ()
{
printf("i = %i\n", find_pos32(iVal32, 0xCD12));
printf("i = %i\n", find_pos64(iVal64, 0x678C));
return 0;
}
<强>更新强>
以下是使用宏的32位和64位的可能解决方案。
{{1}}
答案 3 :(得分:1)
David的回答略有不同,非分支。
bool contains (uint32_t haystack, uint16_t needle)
{
uint32_t h1 = (haystack ^ needle) & 0xFFFF;
haystack >>= 16;
uint32_t h2 = haystack ^ needle; // No need for mask.
// If and only if needle was in haystack, h1 or h2 will now be 0
return (h1*h2) == 0;
}
两个XOR,一个移位,一个掩码,一个乘法和一个可能是免费的比较。只需要3个寄存器。 x64的明显扩展计算h1*h2*h3*h4
,但计算正在运行的产品可能更有效,因此我们不需要4个中间结果的寄存器。 (一个不错的优化器也会这样做)。
由于没有快捷方式评估,这有时可能需要更多指示,但缺乏快捷方式评估也意味着没有分支。我敢打赌,对于字符串搜索,这是一个净胜利。
有点偏离主题,问题提到了x86。 SSE是那里的逻辑选项,特别是对于64位。