成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

移位的位數是負數,結果會怎樣?

開發 前端
有過編程經驗的同學,對于移位操作應該很熟悉了,日常工作中或多或少都有用到,當 移位位數是負數 或者 移位位數超過了 類型的最大二進制位時,和正常移位處理是不一樣的,下面將詳細說明這兩種情況,在此之前,先了解下正常的移位操作。

[[432672]]

有過編程經驗的同學,對于移位操作應該很熟悉了,日常工作中或多或少都有用到,當 移位位數是負數 或者 移位位數超過了 類型的最大二進制位時,和正常移位處理是不一樣的,下面將詳細說明這兩種情況,在此之前,先了解下正常的移位操作

正數的左移和右移

正數的左移是二進制位向左移動,右邊留空的位置補 0,右移是二進制位向右移動,左邊留空的位置補 0 ( 符號位為 0 )

  • 左移

左移操作,最高位的符號位會出現 0 或 1 , 因此結果會出現正數和負數的情況

新建測試文件 base.cpp,代碼如下

  1. #include <stdint.h> 
  2. #include <iostream> 
  3. using namespace std; 
  4. int32_t main(int32_t argc , char *argv[]) 
  5.     int32_t a = 7; 
  6.     cout << "(a << 2) = " << (a << 2) << endl; 
  7.     cout << "(a << 30) = " << (a << 30) << endl; 
  8.  
  9.  
  10.     return 0; 

執行 g++ -g -Wall -std=c++11 -o base base.cpp 命令編譯代碼,再執行 ./base 運行程序,結果如下

  1. (a << 2) = 28 
  2. (a << 30) = -1073741824 

上述代碼中,變量 a 的值為 7,對應的二進制是 0000 0000 0000 0000 0000 0000 0000 0111

左移 2 位:二進制向左移動 2 位,右邊補充 2 位 0 ,左邊丟棄超出的 2 位二進制, 結果是 0000 0000 0000 0000 0000 0000 0001 1100, 對應的十進制數是 28

左移 30 位 的流程如下圖

由上圖可知,二進制向左移動 30 位后, 左邊 30 位二進制 0000 0000 0000 0000 0000 0000 0000 01 因超出被丟棄,同時最右邊剩下的 2 位二進制 11 左移 30 位,右邊空的位置補充 30 位 0,最終的結果是 1100 0000 0000 0000 0000 0000 0000 0000, 對應的十進制數是 -1073741824

可以看出,正數 7 左移 30 位后,二進制的符號位變成了 1 ,也即正數變成了負數了

  • 右移

正數右移,最小為 0 , 不會出現負數,下面是右移的測試代碼

修改 base.cpp 文件,代碼如下

  1. #include <stdint.h> 
  2. #include <iostream> 
  3. using namespace std; 
  4. int32_t main(int32_t argc , char *argv[]) 
  5.    int32_t a = 7; 
  6.    cout << "(a >> 1) = " << (a >> 1) << endl; 
  7.    cout << "(a >> 31) = " << (a >> 31) << endl; 
  8.  
  9.     return 0; 

編譯并運行上面程序,結果如下:

  1. (a >> 1) = 3 
  2. (a >> 31) = 0 

上述實例代碼中,變量 a 的值為 7,對應的二進制是 0000 0000 0000 0000 0000 0000 0000 0111

右移 1 位:二進制向右移動 1 位,左邊補充一位 0 ,右邊丟棄超出的一位二進制, 結果是 0000 0000 0000 0000 0000 0000 0000 0011, 對應的十進制數是 3

右移 31 位:二進制向右移動 31 位,左邊補充 31 位 0 ,右邊丟棄超出的 31 位二進制,結果是 0000 0000 0000 0000 0000 0000 0000 0000, 對應的十進制是 0

負數的左移和右移

負數的左移是二進制位向左移動,右邊留空的位置補 0,右移是二進制位向右移動,左邊留空的位置補 1 ( 符號位為 1 ),這一點跟正數是不一樣的

計算機中是用補碼的形式進行各種運算的,正數的補碼是其自身,負數的補碼是將其正數按位取反加 1

  • 左移

負數左移,符號位可能會變成0,因此結果會出現正數和負數的情況,一直左移的話,最終會變成 0

修改 base.cpp文件,代碼如下

  1. #include <stdint.h> 
  2. #include <iostream> 
  3. using namespace std; 
  4. int32_t main(int32_t argc , char *argv[]) 
  5.    int32_t b = -3; 
  6.    cout << "(b << 1) = " << (b << 1) << endl; 
  7.    cout << "(b << 30) = " << (b << 30) << endl; 
  8.  
  9.     return 0; 

