【问题标题】:Bitwise NOT example on sql serversql server 上的按位非示例
【发布时间】:2021-09-25 22:41:07
【问题描述】:

在SQL Server的网上书籍中,有一个解释bitwise not操作符的例子让我很困惑:

170(a_int_value 或 A)的二进制表示为 0000 0000 1010 1010。对该值执行按位 NOT 运算会产生二进制结果 1111 1111 0101 0101,即十进制 -171。

因为一个整数在 SQL Server 中是 4 个字节,它不应该是:

170: 0000 0000 0000 0000 0000 0000 1010 1010 (0x000000AA)

~170 = -171 : 1111 1111 1111 1111 1111 1111 0101 0101 (0xFFFFFF55)

例如,按位非运算符给出的结果是:1111 1111 0101 0101,即 0xFF55,如果我们将其转换为 int,则它完全是一个不同的整数:

Select cast(0xFF55 as int)
--> 65365

如果是 smallint,那么这个例子就是真的:

Select cast(0xFF55 as smallint)
--> -171

该示例是否遗漏了 1 的前 2 个字节,还是我误解了什么?

谢谢,

【问题讨论】:

  • 你是对的。 INT 使用 4 个字节。也许示例中有错字,它正在考虑使用SMALLINT(2 个字节)。
  • 是的,你是对的。他们正在截断两个高阶字节,这是误导/不正确的。
  • 拉取请求是filed
  • @GSerg :谢谢,我在找这个,你有关于如何通知 MS 此类问题的任何文档吗?有人可以这样做吗?
  • @sporoy,任何拥有 github 帐户的人都可以编辑文档页面并提交拉取请求以供审查和批准。单击页面右上角的编辑链接。然后点击编辑图标,通过网页界面进行编辑。

标签: sql sql-server


【解决方案1】:

你是对的。

那个article现在已经更新为说

170(a_int_valueA)的二进制表示为0000 0000 0000 0000 0000 0000 1010 1010。对该值执行按位非运算会产生二进制结果1111 1111 1111 1111 1111 1111 0101 0101,即十进制-171。

【讨论】:

    【解决方案2】:

    确实,如果您使用按位与 (&) 执行强制转换,给定 SQL 值中的最大 INT,则从 1 开始并向上移动,注意最大 INT 是最高值。

    参考 (&) https://docs.microsoft.com/en-us/sql/t-sql/language-elements/bitwise-and-transact-sql?view=sql-server-ver15

    因此,正如您所看到的,它取决于输入存储大小的类型(请参阅该 OP 引用页面上的注释),在这里我们可以看到它会是什么(我添加了空格以使其在视觉上更容易看到)注意2147483647 是最大 INT

    BinaryStringNot170
    ---------------------------------------
    1111 1111 1111 1111 1111 1111 0101 0101
    
    BinaryString170
    ---------------------------------------
    1000 0000 0000 0000 0000 0000 1010 1010
    

    以及产生这些的查询:

    SELECT 
         cast( cast((~ 170) & 2147483647 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 1073741824 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 536870912 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 268435456 as bit) as CHAR(1)) + ' '
        +cast( cast((~ 170) & 134217728 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 67108864 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 33554432 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 16777216 as bit) as CHAR(1)) + ' '
        +cast( cast((~ 170) & 8388608 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 4194304 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 2097152 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 1048576 as bit) as CHAR(1)) + ' '
        +cast( cast((~ 170) & 524288 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 262144 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 131072 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 65536 as bit) as CHAR(1)) + ' '
        +cast( cast((~ 170) & 32768 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 16384 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 8192 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 4096 as bit) as CHAR(1)) + ' '
        +cast( cast((~ 170) & 2048 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 1024 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 512 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 256 as bit) as CHAR(1)) + ' '
        +cast( cast((~ 170) & 128 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 64 as bit) as CHAR(1)) 
        +cast( cast((~ 170) & 32 as bit) as CHAR(1))
        +cast( cast((~ 170) & 16 as bit)  as CHAR(1)) + ' '
        +cast( cast((~ 170) & 8 as bit)  as CHAR(1))
        +cast( cast((~ 170) & 4 as bit)  as CHAR(1))
        +cast( cast((~ 170) & 2 as bit)   as CHAR(1))
        +cast( cast((~ 170) & 1 as bit)  as CHAR(1))
     AS BinaryStringNot170
    
    
     SELECT 
         cast( cast(( 170) & 2147483647 as bit) as CHAR(1))  
        +cast( cast(( 170) & 1073741824 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 536870912 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 268435456 as bit) as CHAR(1)) + ' '
        +cast( cast(( 170) & 134217728 as bit) as CHAR(1))  
        +cast( cast(( 170) & 67108864 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 33554432 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 16777216 as bit) as CHAR(1))  + ' '
        +cast( cast(( 170) & 8388608 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 4194304 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 2097152 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 1048576 as bit) as CHAR(1))  + ' '
        +cast( cast(( 170) & 524288 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 262144 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 131072 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 65536 as bit) as CHAR(1)) + ' '
        +cast( cast(( 170) & 32768 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 16384 as bit) as CHAR(1))  
        +cast( cast(( 170) & 8192 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 4096 as bit) as CHAR(1)) + ' '
        +cast( cast(( 170) & 2048 as bit) as CHAR(1))  
        +cast( cast(( 170) & 1024 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 512 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 256 as bit) as CHAR(1))  + ' '
        +cast( cast(( 170) & 128 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 64 as bit) as CHAR(1)) 
        +cast( cast(( 170) & 32 as bit) as CHAR(1))
        +cast( cast(( 170) & 16 as bit)  as CHAR(1)) + ' '
        +cast( cast(( 170) & 8 as bit)  as CHAR(1))
        +cast( cast(( 170) & 4 as bit)  as CHAR(1))
        +cast( cast(( 170) & 2 as bit)   as CHAR(1))
        +cast( cast(( 170) & 1 as bit)  as CHAR(1))
     AS BinaryString170
    

    为了更完整,请注意这将返回存储在 sql 中的 MAXINT 值

    SELECT CONVERT(INT, CONVERT(VARBINARY, '0x7FFFFFFF', 1))
    

    这将返回 -1

    SELECT CONVERT(INT, CONVERT(VARBINARY, '0xFFFFFFFF', 1))
    

    【讨论】:

    • hi mark,我认为您提交的代码不对,而不是使用max int 2,147,483,647(0x7fffffff = 01111111 11111111 11111111 11111111)您必须使用Min Int -2,147,483,648(0x80000000 = 10000000 00000000) .在您的帖子中,您可以看到 BinaryStringNot170 和 BinaryString170 并不是真正的二进制补码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 2012-12-25
    相关资源
    最近更新 更多