7

我说的是这个:

如果我们有字母“A”,它是十进制的 77 和十六进制的 4D。我正在寻找获得 D 的最快方法。

我想了两个办法:

给定 x 是一个字节。

  1. x << 4; x >> 4

  2. x %= 16

还有其他方法吗?哪个更快?

4

6 回答 6

37

简洁很好 - 解释更好:)

  • x &= 0x0f

是,当然,正确的答案。它准确地表达了您想要实现的意图,并且在任何健全的架构上总是会编译到最少的指令数(即 1)。将常量放入按位运算符时,请务必使用十六进制而不是十进制。

  • x <<= 4; x >>= 4

仅当您的“字节”是正确的无符号类型时才有效。如果它实际上是一个有符号字符,那么第二个操作可能会导致符号扩展(即原始位 3 也会出现在位 4-7 中)。

如果不进行优化,这当然需要 2 条指令,但在 OSX 上使用 GCC,甚至-O1会减少到第一个答案。

  • x %= 16

即使没有启用优化器,您的编译器几乎肯定会在这里做正确的事情,并将昂贵的 div/mod 操作变成第一个答案。然而,它只能为 2 的幂次方做到这一点,而且这种范式并没有让你想要实现的目标变得那么明显。

于 2008-11-17T11:21:21.180 回答
22

我总是用x &= 0x0f

于 2008-11-17T10:43:18.930 回答
10

有很多好的答案,其中一些在技术上是正确的。

在更广泛的范围内,人们应该理解 C/C++ 不是汇编程序。程序员的工作是尝试告诉编译器你想要实现的意图。编译器将根据体系结构和各种优化标志选择最佳方式。

x &= 0x0F; 是告诉编译器你想要实现什么的最清晰的方法。如果在某些架构上上下移动更快,那么编译器的工作就是了解它并做正确的事情。

于 2008-11-17T11:53:16.607 回答
4

单AND操作就可以做到。

x = (x & 0x0F);
于 2008-11-17T10:42:57.963 回答
2

它在某种程度上取决于架构——在 ARM 上上下移动可能是最快的方式——但是编译器应该为你做这件事。事实上,所有建议的方法都可能会被编译器优化为相同的代码。

于 2008-11-17T11:20:23.677 回答
0

x = x & 15

于 2008-11-17T10:44:52.720 回答