編譯并運行上面程序,結果如下:

  1. (b << 1) = -6 
  2. (b << 30) = 1073741824 

上面代碼中,變量 b 的值為 -3,對應的二進制是 1111 1111 1111 1111 1111 1111 1111 1101

左移 1 位:整個二進制串向左移動 1 位,右邊補充 0 ,左邊丟棄超出的一位二進制,結果是 1111 1111 1111 1111 1111 1111 1111 1010,對應十進制數 -6

左移 30 位 的流程如下

由上圖可知,左移 30 位,左邊的 30 位二進制 1111 1111 1111 1111 1111 1111 1111 11 因超出數值最大位數而被丟棄,原來最右邊的 01 移到了最左邊,緊接著后面的 30 個空位全部補 0 ,最終的結果是 0100 0000 0000 0000 0000 0000 0000 0000 ,對應十進制是 1073741824

可以看出,負數 -3 左移 30 位后,二進制的符號位變成了 0 ,由開始的負數變成了正數了

  • 右移

負數右移是在左邊補 1, 所以結果不會出現正數的情況,如果一直右移,最終二進制位會全部變成 1,即十進制的 -1 ( 二進制全 1 在補碼中表示 -1 )

修改 base.cpp,代碼如下

  1. #include <stdint.h> 
  2. #include <iostream> 
  3. using namespace std; 
  4. int32_t main(int32_t argc , char *argv[]) 
  5.    int32_t b = -3; 
  6.    cout << "(b >> 1) = " << (b >> 1) << endl; 
  7.    cout << "(b >> 31) = " << (b >> 31) << endl; 
  8.  
  9.     return 0; 

編譯并運行上面程序,結果如下:

  1. (b >> 1) = -2 
  2. (b >> 31) = -1 

上面代碼中,變量 b 的值為 -3,對應的二進制是 1111 1111 1111 1111 1111 1111 1111 1101

右移 1 位:二進制位向右移動 1 位,左邊補充 1 ,右邊丟棄一位超出的二進制,結果為 1111 1111 1111 1111 1111 1111 1111 1110,對應的十進制是 -2

右移 31 位 的流程如下

根據上圖可知,右移 31 位,最右邊的 31 位二進制 1111 1111 1111 1111 1111 1111 1111 110 因超出數值最大位數而被丟棄, 原來左邊的 1 移到了最右邊,左邊補 31 位 1,最后結果為:1111 1111 1111 1111 1111 1111 1111 1111 , 對應的十進制數 -1

移位數超過類型最大位數

移位的位數大于等于數值類型的最大位數時,實際的移的位數是:移位的位數和該類型的最大位數做取模運算,余數就是要移的位數,不管左移還是右移,這種方法都適用

比如:類型為 int32_t,移位的位數是 34,實際移位的位數為:34 % 32 = 1

修改 base.cpp 文件,內容如下:

  1. #include <stdint.h> 
  2. #include <iostream> 
  3. using namespace std; 
  4. int32_t main(int32_t argc , char *argv[]) 
  5.     int32_t a = 7; 
  6.     cout << "(a >> 32) = " << (a >> 32) << endl; 
  7.     cout << "(a >> 33) = " << (a >> 33) << endl; 
  8.     cout << "(a << 34) = " << (a << 34) << endl; 
  9.     return 0; 

編譯并執行,結果如下

  1. (a >> 32) = 7 
  2. (a >> 33) = 3 
  3. (a << 34) = 28 

變量 a 的值為 7,對應的二進制是 0000 0000 0000 0000 0000 0000 0000 0111

右移 32 位:因移位位數等于 int32_t 最大位數,所以實際移位數為 32 % 32 = 0,右移 0 位 表示沒有移位,所以結果還是 7

右移 33 位:移位位數大于 int32_t 最大位數,故實際移位數為 33 % 32 = 1,右移 1 位,左邊補 0 ,右邊丟棄超出的位,結果是: 0000 0000 0000 0000 0000 0000 0000 0011,對應的十進制是 3

左移 34 位:移位位數大于 32 ,實際移位數為 34 % 32 = 2,左移 2 位,右邊補 0 ,左邊丟棄超出的位,結果是:0000 0000 0000 0000 0000 0000 0001 1100,對應的十進制是 28

正常情況下,在移位數相同時,分幾次移位操作和單次移位操作的結果是一樣的, 比如:一個 int32_t 變量,值為 7, 7 << 1 << 2 和 7 << 3 的結果相同的

