解码十六进制数字的最快方法

Mar*_* A. 3 algorithm hex

我正在寻找获得十六进制ASCII字符的十进制值的最快方法,即保证出现在以下字符串中的一个(它可以是小写或大写,但没有空格):

0123456789ABCDEFabcdef
Run Code Online (Sandbox Code Playgroud)

到目前为止,我提出的最好的公式是:

char c = 'd';  // or any other hex character
int value = (((c & 0x1F) + 9) % 25;
Run Code Online (Sandbox Code Playgroud)

请注意,它是无分支的,但它确实包含昂贵的模运算.

我可以做得更好吗?

tot*_*oth 5

你可以做到没有模数和没有分支,只需要几个移位和减法.

int value = (c & 0x0F) + 9 - ((c&0x10)>>1) - ((c&0x10)>>4);
Run Code Online (Sandbox Code Playgroud)

我刚刚从你的公式开始,并使用了c&0x100用于字母和0x10for 的事实0-9.

请注意,正如注释中所指出的,由常量修改的mod将通过编译器对乘法和加法进行优化,但这应该稍微好一些,因为编译器没有前提条件c是十六进制数字.


Mar*_*som 5

如果您有可用的快速乘法:

int value = (c & 0x0f) + 9 * (c >> 6)
Run Code Online (Sandbox Code Playgroud)

  • gcc (v5.2.0, x64 target, -O3) 为这一行和 nm 的第二个变体生成完全相同的代码。(因为它知道它可以使用 `leal (%rax,%rax,8), %eax` 来执行该计算。) (2认同)