常量整数值按位非(NOT)运算符的逻辑原理是什么?
拆解按位非(NOT)的“意外”结果:隐式整数位数提升在搞鬼
嘿,我当初刚接触这类位运算的时候也被这个结果搞懵过!其实核心原因是语言的隐式整数位数提升规则,和你理解的“操作数类型”不是一回事,我给你一步步理清楚:
先看你的例子对应的底层逻辑
我们把每个十六进制值转换成二进制,结合“零扩展”规则来看:
- 对于
not $FF:$FF是8位无符号二进制:0b11111111- 执行位运算时,语言会自动把它零扩展到默认的基本整数宽度(比如16位),变成
0b0000000011111111 - 按位取反后得到
0b1111111100000000,也就是十六进制的$FF00
- 对于
not $FFFF:$FFFF是16位二进制:0b1111111111111111- 零扩展到32位基本整数宽度:
0b00000000000000001111111111111111 - 取反后得到
0b11111111111111110000000000000000,即$FFFF0000
- 对于
not $FFFFFFFF和not $FFFFFFFFFFFFFFFF:
这两个值本身已经是32位/64位的全1二进制,零扩展后还是自身,取反自然就是对应宽度的全0(你看到的$00是简写,实际是$00000000或$0000000000000000)
为什么文档描述和实际不符?
文档里说“not操作的结果与操作数类型相同”,这里的“类型”大概率指的是符号属性(无符号/有符号),而不是存储位数。很多语言的位运算规则里,小宽度的整数(比如byte、word)会被自动提升到语言的“基本整数类型”(比如16位、32位)再执行运算,结果的类型就是这个基本整数类型,而非原操作数的窄位数类型。
验证这个逻辑的小技巧
如果你想确认,可以试试这两个操作:
- 显式指定操作数的位数:比如如果你的语言支持,写
not byte($FF),应该会得到$00(8位取反的结果) - 查看操作数和结果的类型:用类型检测函数(比如
typeof)看$FF是不是byte类型,而not $FF是不是word(16位整数)类型
内容的提问来源于stack exchange,提问作者ventiseis




