如果您经常调用这些方法,那么最快的方法不是位操作,而是可能是查找表。为每个操作定义一个长度为 511 的数组。减号(减法)示例
static unsigned char maxTable[511];
memset(maxTable, 0, 255); // If smaller, emulates cutoff at zero
maxTable[255]=0; // If equal - return zero
for (int i=0; i<256; i++)
maxTable[255+i] = i; // If greater - return the difference
该数组是静态的并且仅初始化一次。现在您的减法可以定义为内联方法或使用预编译器:
#define MINUS(A,B) maxTable[A-B+255];
这个怎么运作?好吧,您想预先计算无符号字符的所有可能减法。结果从 -255 到 +255 不等,共有 511 个不同的结果。我们定义了一个包含所有可能结果的数组,但是因为在 C 中我们不能从负索引访问它,所以我们使用 +255(在 [A-B+255] 中)。您可以通过定义指向数组中心的指针来删除此操作。
const unsigned char *result = maxTable+255;
#define MINUS(A,B) result[A-B];
像这样使用它:
bsub = MINUS(13,15); // i.e 13-15 with zero cutoff as requested
请注意,执行速度非常快。只有一个减法和一个指针引用才能得到结果。没有分支。静态数组非常短,因此它们将完全加载到 CPU 的缓存中以进一步加快计算速度
同样适用于加法,但表略有不同(前 256 个元素将是索引,最后 255 个元素将等于 255 以模拟超过 255 的截止值。
如果你坚持位操作,使用 (a>b) 的答案是错误的。这仍然可以实现为分支。使用符号位技术
// (num1>num2) ? 1 : 0
#define is_int_biggerNotEqual( num1,num2) ((((__int32)((num2)-(num1)))&0x80000000)>>31)
现在你可以用它来计算减法和加法。
如果你想在没有分支的情况下模拟函数 max()、min(),请使用:
inline __int32 MIN_INT(__int32 x, __int32 y){ __int32 d=x-y; return y+(d&(d>>31)); }
inline __int32 MAX_INT(__int32 x, __int32 y){ __int32 d=x-y; return x-(d&(d>>31)); }
我上面的例子使用 32 位整数。您可以将其更改为 64,但我相信 32 位计算运行得更快一些。由你决定