二进制转换中的十六进制与十进制

发布于 2024-11-26 10:59:30 字数 207 浏览 2 评论 0原文

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

int x = 0xFF;
int y = 255;

哪种语句编译速度更快,可以将实际位设置为整数值?

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

For example, here are two ways to set an integer variable (say C++):

int x = 0xFF;
int y = 255;

Which statement would compile faster to set the actual bits to the integer value?

Edited: *compile changed from execute. I assumed the conversion to binary was at execution time, but seems to be at compile time given @muntoo's answer

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷雾森÷林ヴ 2024-12-03 10:59:30

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

添加以回复评论:
事情是这样的。编译器有一个解析器,可能是递归下降的,并且在底部调用词法分析器来获取标记。在这种情况下,=之后的标记是一个数字,它可以通过前导数字来判断,所以它是这样的,其中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 个指令。
在十六进制情况下,每个字符的指令可能会稍微多一些,但十进制数会有更多的字符,因此很难判断哪个应该更快。
这种情况只发生在您有能力在代码中输入的此类整数总数时,例如大约 100 个。
如果机器每秒可以执行 10^8 条指令,那么它可以以每秒大约 10^7 的速度读取数字,或者每个字符大约 100 纳秒,或者文件中所有数字的读取时间为 10 微秒,给出或取一个数量级。

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

There is absolutely no difference in execution time, and probably no difference in compilation speed.

Added in response to comment:
Here's what happens. The compiler has a parser, probably recursive-descent, and at bottom it calls a lexer to get tokens. In this case the token after = is a number, which it can tell by the leading digit, so it goes something like this, where pc is a pointer to the current character:

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
    }
  }
}

Anyway, as you can see, it's a pretty tight loop that does isdigit or ishexdigit or tolower once or twice for each character in the number, and multiplication, subtraction, and addition. Assuming those functions are in-line, we're talking maybe 10-20 instructions per character.
It's maybe slightly more instructions per character in the hex case, but the decimal number will have somewhat more characters, so it's hard to tell a-priori which should be faster.
This only happens for the total number of such integers you had the energy to type in your code, like maybe around a 100.
If the machine can do, say, 10^8 instructions per second, it can read digits at the rate of around 10^7 per second, or around 100 nanoseconds per character, or 10 microseconds for all the numbers in your file, give or take an order of magnitude.

Once the compiler knows it's a number, it just becomes part of the abstract syntax tree, which is used to generate assembly language. By that time, the fact that it was hexadecimal or decimal has long since been forgotten. All it knows is it's a binary integer of a certain value, so the assembly language will be identical.

时光匆匆的小流年 2024-12-03 10:59:30

从编译器的角度来看,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()更快。 (AFaf 的概率高于 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));
}

虽然您不会得到十进制到二进制的位移,但也不会得到 AFaf

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 的编译速度可能更快。 :)

0xFF is the same as 255, in the point of view of your compiler. Both will generate exactly the same code. Your compiler "converts" them both to 11111111b.


Compilation speed all depends on the compiler and how it compiles.

For example 0xFF could be identified as a hexadecimal number (ignoring regexes, which would be the preferred method):

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);
}

Compared to 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);
}

Well, myisnum() is generally faster than myishex(). (The probability of A-F or a-f is higher than 0-9.)


But conversion from FF to a binary number may be faster slower than 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));
}

Whereas you don't get no bitshifts in decimal to binary, but you don't get no A-F nor a-f neither.

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);    
}

Conclusion: Still depends on the compiler, but the 255 is probably faster to compile. :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文