當移位數大于等于數值類型最大位數時,上述的結果是不一樣的,比如:一個 int32_t 變量,值為 7, 雖然 7 << 33 和 7 << 20 << 13 兩者移位數都是 33,但結果卻是不同的,前者是 14,而后者是 0

移位的位數是負值

當移位的位數是負值時,實際移位的位數是:用被移位數值類型的最大位數和移位位數相加,如果結果還是負數,結果繼續 加上被移位數值類型的最大位數,直到結果不為負數為止,此時的結果即為最終移位的位數

比如:被移位的數據類型是 int32_t,移位位數是 -31,最終移位的位數是:32 + ( -31 ) = 1

當移位位數是 -60,計算最終移位位數,32 + ( -60 ) = -28,由于結果還是負數,所以繼續相加,32 + ( -28 ) = 4,此次結果不為負數了,所以最終移位的位數是 4

修改 base.cpp 文件,內容如下:

  1. #include <stdint.h> 
  2. #include <iostream> 
  3. using namespace std; 
  4. int32_t main(int32_t argc , char *argv[]) 
  5.     int32_t a = 7; 
  6.     cout << "(a >> -31) = " << (a >> -31) << endl; 
  7.     cout << "(a << -60) = " << (a >> -60) << endl; 
  8.     return 0; 

編譯代碼并執行,結果如下

  1. (a >> -31) = 3 
  2. (a >> -60) = 0 

變量 a 的值為 7,對應的二進制是 0000 0000 0000 0000 0000 0000 0000 0111

右移 -31 位:移位數是負數,實際右移 32 + ( -31 ) = 1 位,結果為:0000 0000 0000 0000 0000 0000 0000 0011,對應的十進制是 3

右移 -60 位:移位數是負數,實際右移 32 + 32 + ( -60 ) = 4 位,結果為:0000 0000 0000 0000 0000 0000 0000 0000,對應的十進制是 0

小結

 

本文主要介紹了左移和右移操作,左移相當于乘以 2 的 N 次方,而右移相當于除以 2 的 N 次方,這里的 N 表示移位的位數,需要注意的是,當移位位數是負數或者大于等于類型最大位數時,編譯器對他們的處理和正常的移位是不一樣的

 

責任編輯:武曉燕 來源: Linux開發那些事兒
相關推薦

2013-07-29 17:04:18

2021-08-27 15:03:51

PythonC語言數組

2014-02-19 16:26:26

VDI部署

2010-03-24 15:40:39

網管運維管理摩卡軟件

2020-10-27 07:34:41

基站手機蜂窩網絡

2013-08-20 09:48:59

2022-02-18 15:07:29

goroutinepanic協程

2009-12-03 13:32:04

Virtuozzo捆綁

2022-11-24 11:09:03

自然語言處理(智能語音

2015-11-10 09:09:23

代碼程序員成長

2024-03-28 08:13:51

GPTsOpenAI人工智能

2011-11-25 09:48:04

天線無線

2013-08-19 16:17:48

CIO

2009-09-02 20:18:17

域名劫持域名安全

2009-04-22 08:54:25

2015-06-30 11:52:30

2023-11-07 07:21:04

2015-09-06 09:09:13

2014-06-20 10:34:42

開源

2014-12-31 10:02:14

Android可穿戴設備世界
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中国一级特黄毛片大片 | av中文字幕在线 | 午夜影院在线观看 | 国产一区二区在线播放视频 | 欧美6一10sex性hd | 欧美日韩国产精品一区 | 在线免费亚洲视频 | 欧美精品中文 | 国产目拍亚洲精品99久久精品 | 欧美日一区二区 | 日本午夜网 | 国产精品毛片一区二区三区 | 午夜天堂精品久久久久 | 欧美一级二级视频 | 国产乱码精品一区二区三区忘忧草 | 亚洲精品一区二区三区蜜桃久 | 本道综合精品 | 伊伊综合网 | 干干干操操操 | 国产福利91精品一区二区三区 | 在线视频h| 中文字幕一区二区三区日韩精品 | 国产精品高清一区二区 | 国产一区二区三区欧美 | 亚洲一二三区在线观看 | 精品国产乱码久久久久久蜜臀 | 狠狠骚| 国产精品久久久久久妇女 | 国产成人短视频在线观看 | 国产91久久久久久久免费 | 国产亚洲一区二区三区 | 日韩精品在线观看一区二区 | 欧美日韩一区二区在线播放 | 国产三级一区二区 | 日日操视频 | 99这里只有精品视频 | 亚洲第1页 | 国产亚洲一区精品 | 天堂在线中文 | 国产一区二区三区 | 一区二区三区在线播放视频 |