我很好奇按位
NOT
操作到底是如何如此有效地执行反转以及它在“幕后”是什么样子的,所以我尝试自己实现它。如下图所示:
void bitwiseNOT(char* binaryString) {
int binaryLength = strlen(binaryString);
for (int i = 0; i < binaryLength; i++) {
binaryString[i] = (binaryString[i] == '1') ? '0' : '1';
}
}
这可以正确反转
binaryString
,但比简单使用按位 NOT
运算符 (~
) 效率低得多,例如。通过这样做:
long int binary = 0101010111010001011;
binary = ~binary;
在低级别到底发生了什么导致它比我的实现更快?
OP 函数
bitwiseNot
与 C 的 ~
运算符完全不同。 OP 函数对字符串进行操作,而 ~
对整数类型进行操作。
做什么“幕后”取决于实现,即,C 标准没有指定如何来实现
~
。但实现很可能只会发出一条汇编代码指令来执行按位非运算。 OP bitwiseNOT
函数肯定不会编译为单个指令。
查看 Godbolt Compiler Explorer 上的编译结果,GCC 和 Clang 似乎在 -O3 优化中发出相同的 x86-64 汇编代码,以实现围绕 ~
的简单包装函数。在这两种实现中,加载数据后,
~
都会编译为单个
not
指令。C 函数:
int not_wrapper(int x) {
return ~x;
}
海湾合作委员会13.2:
not_wrapper:
mov eax, edi
not eax
ret
铿锵17.0.1:
not_wrapper: # @not_wrapper
mov eax, edi
not eax
ret