在这里进行按位移位有什么意义?

时间:2013-08-05 14:56:31

标签: c++ c io bitwise-operators

我找到了快速I / O的代码。

    #include <cstdio>

inline void fastRead_int(int &x) {
    register int c = getchar_unlocked();
    x = 0;
    int neg = 0;

    for(; ((c<48 || c>57) && c != '-'); c = getchar_unlocked());

    if(c=='-') {
        neg = 1;
        c = getchar_unlocked();
    }

    for(; c>47 && c<58 ; c = getchar_unlocked()) {
        x = (x<<1) + (x<<3) + c - 48;
    }

    if(neg)
        x = -x;
}

inline void fastRead_string(char *str)
{
    register char c = 0;
    register int i = 0;

    while (c < 33)
        c = getchar_unlocked();

    while (c != '\n') {
        str[i] = c;
        c = getchar_unlocked();
        i = i + 1;
    }

    str[i] = '\0';
}

int main()
{

  int n;
  char s[100];

  fastRead_int(n);
    printf("%d\n", n);

  fastRead_string(s);
    printf("%s\n", s);
  return 0;
}

为什么存在按位移位(x <&lt;&lt; 1)+(x <&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&quot;当我们输入除了neg和数字之外的字符时会发生什么?

3 个答案:

答案 0 :(得分:8)

  

为什么存在按位移位(x <&lt;&lt; 1)+(x <&lt; 3)?

左移n位相当于乘以2^n;所以这个表达式相当于乘以10(从2^1 + 2^3 = 2 + 8 = 10开始)。

代码编写如下:相信(a)移位和加法明显快于乘法,(b)编译器不知道乘以10的最佳方法。对于大多数现代平台而言,这两种假设都是错误的,所以直截了当

x = x*10 + c - '0';    // '0' is more readable, and portable, than 48.

可能更快,更可读。

  

当我们输入除了neg和数字以外的字符时,还会发生什么?

第一个循环跳过&#39; - &#39;以外的任何其他内容。和数字;遇到非数字时,第二个停止(从流中消耗该字符后)。因此它将返回它在输入流中找到的第一个十进制整数,如果没有,则返回零。例如,如果输入是

xxxx123-456xxx-1234xxx

第一个调用将返回123,第二个456(因为第一个调用消耗了-),第三个-1234以及任何进一步的调用{ {1}}。

答案 1 :(得分:5)

这是非常糟糕的代码。首先,为什么48和57,而不是 比'0'和'9'。关于你的问题: 按位移位用于混淆,并可能减慢速度 事情发生了。表达式(x << 1) + (x << 3)具有相同的含义 数学值为10 * x。它的可读性差得多, 并且可能会干扰某些编译器优化。 (上 处理器,其中两个班次和加法更快 乘法,编译器将转换为 你,通常比你写出来更好,因为它知道 为什么它正在转移。)至于你的第二个问题:代码 有问题的人会先忽略所有角色,直到它为止 找到一个数字或一个减号;它将转换类似的东西 "abc12"12,没有丝毫错误。

实际上,完全没有错误检查(以及使用 getchar_unlocked,而不是getchar) 快。

答案 2 :(得分:1)

该例程正在组合读取字符值并在同一操作中将它们转换为整数值(显然很快)。这些转变有助于价值的总和。合并后的班次等于x10。