0
点赞
收藏
分享

微信扫一扫

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

洛茄 2022-04-07 阅读 48
sql

 & 运算符

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

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

2. 负数与负数:运算结果的符号位为负数需要转换(补码-1取反码后得原码,符号位不变)

>sqlite select -3 & -7;  /* -3 转换二进制为 1000 0011,取补码为 1111 1101,
                            -7 转换二进制为 1000 0111,取补码为 1111 1001,
                                               则按位取与‘&’得 1111 1001,
                                         符号位为负数,需要转换 1000 0111,转十进制 -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 转换二进制为 1011 1100,
                        -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,
                       最高位为符号位,1表示为负号,故转换为十进制 -2^7+2^6+2+1=-61 */
~60 = -61
举报

相关推荐

0 条评论