我想为二进制旋转创建宏。
我的目标是使这些宏对uint32_t
和uint64_t
操作数类型通用。
我来到了这个实现:
#define ROTL(X, N) (((X) << (N)) | ((X) >> (8 * sizeof(X) - (N))))
#define ROTR(X, N) (((X) >> (N)) | ((X) << (8 * sizeof(X) - (N))))
这些宏可以正常工作,但是
gcc
编译器在编译过程中会产生警告:warning: right shift count >= width of type [enabled by default]
#define ROTL(X, N) (((X) << (N)) | ((X) >> (8 * sizeof(X) - (N))))
warning: left shift count >= width of type [enabled by default]
#define ROTL(X, N) (((X) << (N)) | ((X) >> (8 * sizeof(X) - (N))))
我知道编译器抱怨
X
和N
类型之间可能不匹配。但是即使我同时投射X
和N
也会产生警告:ROTL((uint32_t)0xdeadbeef, (uint32_t)0U);
我该怎么做才能以正确的方式摆脱这些警告?
最佳答案
当第二个参数为零或大于第一个参数的位数时,您会遇到一些问题。您可以尝试使用该模块摆脱此问题。这个简单的例子似乎可行:
#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>
#include <limits.h>
#define ROTL(X, N) \
(((X) << ((N) % (CHAR_BIT * sizeof(X)))) | \
((X) >> ((CHAR_BIT * sizeof(X) - (N)) % (CHAR_BIT * sizeof(X)))))
int main() {
for (int i = 0; i < 100; i++) {
uint32_t a = ROTL(UINT32_C(0xdeadbeef), i);
printf("%d\t%"PRIX32"\n", i, a);
}
return 0;
}
我使用了
CHAR_BIT
和limits.h
的UINT32_C
和PRIX32
的inttypes.h
。您可以自行调整ROTR
以执行相同的操作。