Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C hash2无符号整数溢出_C_Murmurhash - Fatal编程技术网

C hash2无符号整数溢出

C hash2无符号整数溢出,c,murmurhash,C,Murmurhash,我目前正在尝试实现一个hashtable/trie,但当我将参数传递给hash2时,它会返回一个数字,但我得到了unsigned int overflow的运行时错误: test.c:53:12:运行时错误:无符号整数溢出:24930*1540483477不能在类型“unsigned int”中表示 test.c:60:4:运行时错误:无符号整数溢出:2950274797*1540483477不能在类型“unsigned int”中表示 6265 我在第53行和第60行放了一堆星星(*) 我不确

我目前正在尝试实现一个hashtable/trie,但当我将参数传递给hash2时,它会返回一个数字,但我得到了unsigned int overflow的运行时错误:

test.c:53:12:运行时错误:无符号整数溢出:24930*1540483477不能在类型“unsigned int”中表示

test.c:60:4:运行时错误:无符号整数溢出:2950274797*1540483477不能在类型“unsigned int”中表示 6265

我在第53行和第60行放了一堆星星(*)

我不确定我是否传递了一些错误的参数。任何帮助都将不胜感激

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed );

int main(void)
{
   const char* s= "aa";
   unsigned int number= MurmurHash2 (s, (int)strlen(s), 1) % 10000;
   printf("%u\n", number);
}

unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed )
{
// 'm' and 'r' are mixing constants generated offline.
// They're not really 'magic', they just happen to work well.

const unsigned int m = 0x5bd1e995;
const int r = 24;

// Initialize the hash to a 'random' value

unsigned int h = seed ^ len;

// Mix 4 bytes at a time into the hash

const unsigned char * data = (const unsigned char *)key;

while(len >= 4)
{
    unsigned int k = *(unsigned int *)data;

    k *= m;
    k ^= k >> r;
    k *= m;

    h *= m;
    h ^= k;

    data += 4;
    len -= 4;
}

// Handle the last few bytes of the input array

switch(len)
{
case 3: h ^= data[2] << 16;
case 2: h ^= data[1] << 8;
case 1: h ^= data[0];
        h *= m; ************************************************
};

// Do a few final mixes of the hash to ensure the last few
// bytes are well-incorporated.

h ^= h >> 13;
h *= m;   **************************************
h ^= h >> 15;

return h;
}
#包括
#包括
#包括
无符号整数哈希2(常量void*键、整数len、无符号整数种子);
内部主(空)
{
const char*s=“aa”;
无符号整数=2(s,(int)strlen(s),1)%10000;
printf(“%u\n”,数字);
}
无符号整数哈希2(常量void*键、整数len、无符号整数种子)
{
//“m”和“r”是脱机生成的混合常量。
//它们不是真正的“魔法”,它们只是碰巧工作得很好。
常量无符号整数m=0x5bd1e995;
常数int r=24;
//将哈希初始化为“随机”值
无符号整数h=种子^len;
//在散列中一次混合4个字节
常量无符号字符*数据=(常量无符号字符*)键;
而(len>=4)
{
无符号整数k=*(无符号整数*)数据;
k*=m;
k^=k>>r;
k*=m;
h*=m;
h^=k;
数据+=4;
len-=4;
}
//处理输入数组的最后几个字节
开关(透镜)
{
案例3:h^=数据[2]13;
h*=m**************************************
h^=h>>15;
返回h;
}

unsigned int具有与系统相关的位数

在大多数系统上,这个数字是32位(4字节),但有些系统可能使用不同的大小(即在某些机器上是64位(8字节))

但是,杂音散列“字”是特定的大小。64位变量需要64位无符号类型,32位变量需要32位无符号类型

使用
中定义的
uint64\u t
uint32\u t
类型可以解决此不一致性

我想补充一点,后缀
UL
(unsigned long)可能应该添加到您使用的任何数值常量中。即
2950274797UL*1540483477UL

如@nwellnhof所示,您的代码似乎使用了算法的32位变体

乘法指令中的溢出在这些情况下是正常的(结果大于可用位数并被截断)。作为散列过程的一部分,这种数据丢失是可以接受的

考虑使用以下方法将预期结果告知编译器:

 h = (uint32_t)(((uint64_t)h * m) & 0xFFFFFFFF)

祝你好运!

unsigned int
具有与系统相关的位数

在大多数系统上,这个数字是32位(4字节),但有些系统可能使用不同的大小(即在某些机器上是64位(8字节))

但是,杂音散列“字”是特定的大小。64位变量需要64位无符号类型,32位变量需要32位无符号类型

使用
中定义的
uint64\u t
uint32\u t
类型可以解决此不一致性

我想补充一点,后缀
UL
(unsigned long)可能应该添加到您使用的任何数值常量中。即
2950274797UL*1540483477UL

如@nwellnhof所示,您的代码似乎使用了算法的32位变体

乘法指令中的溢出在这些情况下是正常的(结果大于可用位数并被截断)。作为散列过程的一部分,这种数据丢失是可以接受的

考虑使用以下方法将预期结果告知编译器:

 h = (uint32_t)(((uint64_t)h * m) & 0xFFFFFFFF)

祝您好运!

您似乎正在使用UBSan选项
-fsanize=unsigned integer overflow
或启用此检查的其他选项,如
-fsanize=integer
。说明:

请注意,与有符号整数溢出不同,无符号整数不是未定义的行为。然而,尽管它具有定义良好的语义,但它通常是无意的,因此UBSan提供了捕获它的方法

在杂音散列的情况下,乘法中的无符号整数溢出完全是故意的,因此应该禁用该选项

  • 如果显式使用
    -fsanize=unsigned integer overflow
    ,请将其删除
  • 如果由另一个选项启用,则传递
    -fno sanitize=无符号整数溢出
  • 或者,使用
    \uuuu属性((无清除(“无符号整数溢出”))注释函数
    2

<>另一个注释:您的代码似乎是从假定为32位<代码> int >代码> s中复制的。您应该考虑使用<代码> uint 32→t/代码>。

看起来,您正在使用UBSAN选项<代码> -FSANITIZE =无符号整数溢出< /代码>或其他选项如<代码> -FSATIZIZ=整数< /代码>来启用此检查。:

请注意,与有符号整数溢出不同,无符号整数不是未定义的行为。然而,尽管它具有定义良好的语义,但它通常是无意的,因此UBSan提供了捕获它的方法

在杂音散列的情况下,乘法中的无符号整数溢出完全是故意的,因此应该禁用该选项

  • 如果显式使用
    -fsanize=unsigned integer overflow
    ,请将其删除
  • 如果由另一个选项启用,则传递
    -fno sanitize=无符号整数溢出
  • 或者,使用
    \uuuu属性((无清除(“无符号整数溢出”))注释函数
    2

<>另一个注释:您的代码似乎是从假定为32位<代码> int >代码>的。您应该考虑使用<代码> UINT32×T 。