【问题标题】:Hexadecimal vs decimal on binary conversion二进制转换的十六进制与十进制
【发布时间】:2011-10-11 11:20:15
【问题描述】:

例如,这里有两种设置整数变量的方法(比如 C++):

int x = 0xFF;
int y = 255;

哪个语句会编译更快地将实际位设置为整数值?

已编辑:*编译从执行更改。我假设转换为二进制是在执行时,但似乎是在编译时给出@muntoo 的回答

【问题讨论】:

    标签: c++ binary decimal hex


    【解决方案1】:

    执行时间绝对没有差异,编译速度可能没有差异。

    添加以回应评论:
    这就是发生的事情。编译器有一个解析器,可能是递归下降的,在底部它调用一个词法分析器来获取标记。在这种情况下,= 之后的标记是一个数字,它可以通过前导数字来判断,所以它是这样的,其中 pc 是指向当前字符的指针:

    if (isdigit(*pc)){
      intpart = 0;
      if (pc[0]=='0' && pc[1]=='x'){
        pc += 2;
        while(ishexdigit(*pc)){
          intpart *= 16;
          if (isdigit(*pc)){
            intpart += (*pc - '0')
          }
          else {
            intpart += (tolower(*pc) - 'a' + 10);
          }
          pc++;
        }
      }
      else {
        while(isdigit(*pc)){
          intpart *= 10;
          intpart += (*pc - '0');
          pc++;
        }
        if (*pc == '.'){
          // ... handle fractional part
        }
      }
    }
    

    无论如何,如您所见,这是一个非常紧凑的循环,对数字中的每个字符执行一次或两次isdigitishexdigittolower,以及乘法、减法和加法。假设这些函数是内联的,我们说的每个字符可能有 10-20 条指令。 在十六进制情况下,每个字符的指令可能略多一些,但十进制数会有更多的字符,所以很难告诉 a-priori 哪个应该更快。 这只发生在你有能力在代码中输入的整数的总数中,比如大约 100。 如果机器每秒可以执行 10^8 条指令,它可以以每秒 10^7 左右的速度读取数字,或者每个字符大约 100 纳秒,或者文件中的所有数字为 10 微秒,给出或取一个数量级。

    一旦编译器知道它是一个数字,它就会成为抽象语法树的一部分,用于生成汇编语言。到那时,它是十六进制或十进制的事实早已被遗忘。它只知道它是一个特定值的二进制整数,因此汇编语言将是相同的。

    【讨论】:

    • 编译速度可能存在差异,尽管差异不大。 :-)
    • 额外的字符可能会导致额外的页面错误:)
    • @Mike 在执行时,程序会不会走不同的处理路线,以便将值存储在内存中:一个将十六进制转换为二进制,另一个将十进制转换为二进制?如果是这样,一种方法肯定会更快,即使它在今天的计算机上非常小
    • @Mike 我想我的意思是“在编译时”,请查看我编辑的问题 >_
    • 哇!感谢您提供出色的答案/代码。我花了一点时间来消化它,但一旦我消化了,我很惊讶~如果可以的话+10..再次感谢! :)
    【解决方案2】:

    0xFF255 相同,从您的编译器的角度来看。两者都将生成完全相同的代码。您的编译器将它们都“转换”为11111111b


    编译速度完全取决于编译器及其编译方式。

    例如,0xFF 可以识别为十六进制数字(忽略正则表达式,这将是首选方法):

    bool myishex(string sz)
    {
        if(sz[0] == '0' && sz[1] == 'x')
        {
            for(size_t i = 2; i < sz.length(); ++i)
                if(!(sz[i] >= '0' && sz[i] <= '9') || !(sz[i] >= 'A' && sz[i] <= 'F') || !(sz[i] >= 'a' && sz[i] <= 'f'))
                    return(false);
        }
        else
        {
            return(false);
        }
    
        return(true);
    }
    

    myisnum()相比:

    bool myisnum(string sz)
    {
        for(size_t i = 0; i < sz.length(); ++i)
            if(!(sz[i] >= '0' && sz[i] <= '9'))
                return(false);
    
        return(true);
    }
    

    嗯,myisnum()通常myishex()快。 (A-Fa-f的概率高于0-9。)


    但是从FF 到二进制数的转换可能比255

    int myhex2bin(string sz)
    {
        int b = 0;
    
        sz = sz.substr(2); // Cut the "0x" out.
    
        for(size_t i = 0; i < sz.length(); ++i)
        {
            sz[i] = tolower(sz[i]);
            b += myhexdigit2dec(sz[i]) << ((sz.length() - (i + 1)) << 2);
        }
    
        return(b);
    }
    
    // Unsafe. Optimized for speed.
    int myhexdigit2dec(char c)
    {
        return(c < 'A' ? c - '0' : (c < 'a' ? c - 'A' + 10 : c - 'a' + 10));
    }
    

    虽然你没有得到十进制到二进制的位移,但你也没有得到A-Fa-f

    int mydec2bin(string sz)
    {
        int b = 0;
        int factor = 1;
    
        for(size_t i = sz.length(); i > 0; --i)
        {
            b += (sz[i - 1] - '0') * factor;
            factor *= 10;
        }
    
        return(b);    
    }
    

    结论:仍然取决于编译器,但255可能编译得更快。 :)

    【讨论】:

    • 我不是要求编程实践,而是出于好奇。而且我的问题错了,我想我的意思是在编译时(请参阅我编辑的问题)。我假设十六进制/十进制到二进制的转换是在执行时进行的,但听起来你说它发生在编译时。就像您说的那样,无论今天强大的计算机需要几分之一秒,都应该有所不同。这是我感兴趣的理论。鉴于此,你知道哪个更快吗?
    猜你喜欢
    • 1970-01-01
    • 2014-10-30
    • 2012-06-26
    • 2014-01-07
    • 2012-04-08
    • 2015-12-12
    • 2020-06-27
    • 1970-01-01
    • 2016-02-09
    相关资源
    最近更新 更多