我说的是这个:
如果我们有字母“A”,它是十进制的 77 和十六进制的 4D。我正在寻找获得 D 的最快方法。
我想了两个办法:
给定 x 是一个字节。
x << 4; x >> 4
x %= 16
还有其他方法吗?哪个更快?
我说的是这个:
如果我们有字母“A”,它是十进制的 77 和十六进制的 4D。我正在寻找获得 D 的最快方法。
我想了两个办法:
给定 x 是一个字节。
x << 4; x >> 4
x %= 16
还有其他方法吗?哪个更快?
简洁很好 - 解释更好:)
x &= 0x0f
是,当然,正确的答案。它准确地表达了您想要实现的意图,并且在任何健全的架构上总是会编译到最少的指令数(即 1)。将常量放入按位运算符时,请务必使用十六进制而不是十进制。
x <<= 4; x >>= 4
仅当您的“字节”是正确的无符号类型时才有效。如果它实际上是一个有符号字符,那么第二个操作可能会导致符号扩展(即原始位 3 也会出现在位 4-7 中)。
如果不进行优化,这当然需要 2 条指令,但在 OSX 上使用 GCC,甚至
-O1
会减少到第一个答案。
x %= 16
即使没有启用优化器,您的编译器几乎肯定会在这里做正确的事情,并将昂贵的 div/mod 操作变成第一个答案。然而,它只能为 2 的幂次方做到这一点,而且这种范式并没有让你想要实现的目标变得那么明显。
我总是用x &= 0x0f
有很多好的答案,其中一些在技术上是正确的。
在更广泛的范围内,人们应该理解 C/C++ 不是汇编程序。程序员的工作是尝试告诉编译器你想要实现的意图。编译器将根据体系结构和各种优化标志选择最佳方式。
x &= 0x0F; 是告诉编译器你想要实现什么的最清晰的方法。如果在某些架构上上下移动更快,那么编译器的工作就是了解它并做正确的事情。
单AND操作就可以做到。
x = (x & 0x0F);
它在某种程度上取决于架构——在 ARM 上上下移动可能是最快的方式——但是编译器应该为你做这件事。事实上,所有建议的方法都可能会被编译器优化为相同的代码。
x = x & 15