为什么T-SQL命令`SELECT ~ 0`的返回结果为-1?
按位非运算结果呈现固定规律的核心原理
SSMS中执行SELECT ~ 0返回-1、其他数值执行同类按位非操作也匹配固定规律的现象,本质是带符号整数的补码存储规则与按位非操作的原生定义共同作用的结果,拆解如下:
1. 按位非操作的原生定义
SQL Server中的~是一级按位运算符,没有任何隐式的数学转换逻辑,操作规则非常直接:
- 对参与运算的整数,逐位翻转其二进制表示的所有位:原本为0的位替换为1,原本为1的位替换为0
- 翻转过程不会跳过符号位,会连同标识数值正负的最高位一起处理,这也是它和数学层面“取相反数”操作的核心区别
2. ~ 0返回-1的推导过程
SSMS中直接书写的字面量0,默认会被匹配为32位长度的带符号int类型,整个计算过程可以手动复现:
- 32位带符号int类型中,0的二进制存储形式为全0:
0000 0000 0000 0000 0000 0000 0000 0000 - 执行按位非操作后,所有0位翻转为1,得到全1的二进制串:
1111 1111 1111 1111 1111 1111 1111 1111 - 按照带符号整数的补码编码规则,最高位为1代表数值为负数,全1的32位补码对应的十进制值恰好是-1。补码转换负数的逻辑为:对除最高位符号位外的剩余位取反、加1后添加负号,全1的二进制串经过该计算得到的数值就是-1。
3. 全量数值匹配固定规律的来源
对任意带符号整数x执行~x操作,结果都满足固定数学关系:~x = -x - 1,这就是所有数值执行同类操作都存在可预测规律的核心原因:
- 可直接在SSMS复现的验证用例:
- 执行
SELECT ~1返回-2:1的二进制为0000...0001,按位非后得到1111...1110,对应补码的十进制值为-2,匹配公式-1 -1 = -2 - 执行
SELECT ~-3返回2:-3的补码二进制为1111...1101,按位非后得到0000...0010,对应十进制值为2,匹配公式-(-3) -1 = 2
- 执行
- 如果参与运算的是无符号整数类型(如
tinyint),因为没有符号位的定义,按位非的结果会变为“同二进制位数下的最大值减去原值”,不再符合上述带符号数的计算规律,这也是测试时切换字段类型会得到不同结果的原因。
内容的提问来源于stack exchange,提问作者Strayda
相关产品推荐
相关产品推荐

