C ++编译器是否可以识别2的幂次?

我正在构建一个自定义散列,根据公式对字符串中的所有字母进行求和:

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;

尝试一下!

你使用什么编译器? 你可以告诉大多数编译器在编译之后将中间文件放在适当的位置,或者只是编译(而不是汇编),所以你可以看看它生成的汇编代码。

你可以在我的另一个问题上看到,这正是我所做的。

例如,在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具有按位旋转指令( rorrol用于左右旋转)。 但是,C没有提供表达旋转操作的方法。 所以我定义了为你旋转的ROR宏。 (了解它是如何工作的,仅供读者参考!)

在我的循环中,我像你一样在0x10000(65536)处启动乘法器。 循环的每次迭代,我将乘数右移一位。 这基本上将它除以2,直到你达到1,之后它变成0x80000000。


答案取决于你的编译器,硬件架构和其他可能的东西。

先验甚至不明显,即用换档来代替这种乘法是最佳的事情。 我认为通常应该让编译器进行指令级优化。

这就是说,让我们看看我的编译器做了什么:)

int i, j;

int main() {
  j = i * 8;
}

这是使用gcc 4.7.2-O3编译的结果

_main:
LFB0:
        movq    _i@GOTPCREL(%rip), %rax
        movl    (%rax), %edx
        movq    _j@GOTPCREL(%rip), %rax
        sall    $3, %edx                  ;<<<<<<<<<< THE SHIFT INSTRUCTION
        movl    %edx, (%rax)
        ret

所以,在我的环境中,答案显然是“是”。

至于你的其他问题,不要预先计算MULTIPLICATION 。 为了得到系数

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

只需从coeff = 65536开始,每次迭代将它向右移一位:

coeff >>= 1;

你为什么不使用C ++中的shift运算符?

(string[0] << 16) + (string[1] << 15) + (string[2] << 14) + ...
链接地址: http://www.djcxy.com/p/31571.html

上一篇: Does C++ compiler recognizes powers of 2?

下一篇: How C# or any other language NOT Equal to operator performs