加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C编译器是否识别2的幂?

发布时间:2020-12-16 10:32:41 所属栏目:百科 来源:网络整理
导读:我正在构建一个自定义哈希,我根据公式对字符串中的所有字母求和: string[0] * 65536 + string[1] * 32768 + string[2] * 16384 + ... 而且我遇到了一个问题,我是否应该将这些数字定义为int数组中的常量,如下所示: const int MULTIPLICATION[] = { 65536,32
我正在构建一个自定义哈希,我根据公式对字符串中的所有字母求和:

string[0] * 65536 + string[1] * 32768 + string[2] * 16384 + ...

而且我遇到了一个问题,我是否应该将这些数字定义为int数组中的常量,如下所示:

const int MULTIPLICATION[] = {
    65536,32768,16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1
}

或者,也许我应该在计算哈希本身时生成这些数字(虽然由于它们尚未生成而可能会失去一些速度)?
我需要数百万次这个哈希计数,我希望编译器理解的主要事情是,而不是正常的MUL操作

MOV EBX,8
MUL EBX

它会的

SHL EAX,3

编译器是否理解如果我乘以2的幂来移位而不是通常的乘法?

另一个问题,我很确定当你用c写的时候它会移位
????数字* = 2;
但只是为了澄清,是吗?

谢谢,我已经找到了如何在调试器中查看dissasembly.是的,如果您使用它,编译器确实理解移位

number *= 65536

但是,如果你这样做,它会进行正常的乘法运算

number1 = 65536
number *= number1;

解决方法

试试吧!

你用的是什么编译器?您可以告诉大多数编译器在编译后保留中间文件,或者只编译(而不是汇编),这样您就可以实际查看它生成的汇编代码.

你可以在这other question of mine上看到这就是我所做的.

例如,在gcc中,-S标志表示“仅编译”.并且-masm = intel生成更可读的程序集,IMO.

编辑

总而言之,我认为以下是您正在寻找的算法(未经测试):

// Rotate right by n bits
#define ROR(a,n)   ((a >> n) | (a << (sizeof(a)*8-n)))


int custom_hash(const char* str,int len) {
    int hash = 0;
    int mult = 0x10000;  // 65536,but more obvious

    for (int i=0; i<len; i++) {
        hash += str[i] * mult;
        mult = ROR(mult,1);    
    }

    return mult;
}

首先,你没有指定当你有超过16个字符时会发生什么(乘数是多少?)所以在这个实现中,我使用了一个按位旋转. x86有bitwise rotate instructions(ror和rol分别为左右旋转).但是,C没有提供表达旋转操作的方法.所以我定义了为你做旋转的ROR宏. (了解它的工作原理留给读者练习!)

在我的循环中,我像你一样在0x10000(65536)开始乘数.循环的每次迭代,我将乘数右旋一位.这基本上将它除以2,直到达到1,之后变为0x80000000.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读