日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

位运算(按位与、按位或、异或、取反)以及原码、反码、补码

發(fā)布時間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 位运算(按位与、按位或、异或、取反)以及原码、反码、补码 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

參考:運算符的計算(按位與 按位或 異或 取反)
作者:一只青木呀
發(fā)布時間: 2020-07-23 18:13:55
網(wǎng)址:https://blog.csdn.net/weixin_45309916/article/details/107543919

參考:計算機原碼,反碼,補碼
作者:chenchao2017
發(fā)布時間: 2018-04-03 10:22:38
網(wǎng)址:https://blog.csdn.net/chenchao2017/article/details/79733278?utm_medium=distribute.pc_relevant_t0.none-task-blog-searchFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-searchFromBaidu-1.control

目錄

  • 位運算
    • 按位與運算符 [ & ]
    • 按位或運算符 [ | ]
    • 異或運算符 [ ^ ]
    • 取反運算符 [ ~ ]
    • 移位操作
    • 一些面試常考的位操作運算
  • 計算機原碼、反碼、補碼
    • 機器數(shù)
    • 真數(shù)
    • 原碼
    • 反碼
    • 補碼
    • 有了原碼為什么要使用反碼和補碼

位運算

按位與運算符 [ & ]

運算規(guī)則:依次比較兩個二進(jìn)制數(shù)的每一位,全部為1則為1,否則為0的規(guī)則,依次計算出一個新的二進(jìn)制數(shù):

即:0 & 0= 0 ,0 & 1= 0,1 & 0= 0, 1 & 1= 1
例: 39 & 21 --> 0010 0111 & 0001 0101 --> 0000 0101

按位或運算符 [ | ]

運算規(guī)則:依次比較兩個二進(jìn)制數(shù)的每一位,只要有一個為1則為1,否則為0的規(guī)則,依次計算出一個新的二進(jìn)制數(shù):

即:0 | 0= 0 ,0 | 1= 1,1 | 0= 1, 1 | 1= 1
例: 39 | 21 --> 0010 0111 | 0001 0101 --> 0011 0111

異或運算符 [ ^ ]

運算規(guī)則:依次比較兩個二進(jìn)制數(shù)的每一位,按照相同為0,不同為1的規(guī)則,依次計算出一個新的二進(jìn)制數(shù):

即:0 ^ 0= 0 ,0 ^ 1= 1,1 ^ 0= 1, 1 ^ 1= 1
例: 39 ^ 21 --> 0010 0111 ^ 0001 0101 --> 0011 0010

取反運算符 [ ~ ]

運算規(guī)則:對于二進(jìn)制數(shù)的每一位,1變0,0變1,得到一個新的二進(jìn)制數(shù):

即:~0 = 1 , ~1= 0
因為涉及到、補碼、原碼、符號,感覺挺復(fù)雜的,涉及的知識比較多,總結(jié)為一句:

對所有整數(shù)取反=本身的相反數(shù)減一
~9 = -10
~10 = -11

移位操作

<<: 左移、>> : 右移
箭頭指向哪就是向哪移。左移之后右邊補0,右移之后在左邊補0

結(jié)論: 對于正數(shù)而言,其實左移和右移n位就相當(dāng)于乘以或者除以2的n次方。

比如:十進(jìn)制的5,該數(shù)二進(jìn)制為 0000 0101,將該數(shù)左移3為
結(jié)果為0010 1000,轉(zhuǎn)換成十進(jìn)制為 40, 驗證了上面的結(jié)論:5左移三位就等于5乘以2的三次方等于40。
再比如:十進(jìn)制的40,右移三位就相當(dāng)于除以8(2的三次方)結(jié)果為5。
那么問題來了,有一個數(shù)a,有一個數(shù)b,我要讓b等于a的第三位,怎么算。

思路:先讓a右移倆位,那么a原來的第三位現(xiàn)在就變成最后一位,再讓移后的數(shù)和1想與,結(jié)果即為a原來的第三位。

一些面試??嫉奈徊僮鬟\算

去掉最后一位 | (101101->10110) | x >> 1 在最后加一個0 | (101101->1011010) | x << 1 在最后加一個1 | (101101->1011011) | x << 1+1 把最后一位變成1 | (101100->101101) | x | 1 把最后一位變成0 | (101101->101100) | x | 1-1 最后一位取反 | (101101->101100) | x ^ 1 把右數(shù)第k位變成1 | (101001->101101,k=3) | x | (1 << (k-1)) 把右數(shù)第k位變成0 | (101101->101001,k=3) | x & ~ (1 << (k-1)) 右數(shù)第k位取反 | (101001->101101,k=3) | x ^ (1 << (k-1)) 取末三位 | (1101101->101) | x & 7 取末k位 | (1101101->1101,k=5) | x & ((1 << k)-1) 取右數(shù)第k位 | (1101101->1,k=4) | x >> (k-1) & 1 把末k位變成1 | (101001->101111,k=4) | x | (1 << k-1) 末k位取反 | (101001->100110,k=4) | x ^ (1 << k-1) 把右邊連續(xù)的1變成0 | (100101111->100100000) | x & (x+1) 把右起第一個0變成1 | (100101111->100111111) | x | (x+1) 把右邊連續(xù)的0變成1 | (11011000->11011111) | x | (x-1) 取右邊連續(xù)的1 | (100101111->1111) | (x ^ (x+1)) >> 1 去掉右起第一個1的左邊 | (100101000->1000) | x & (x ^ (x-1)) 判斷奇數(shù) (x&1)==1 判斷偶數(shù) (x&1)==0 取右邊第一個1所在位置 x&-x

