【C 语言】简单通俗掌握位运算符

文中整数都以Int8为例,Int8大小为1字节,区间值为-128至127

8比特位 = 1符号位 + 7数值位

即二进制表示为:


-128

至

127

多说几句
符号位0正数1负数

127 = 26 + 25 + 24 + 23 + 22 + 21 + 20
-128 = - (27 - |0|)

二进制转十进制
正数的二进制转十进制不用多说了。
负数的二进制转十进制时符号位是 1 表示负数,2n 减去数值位十进制值的绝对值(n为位数)。

再举个栗子:
- (27 - |26 + 25 + 24 + 22 + 20|) = -10

-10

十进制转二进制
正数的十进制转二进制不用多说了。
负数的十进制转二进制是正数的补码。

原码 反码 补码


位与运算符(&)

两个数进行位与运算,每一个比特位依次计算,只有数值位对应的两个二进制值都是 1 的时候才是 1

&


位或运算符(|)

&同理,|是只要数值位对应的两个二进制值任意一个是 1 的时候就是 1

|


位异或运算符(^)

&同理,^是只有数值位对应的两个二进制值不相等时是 1

^


位取反运算符(~)

一个数进行位取反运算,每一个比特位依次取反,即10

~

可以知道~就是原码转反码的过程。


位左移运算符(<<)

位左移运算简单来说是一个数所有数值位的二进制值向左移动确定位数。

  1. 无符号整数 例如:10<<5

    10<<5

  2. 有符号整数 例如:-10<<5

    -10<<5.png

  • 所有比特位按指定的位数进行左移。
  • 空白位用0补充。
  • 超出整形存储边界都舍弃,例如上图中Int8类型的10位左运算置灰部分应舍弃,值为64。若是Int64类型的10位左运算置灰部分不应舍弃,值为320
  • 可以看出一个数位左移 1后在整型存储范围内(没有舍弃部分)相当于将这个数x2
例如:
var i: Int = 20
print(I<<2)  
运行结果:80
 
即:20*2*2 = 80

位右移运算符(>>)

同理,位左移运算简单来说是一个数所有数值位的二进制值向右移动确定位数。

  1. 无符号整数 例如:10>>5

    10>>5.png

  2. 有符号整数 例如:-10>>5

    -10>>5

  • 所有比特位按指定的位数进行右移。
  • 无符号整数空白位用0补充,有符号整数空白位用符号位数值补充。
  • 超出整形存储边界都舍弃。
  • 可以看出一个数位左移 1后在整型存储范围内(没有舍弃部分)相当于将这个数/2,若位左移导致结果<1无符号整数结果为0有符号整数中的负数结果为-1
例如:
var i: Int =20
print(i<<2)
运行结果:5

即:20/2/2 = 5

几个常见的位运算符操作总结

  • 两个数 ^ 得到的结果,再 ^ 其中任意一个数,能得到另一个数。
  • 两个相等的数 ^ 得到的结果为 0。
  • 0 和任何一个数 ^ 得到的都是这个数本身。

应用: 交换两个变量的值

var a = 1
var b = 2
a = a ^ b
b = a ^ b
a = a ^ b
print("a = \(a), b = \(b)")

  • i & 1 可以判断 i 最后一位是不是 1。

应用:求无符号整数二进制中 1 的个数

func countOfOnes(num: UInt) -> UInt {
    var count: UInt = 0
    var temp = num
    while temp != 0 {
        count += temp & 1
        temp = temp >> 1
    }
    return count
}
var a: UInt = 3
print(countOfOne(num: a))

  • i & (i - 1) 消除 i 最后一位的 1。

应用:判断无符号整数是否为 2 的整数次幂

func isPowerOfTwo(num: UInt) -> Bool {
    return (num & (num - 1)) == 0
}
print(isPowerOfTwo(num: 2))

  • i & j == 0 可以知道 i 的 第 j 位不是 1。

应用:分组

func divideTwoGroups(nums: [UInt], flag: UInt)  {
    var lostNum1Array: Array<Int> = []
    var lostNum2Array: Array<Int> = []

    for num in nums {
        if (num & flag) == 0 {
            lostNum1Array.append(Int(num))
        } else {
            lostNum2Array.append(Int(num))
        }
    }
    print(lostNum1Array)
    print(lostNum2Array)
}
divideTwoGroups(nums: [1,2,3,3,5,8,9,9], flag: 2)

  • (i >> j) & 1 == 1 可以知道 i 右移 j 位后等于 1。

应用:给定一个集合,返回这个集合所有的子集

func getSubsets<T>(_ set: Set<T>) -> Array<Set<T>> {
    // 1 << set.count 相当于 2^set.count 
    let count = 1 << set.count
    let elements = Array(set)
    var subsets = [Set<T>]()
    for i in 0..<count {
        var subset = Set<T>()
        for j in 0..<elements.count {
            // i = 5, j = 0时  101 >> 0  =>  101 & 001  =>  001 满足
            // i = 5, j = 1时  101 >> 1  =>  010 & 001  =>  000 不满足
            // i = 5, j = 2 时 101 >> 0  =>  001 & 001  =>  001 满足
            if ((i >> j) & 1) == 1 {
                subset.insert(elements[j])
            }
           // subset : ["A", "B"]
        }
        subsets.append(subset)
    }
    return subsets
}
print(getSubsets(["A", "B", "C"]))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351