TSQL按位非

TSQL按位非,sql,sql-server,bit,Sql,Sql Server,Bit,整数170的二进制表示为10101010 将位反转为0 1 0 1 0 1 转换成十进制的是整数85 为什么选择~170 返回-171 我正在努力理解我在这里遗漏了什么。它不是一个字节(8位),可能是一个32位的数字 无论长度(16、32或64)如何,它都将具有前导0s。在16位中,这看起来像: 0000 0000 1010 1010变为1111111 0101 0101,即-171 您可以使用windows calculator和程序员模式、十进制以及高于所选字节的任何内容来完成此操作。输入1

整数170的二进制表示为
10101010
将位反转为
0 1 0 1 0 1
转换成十进制的是整数85

为什么
选择~170
返回-171

我正在努力理解我在这里遗漏了什么。

它不是一个字节(8位),可能是一个32位的数字

无论长度(16、32或64)如何,它都将具有前导
0
s。在16位中,这看起来像:

0000 0000 1010 1010
变为
1111111 0101 0101
,即-171

您可以使用windows calculator和程序员模式、十进制以及高于所选字节的任何内容来完成此操作。输入170,点击NOT,得到-171,它将显示每个的位表示

另一件需要注意的事情是
10101010
实际上不是170,如果它是有符号字节的话。作为有符号字节,它将是-86。如您所料,在字节模式中反转它会产生85

还要注意有符号和无符号位模式之间的差异。位长度很重要,因为对于有符号整数,以
1
开头的数字是负数,通过反转位并加上一,可以得到负数的绝对值。(见:)

这就是为什么
1010 1010
(作为字节)在反转时给出正数,而
0000 0000 1010 1010
在反转时给出负数的原因

作为参考,SQL Server中的整数类型有:

  • tinyint:字节(1字节)(8位)(无符号)
  • smallint:字(2字节)(16位)(有符号)
  • int:dword(4字节)(32位)(有符号)
  • bigint:qword(8字节)(64位)(带符号)

请注意,虽然我描述了有符号字节,但SQL Server似乎根本没有有符号字节,也没有更大的无符号整数类型。因此,如果您使用
tinyint
它将始终是无符号的,如果您使用任何较大的,它将始终是有符号的。

尝试
选择~CAST(170 AS tinyint)以避免对32位整数进行运算。谢谢,这给出了我期望的答案,即85。如果使用15位,您将得到建议的0 0 0 0 0 0 1 0 1 0 1 0 1 0。将位反转得到1 1 1 0 1 0 1 0 1 0 1 1,转换为十进制的是65365而不是-171。@AAsk
1111111 0101 0101
有符号16位整数是-171。作为一个无符号16位整数,它是65365,是的。谢谢;这使我对正在发生的事情有了更好的了解。但是,我觉得有点奇怪,因为TSL(据我所知)没有将INT指定为有符号或无符号的功能。@AAsk看起来
tinyint
s总是无符号的,任何较大的整数类型总是有符号的。