【编程小记】位运算 x & -x 表示含义

简介: 【编程小记】位运算 x & -x 表示含义

位运算 x & -x 表示含义

一、原码反码补码

在计算机中,整数的数据的存储是按照补码的方式进行存储的

按照数据与0的大小,数据又被分为正数与负数

  • 正数的原码反码补码相同。
  • 负数的原码,反码,补码并不相同。它们之间的转换关系如下:
  • 负数的反码:该负数的原码除符号位外各位取反。
  • 负数的补码:负数的反码 + 1

我们来看下面的一个例子理解原码反码补码的求解:

[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补

通过上面的例子我们可以知道:

在计算机中取一个数 x(可正可负)的相反数,其实也就等价于:这个数的补码的基础上进行按位取反(包括符号位)之后在增加1

即:-x = (~x) +1

二、位运算 x & -x 表示含义

下面我们来讨论: 位运算 x & -x 表示含义

x为奇数时

例如: x = 3

x = 3
// 00000000  00000000  00000000  00000011   补码
-x
// 11111111  11111111  11111111  11111101   补码
ret = x & -x
//00000000  00000000  00000000  00000011   补码
//11111111  11111111  11111111  11111101   补码
ret
//00000000  00000000  00000000  00000001   补码

可以看到对于一个奇数如果执行表达式ret = x & -x 那么得到的结果是1,如果你不相信,你还可以试一试其他奇数。

原理分析

对于一个奇数 x,其比特位最后一位(最右边的那一位)一定是1 ,对这个奇数x取相反数也就相当于按位取反然后加一,奇数按位取反以后最后一位一定是0,然后+1后最后一位一定是1,但是 -x 除了最后一位与 x 相同,其余均不同,于是x & -x的结果一定是 1。

举例:

[+1]//   00000001  奇数的最后一位一定是1
[-1]//   11111111  相反数是 按位取反 然后 +1, 导致最后一位与原数相等

x为偶数时

例如 x = 4

x = 6
// 00000000  00000000  00000000  00000110   补码
-x
// 11111111  11111111  11111111  11111001   反码
// 11111111  11111111  11111111  11111010   补码
ret = x & -x
// 00000000  00000000  00000000  00000110   补码
// 11111111  11111111  11111111  11111010   补码
ret
// 00000000  00000000  00000000  00000010   补码

观察结果ret我们会发现:

  1. 这个结果只有一位值是1, 其他位均是0 ,而且这个值为 1 的位置是与原数 x 从右向左第一个比特位为 1 的位置相同
  2. 这个值的末位0的个数与原值 x 保持一致

原理分析

  1. 原数 x 最低非0位右边所有的0,经由取反后全部变为1,反码+1会导致这些1逐位发生进位并变为0,最终进位记到最低非0位。
  2. 原最低非0位是1,取反后是0,进位到这一位0变成1,不再向左进位
  3. 原最低非0位左边的每一位经由取反后 和 原码 进行与运算必为0

三、最终结论

当一个数与其相反数相与(&):

如果这个数是奇数, 则结果必为1(这个1的位置与原数的最低非零位位置相同)。

如果这个数是偶数, 则结果是一个特殊的数据,与原数据的最低非零位相同位置为1,其他位置全为0

用途: 一般可以用来获取某个二进制数的最低非零位

相关文章
|
1月前
|
算法 安全 C语言
C语言中的位操作运算符有什么作用
C语言中的位操作运算符有什么作用
18 0
|
4月前
|
C语言
c语言编程练习题:7-16 计算符号函数的值
请编写程序计算该函数对任一输入整数的值。
54 0
|
29天前
|
存储 编译器 C语言
【C语言】求任意两整数的和入门详解
【C语言】求任意两整数的和入门详解
6 0
|
4月前
|
C语言
C语言进阶教程(位操作和进制数的表示)
C语言进阶教程(位操作和进制数的表示)
44 0
|
7月前
|
存储 算法 C语言
C语言数组结合位运算实战-位移与查表
C语言数组结合位运算实战-位移与查表
59 0
|
9月前
|
C语言 索引
C语言基础知识:操作符详解(附操作符优先级及结合性一览表)(下)
C语言基础知识:操作符详解(附操作符优先级及结合性一览表)(下)
56 0
|
9月前
|
C语言
C语言基础知识:操作符详解(附操作符优先级及结合性一览表)(上)
C语言基础知识:操作符详解(附操作符优先级及结合性一览表)
67 0
|
10月前
|
存储 C语言
【C语言_复习_学习第二课】什么是进制?进制之间应该如何转换
什么是进制?在我们的生活中处处充满进制,一天是24个小时、一个小时是60分钟、一分钟是60秒、一个星期一共7天........还有大家听说过半斤八两这个词语吗?也就是说买半斤东西也就是八两,一斤也就是十六两,满16进一位这就是十六进制。我今天就当一次小学老师来考考你,5+8等于多少(我没有在和大家开玩笑)你会说等于13,你的回答就是十进制也就是满十进一,而在计算机中数字都是以二进制(只有1和0)存储的也就是满二进一位,当然也有八进制(从0到7)、十六进制(从0到F)都是类似的,八进制满八进一位,十六进制满十六进一位(其中十六进制10用A来表示,11-B、12-C、13-D、14-E、15-F)
81 0
【C】操作符——知识点大全(简洁,全面)(二)
【C】操作符——知识点大全(简洁,全面)
|
10月前
|
存储
【C】操作符——知识点大全(简洁,全面)(一)
【C】操作符——知识点大全(简洁,全面)