計算機原碼、反碼、補碼

機器數(shù)

一個數(shù)在計算機中的表現(xiàn)形式叫做機器數(shù),這個數(shù)有正負(fù)之分,在計算機中用一個數(shù)的最高位(符號位)用來表示它的正負(fù),其中0表示正數(shù),1表示負(fù)數(shù)。

例如正數(shù)7,在計算機中用一個8位的二進(jìn)制數(shù)來表示,是00000111,而負(fù)數(shù)-7,則用10000111表示,這里的00000111和10000111是機器數(shù)

真數(shù)

計算機中的機器數(shù)對應(yīng)的真實的值就是真數(shù),對最高位(符號位)后面的二進(jìn)制數(shù)轉(zhuǎn)換成10進(jìn)制,并根據(jù)最高位來確定這個數(shù)的正負(fù)。對于上面的00000111和10000111來說,對最高位后面的二進(jìn)制數(shù)轉(zhuǎn)換成10進(jìn)制是7,在結(jié)合最高位的值,得出對應(yīng)的真數(shù)分別是7和-7

原碼

用第一位表示符號,其余位表示值。因為第一位是符號位,所以8位二進(jìn)制數(shù)的取值范圍就是:[1111_1111 , 0111_1111] 即 [-127 , 127] ,原碼是容易被人腦所理解的表達(dá)方式

反碼

正數(shù)的補碼反碼是其本身,負(fù)數(shù)的反碼是符號位保持不變,其余位取反。例如正數(shù)1的原碼是[0000_0001],它的反碼是是其本身

[0000_0001],-1的原碼是[1000_0001],其反碼是[1111_1110]

補碼

正數(shù)的補碼是其本身,負(fù)數(shù)的補碼是在其反碼的基礎(chǔ)上+1,例如正數(shù)1的原碼是[0000_0001],他的補碼是其本身[0000_0001],

-1的補碼是[1111_1111]

有了原碼為什么要使用反碼和補碼

因為人腦可以知道第一位是符號位,可以根據(jù)符號位對真值的絕對值進(jìn)行加減乘除,但是對于計算機來說,加減乘除是最最最基本的運算,要設(shè)計的盡量簡單,計算機辨別符號位會讓計算機的設(shè)計電路變得很復(fù)雜,于是人們想出了讓符號位也參與到運算上來。減去一個數(shù),等于加上他的負(fù)數(shù)。

使用原碼參數(shù)運算的缺陷

從上面的原碼表中可以看見左邊每增加一個二進(jìn)制單位對應(yīng)的真數(shù)是遞減的,而右邊每增加一個二進(jìn)制單位對應(yīng)的真數(shù)是遞增的,所以對于原碼來說,能滿足正數(shù)的加法,但無法滿足負(fù)數(shù)的加法

2+1 = [0000_0010]原+[0000_0001]原=[0000_0011]原 = 3

1±1=[0000_00001]原+[1000_0001]原=[1000_0010]原=-2

為了滿足負(fù)數(shù)對加法的需求,就必須讓負(fù)數(shù)與他對應(yīng)的二進(jìn)制碼是同步遞增或者同步遞減

于是就通過符號位不變,其余位取反來滿足這個同步遞增或者遞減的要求,由于正數(shù)本來就滿足它本身的加法,所以不需要做任何改變。這就是反碼的定義由來。

從上圖的反碼表中可以看到在運算不跨過0的時候,正負(fù)數(shù)的加法已經(jīng)能滿足要求

-2+1=[1111_1101]反+[0000_0001]反=[1111_1110]反=-1

127+1=[1000_0000]反=-127=128 加法算出來是128,由于128超過最大值,余1,所以取最小值開始的第一位,也就是

最小值-127,但是這里有個不合理的地方,就是[1111_1111]和[0000_0000]都表示0,這導(dǎo)致在實際計算中每當(dāng)跨過0一次,就有一個單位的誤差

-1+2=[1111_1110]反+[0000_0010]反=[0000_0000]反=0

要解決這個問題就必須讓反碼中的[1111_1111]和[0000_0000]合并,

由于[1111_1111]+[0000_0001]=[0000_0000],所以在負(fù)數(shù)反碼的基礎(chǔ)上+1就可以解決反碼中跨0的誤差問題,同時不會對負(fù)數(shù)與它對應(yīng)的二進(jìn)制反碼的同步遞增產(chǎn)生影響,所以在反碼的基礎(chǔ)上+1就完美的解決了符號參與預(yù)算的問題,這就是補碼為什么是在負(fù)數(shù)反碼的基礎(chǔ)上+1的由來。

從上面的圖中發(fā)現(xiàn)還有一個[1000_0000]的二進(jìn)制沒有對應(yīng)任何真數(shù),于是就規(guī)定了這個數(shù)的真數(shù)是-128

所以補碼的表示范圍是[-128~127] ,這樣一來256個二進(jìn)制正好表示256個整數(shù),在實際二進(jìn)制的運算中超過范圍其實就是對256的取余預(yù)算(x+128)mod 256 - 128。

總結(jié)

以上是生活随笔為你收集整理的位运算(按位与、按位或、异或、取反)以及原码、反码、补码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。