欢迎来到计算机世界的奇妙旅程!今天,我们将探讨一个基本但强大的概念:位运算中的取反运算。这个概念在计算机科学和电子工程中扮演着重要角色,尤其是在进行低级编程和硬件设计时。

一、取反运算(~)

什么是取反运算?

取反运算,用符号 ~ 表示,是一个单目运算符,作用于整数的二进制表示,也就是只有一个操作数,表示为 ~x 。

在这个操作中,所有的二进制位都会被反转:1变为0,0变为1。

取反运算符右结合性,作用是对参与运算的二进制位取反。~1为0,~0为1

为什么要用取反运算?

取反运算在多种场合中都非常有用,如反转标志位、生成数值的补数,以及在某些特定算法中实现快速计算。

如何计算取反? --- 对9取反的两种方法总结

我们考虑在32位整数环境中对数字9进行取反操作。

9的二进制表示为:

        0000 0000 0000 0000 0000 0000 0000 1001(9 在内存中的存储)

-10的补码:(稍后会详细介绍)

        1111 1111 1111 1111 1111 1111 1111 0110(这就是-10的补码)

方法1:直接取反

简单直接,对9的每个二进制位取反,

结果为 1111 1111 1111 1111 1111 1111 1111 0110,这表示-10。

方法2:补码表示取反

由于9是正数,它的补码与原码相同。对这个补码取反,

结果为 1111 1111 1111 1111 1111 1111 1111 0110,同样表示-10。

在这两种方法中,结果是一样的。无论是直接对原码取反还是对补码取反,最终都得到了-10。

-10的补码表示

对于负数,在计算机中用补码来表示。补码是原码的二进制反码(即每一位取反)加1。

下面我们以-10为例,来展示这两种从补码转换回原码的步骤:

        首先,我们需要知道-10在计算机中的补码表示。对于32位整数,-10的补码是:

10的原码(正数)        0000 0000 0000 0000 0000 0000 0000 1010

取反:                ​​​​​​           1111 1111 1111 1111 1111 1111 1111 0101

加1:                             1111 1111 1111 1111 1111 1111 1111 0110(这就是-10的补码)


方法1: 先取反再加1
  1. 取反:对补码1111 1111 1111 1111 1111 1111 1111 0110每一位取反(除了符号位),得到 1000 0000 0000 0000 0000 0000 0000 1001
  2. 加1:将上述结果加1,得到 1000 0000 0000 0000 0000 0000 0000 1010,这是-10的原码。
方法2: 先减1再取反
  1. 减1:从补码1111 1111 1111 1111 1111 1111 1111 0110 减1,得到 1111 1111 1111 1111 1111 1111 1111 0101
  2. 取反:对上一步的结果取反(除了符号位),得到 1000 0000 0000 0000 0000 0000 0000 1010,这同样是-10的原码。

在这两种方法中,我们最终都得到了相同的原码表示 1000 0000 0000 0000 0000 0000 0000 1010,它代表了-10。这两种方法都是有效的,用于将负数的补码转换回其原码表示。

总结:

  • 所有正整数 x 的按位取反结果是 −(x+1)。
  • 所有负整数 y 的按位取反结果是 ∣y∣−1。
  • 0的按位取反是 -1(0在数学界既不是正数也不是负数) 

所有正整数的按位取反:对于任何正整数 x,其按位取反的结果是 −(x+1)。这是因为正整数的补码就是其本身,取反后,你得到了它的补码的负数形式,即该数+1的负数。

所有负整数的按位取反:对于任何负整数 y,其按位取反的结果是 ∣y∣−1。这里的关键是理解负整数在计算机中是以补码形式存储的。补码是原码取反加1。因此,当你对一个负数的补码进行取反操作时,你实际上得到了它的绝对值减1。

以~11为例:

        ~11的计算步骤:

                计算11的补码

                转二进制:0 1011

                计算补码:0 1011

                按位取反:1 0100 (按位取反是在这进行的,即补码的形式进行按位取反) 注意:这里是 补码

                将转为原码:

                取其反码(因为补码是负数):1 1011

                末位加一:1 1100

                符号位为1是负数,即-12

以~(-11)为例:

        ~(-11)的计算步骤:

                计算-11的补码

                转二进制:1 1011

                计算补码:1 0101

                按位取反:0 1010 (按位取反是在这进行的,即补码的形式进行按位取反) 注意:这里是补码

                将转为原码:

                正数补码就是原码:0 1010

                符号位为0是正数,即10

二、按位取反运算符的应用

(1)0的取反

(有符号整型int:~0 为 -1;无符号整型 unsigned int :~0 为 4294967295)

(2)相反数

(直接利用不嘛定义,对于正数x,他的 相反数的补码就是x二进制取反加1. ~x+1)

(3)代替减法

(由(2)延伸 :x - y = x + (-y) = x + ~y + 1)

(4)代替加法

(由(2)延伸 : x - ~y + 1)

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