解码十六进制数字的最快方法
Fastest way to decode a hexadecimal digit
我正在寻找最快的方法来获取十六进制 ASCII 字符的十进制值,即保证出现在以下字符串中的一个(它可以是小写或大写,但没有白色 space):
0123456789ABCDEFabcdef
到目前为止,我想出的最好的公式是:
char c = 'd'; // or any other hex character
int value = (((c & 0x1F) + 9) % 25;
注意它是无分支的,但它确实包含一个昂贵的模运算。
我可以做得更好吗?
您可以在没有 modulos 和分支的情况下完成它,只需几个移位和减法。
int value = (c & 0x0F) + 9 - ((c&0x10)>>1) - ((c&0x10)>>4);
我刚从你的公式开始,并使用了 c&0x10
对于字母 0
和 0x10
对于 0-9
的事实。
请注意,正如评论中指出的那样,mod 常量将由编译器优化为乘法和加法,但这应该会稍微好一些,因为编译器没有 c
是十六进制数。
(d & 0xf) + ((d & 0x40) >> 3) + ((d & 0x40) >> 6)
非常直截了当。
略有不同的变体
(d & 0xf) + (d >> 6) + ((d >> 6) << 3)
保存另一个按位 and
操作。
两种变体基本上都是将第 6 位乘以 9(与 Mark Ransom 的回答相同,但没有硬件乘法)。
如果您有可用的快速乘法:
int value = (c & 0x0f) + 9 * (c >> 6)
我正在寻找最快的方法来获取十六进制 ASCII 字符的十进制值,即保证出现在以下字符串中的一个(它可以是小写或大写,但没有白色 space):
0123456789ABCDEFabcdef
到目前为止,我想出的最好的公式是:
char c = 'd'; // or any other hex character
int value = (((c & 0x1F) + 9) % 25;
注意它是无分支的,但它确实包含一个昂贵的模运算。
我可以做得更好吗?
您可以在没有 modulos 和分支的情况下完成它,只需几个移位和减法。
int value = (c & 0x0F) + 9 - ((c&0x10)>>1) - ((c&0x10)>>4);
我刚从你的公式开始,并使用了 c&0x10
对于字母 0
和 0x10
对于 0-9
的事实。
请注意,正如评论中指出的那样,mod 常量将由编译器优化为乘法和加法,但这应该会稍微好一些,因为编译器没有 c
是十六进制数。
(d & 0xf) + ((d & 0x40) >> 3) + ((d & 0x40) >> 6)
非常直截了当。
略有不同的变体
(d & 0xf) + (d >> 6) + ((d >> 6) << 3)
保存另一个按位 and
操作。
两种变体基本上都是将第 6 位乘以 9(与 Mark Ransom 的回答相同,但没有硬件乘法)。
如果您有可用的快速乘法:
int value = (c & 0x0f) + 9 * (c >> 6)