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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言的补码表示和unsigned及signed的转换

發(fā)布時間:2025/7/14 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言的补码表示和unsigned及signed的转换 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這東西實際編程時一直無視的,范圍小了就換個大點的表示形式,但是總覺得基礎知識還是掌握得好,免得到時候用移位運算或類型轉換或筆試題時要花時間想。

C語言的基本類型有char、int、float、double,另外還有說明符long、short、signed和unsigned。

首先要注意在不同操作系統(tǒng)中類型大小不一樣,下面的情況只是考慮其中一種情況。

int和char均默認為signed,二進制的最高一位來表示符號,0為正1為負。

假如short int是16位,由于第1位表示正負,所以只剩15位表示實際數(shù)值,范圍為-2^15到2^15-1

舉例,按照原碼表示:

0000 0000 0000 0101表示5

1000 0000 0000 0101表示-5

反碼就是符號位不變,數(shù)值位取反,比如5就表示為0111 1111 1111 1010

但是這樣問題來了,1000 0000 0000 0000跟0000 0000 0000 0000表示的都是0,這樣0就有2種編碼方式。

所以C語言采取了補碼表示,1000 0000 0000 0000表示的是-2^15而非0。

補碼:1、對于正數(shù),補碼與原碼相同;2、對于負數(shù),數(shù)值位的絕對值取反后在最低位加1。

PS:負數(shù)轉整數(shù)也是取反后最低位加1(不是減1

因此,C語言中是用表示-5的是1111 1111 1111 1011

那么對負整數(shù)逐次進行自加運算得到結果如下

-4  1111 1111 1111 1100

-3  1111 1111 1111 1101

-2  1111 1111 1111 1110

-1  1111 1111 1111 1111

于是-1再自加后所有位數(shù)全部變?yōu)?,0的表示形式就變成了0000 0000 0000 0000,表示0的只有一種形式。

C語言支持移位運算,即將數(shù)據(jù)看成二進制數(shù),對其向左或向右移動若干位。

邏輯移位:移出去的位丟棄,空位補0

算術移位:移出去的位丟棄,空位補符號位(只有當有符號數(shù)做右移運算時才是算術移位)

0000 0101向左移2位(即5<<2)后變成 0001 01??,?處補0,所以結果是0001 0100,為20.

1111 1011向左移2位(即-5<<2)后變成1110 11??,?處補0,所以結果是1110 1100,按照補碼規(guī)則,為正數(shù)0001 0011的相反數(shù)加1,即-(19+1)=-20

所以左移很簡單,可以i << j可以替代乘法運算i*2j,運算效率更高。

要注意的是,雖然一般不會用到,但是左移位數(shù)超過該數(shù)值類型最大位數(shù)時,編譯器會用位數(shù)求余,所以這就跟具體類型大小有關。

0010 1001向右移2位(即41>>2)后變成??00 1010,正數(shù)?處補0,所以結果是0000 1010,為10。

1101 0111向右移2位(即-41>>2)后變成了??11 0101,負數(shù)?處補1,所以結果是1111 0101,為正數(shù)0000 1010的相反數(shù)加1,即-(10+1)=-11

可以看出絕對值相同的正數(shù)和負數(shù)右移同樣位數(shù)后得出的結果并不一致,i>>j并不能等價于i/2j!-41/4的結果是-10!

?

最后談談unsigned轉signed,以char為例。

char在計算機內部是用一個字節(jié)的二進制來表示的,這里假定默認為signed,表示范圍為-128到127。

對于char c = 128; c的二進制表示為1000 0000,如果轉換成int輸出是-127。

char轉換成short int并不是說位數(shù)增加了,而是把它當成short int來解釋,因此c還是1000 0000,表示的是-127,而不會因為轉型為int就變成了0000 0000 1000 0000

看下面一段代碼,signed轉unsigned

int _tmain(int argc, _TCHAR* argv[]) {char c = 128;unsigned char cu = c;short int i = cu;cout << i;return 0; }

把c轉換成unsigned char后,再轉換成short int,那么輸出的就是128,轉型后還是1000 0000,但是按照unsigned的解釋,最高位不再是符號位,而是數(shù)值位,所以結果就是2^8=128。

好了,再看下面一段代碼,unsigned轉signed

int _tmain(int argc, _TCHAR* argv[]) {unsigned char cu = 255;char c = cu;short int i = c;cout << i;return 0; }

255的unsigned表示為 1111 1111,轉換為signed后,符號位1代表是負數(shù),數(shù)值位轉換成十進制后是127,按照補碼的定義結果為-1。

以前用OpenCV處理圖像時,經(jīng)常被繞住,因為IplImage*的ImageData是char表示的,而處理圖像時一般都轉化成了unsigned char,回顧了補碼的概念后那么下面這個對應就好理解了。

數(shù)值區(qū)間[0,127][-128,-1]
charxx
unsigned charx256+x

轉載于:https://www.cnblogs.com/Harley-Quinn/p/5346626.html

總結

以上是生活随笔為你收集整理的C语言的补码表示和unsigned及signed的转换的全部內容,希望文章能夠幫你解決所遇到的問題。

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