位运算

原码,反码,补码

原码

  1. 正数的原码就是其二进制本身
  2. 负数的原码是把对应的正数的原码最高位改为1

反码

  1. 正数的反码就是其二进制原码本身
  2. 负数的反码是在其原码的基础上,符号位不变,其余各位取反

补码

  1. 正数的补码就是其二进制原码本身
  2. 负数的补码是在其反码的基础上加1,** -1的补码是11111111, 所以当一个数减1的时候,可以直接对其二进制数加1111111**

位运算小技巧

NOTE: 位运算只能运用在整数上

判断奇偶

只要根据末位是0还是1来决定,末位为0就是偶数,末位为1就是奇数,因此可以这样写

bool is_odd(int n) { 
    if ( n & 1 == 0) {
        return true; 
    }
    return false;
}

交换两数

//位操作的交换两数
void swap(int &a, int &b) { 
    a = a ^ b; 
    b = b ^ a; 
    a = a ^ b;
}
  • b = b ^ a这一句根据上一句可以替换为b = b ^ (a ^ b),由于^(异或操作)满足交换律, b = b ^ a ^ b等价于b = b ^ b ^ a,对于异或操作来说,一个整数和自己异或永远等于0,  而一个数与0进行异或数值仍然不变, 所以此时等价于b = a
  • 第三句a = a ^ b,由于第二句等价于b = a且第一句a = a ^ b所以第三句可以等价于a = a ^ b ^ a,又可以等价于a = b,即a被赋予b的值

正负变换

11的二进制为000 01011 , 进行取反 --> 1111 0100, 加1 --> 1111 0101(-11)同理,-11的二进制为1111 0101,取反 --> 0000 1010,加1 --> 0000 1011(11)

int reverse_signal(int n) { 
    return ~n + 1;
}

求绝对值

  1. 先移位来取符号位, int i = n >> 31, 如果n为整数则i=0,n为负数则i=-1> 因为int型整数一般是4个字节,共32位,最高位为符号位,所以右移31位可以得到符号位> NOTE:符号位为1即负数的二进制,每右移一位,高位补的是1
  2. 对于任何数,与0异或保持不变,与-1即0xFFFFFFFF异或相当于取反,因此,n与i异或后再减i(因为i不是为0就是-1,而减去-1即加1)也可以得到绝对值> 二进制转十六进制:-1的二进制为32个1, 转成十六进制的话,每四位先计算出对应的十进制
//第一种方法
int abs(int n) {
    int i = n >> 31; 
    return i == -1 ? (~n + 1) : n;
}
//第二种方法
int abs(int n) {
    int i = n >> 31; 
    return (a ^ i) - i;
}

高低位交换

假设一个16位无符号整数的二进制为:1000011011011000,经过高低位变换后则为11011000 10000110.无符号左移低位补0,右移高位补0,因此将1000011011011000 这个数先右移8位为0000000010000110得到高位,再将10000011011011000左移8位为11011000 00000000即得到低位,再将两个数相或就可以得到高低位变换后的数字

int low_high_transit(int n) { 
    return (n >> 8) | (n << 8)
}

二进制逆序

//16位二进制
int reverse_binary(int &n) { 
  n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); 
  n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2);
  n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); 
  n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); 
  return n;
}

计算32位二进制有几个位是1

//32位二进制,如果要计算16位则0x55555555变为0x5555,依次类推,且没有最后一步
int count_bit(int &n) { 
    n = (n & 0x55555555) + ((n & 0xAAAAAAAA) >> 1); 
    n = (n & 0x33333333) + ((n & 0xCCCCCCCC) >> 2); 
    n = (n & 0x0F0F0F0F) + ((n & 0xF0F0F0F0) >> 4); 
    n = (n & 0x00FF00FF) + ((n & 0xFF00FF00) >> 8); 
    n = (n & 0x0000FFFF) + ((n & 0FFFF0000)) >> 16);
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 进制二进制以0b或0B开头,如0b001。(数字0不是字母O)八进制以0开头,如067。十六进制以0x或0X开头,...
    ForeverYoung21阅读 1,000评论 0 5
  • 局部变量,就是在函数内部定义的变量 不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响 局部变量的...
    遐迩_84a7阅读 652评论 0 0
  • 数据在计算机中都是以补码形式存放的,位运算也是以一个数的补码进行运算,结果也自然也是一个补码,这点在分析计算过程时...
    SharpChen阅读 691评论 0 4
  • C语言里位运算就是对一个比特(Bit)进行操作,比特(Bit)是计算机的一个电子元件,只有通电和断电两种状态(这也...
    Mark_Ming阅读 2,497评论 0 8
  • 这段时间以来,我惯是冷着他的,他不找我我就不找他,他找我也简明扼要的回复他,虽说是打算好的这样做,但到底还是心有不...
    依然丶恣意阅读 198评论 0 0