SQL位运算符-负数符号位问题

负数的二进制由其绝对值的二进制前面 补 \color{red}\mathbf{0} 取反 加 \color{red}\mathbf{1} 得到

例如: 60 的二进制为 11\ 1100,如果要用八位表示二进制,则补 0 后的原码是 0011\ 1100,取反为 1100\ 0011,再 +1 得 1100\ 0100,由 -2^7+2^6+2^2=-2^6+2^2=-64+4=-60 (首位为符号位,要乘以-1),故 -60 的二进制为 1100\ 0100

& 运算符

1. 负数与正数:

>sqlite .mode line
>sqlite select -4 & 10;  /*  4 转换二进制为 0000 0100,反码 1111 1011,
                      加 1 得 -4 的二进制为 1111 1100,
                            10 转换二进制为 0000 1010 
                            则按位取与‘&’得 0000 1000,转为十进制 8 */               
-4 & 10 = 8

2. 负数与负数:

>sqlite select -3 & -7;  /* 3 转换二进制为 0000 0011,反码 1111 1100,
                                                     加 1 得 -4 的二进制为 1111 1101,
                            7 转换二进制为 0000 0111,反码 1111 1000,
                                                     加 1 得 -7 得二进制为 1111 1001,
                                                           则按位取与‘&’得 1111 1001,
                            转为十进制 -2^7+2^6+2^5+2^4+2^3+1=-7 */           
-3 & -7 = -7

3. 正数与正数:

>sqlite select 5 & 15;  /* 5  转换二进制为 0000 0101,
                           15 转换二进制为 0000 1111,
                           则按位取与‘&’得 0000 0101,转为十进制 5 */
5 + 15 = 5

 | 运算符

与 & 运算符类似,不再举例

 ~ 运算符

1. 负数取反:负数需要用补码(原码取反+1得补码,符号位不变 )

>sqlite select ~-60; /* -60 转换二进制为 1100 0100,       
                         则按位取反‘~’为 0011 1011,转为十进制 2^5+2^4+2^3+3=59 */
~-60 = 59

2. 正数取反:默认补码形式,即最高位是符号位,转换为十进制时要乘以 -1(而非补码形式时最无负号位,最高位转换十进制时不需要乘以 -1)

>sqlite select ~60; /* 60 转换二进制为 0011 1100,
                       则按位取反‘~’为 1100 0011,转为十进制 -2^7+2^6+2+1=-61 */
~60 = -61

 << 运算符

左移会让最高位溢出(也就是把最高位抛弃),接着向最低位补 0 

\sqlite select 72 << 2;  /* 72 转换二进制为 0000 0000 0000 0000 0000 0000 0100 1000,
                                 左移两位为 0000 0000 0000 0000 0000 0001 0010 0000,
                                 转为十进制 2^8+2^5=288 */
72 << 2 = 288

\sqlite select -72 << 2;  /* -72 转换二进制为 1111 1111 1111 1111 1111 1111 1011 1000,
                                   左移两位为 1111 1111 1111 1111 1111 1110 1110 0000,
                                   转为十进制 -2^9+2^7+2^6+2^5=-288 */
-72 << 2 = -288

 >> 运算符

右移会让最低位溢出(也就是把最低位抛弃),接着向高位补 1 (负数) / 0 (正数) 

\sqlite select 72 >> 2;  /* 72 转换二进制为 0000 0000 0000 0000 0000 0000 0100 1000,
                                 左移两位为 0000 0000 0000 0000 0000 0000 0001 0010,
                                 转为十进制 2^4+2=18 */
72 << 2 = 18

\sqlite select -72 >> 2;  /* -72 转换二进制 1111 1111 1111 1111 1111 1111 1011 1000,
                                   左移两位 1111 1111 1111 1111 1111 1111 1110 1110,
                                   转十进制 -2^5+2^3+2^2+2=-18 */
-72 << 2 = -18

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值