自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

移位的位數(shù)是負(fù)數(shù),結(jié)果會(huì)怎樣?

開(kāi)發(fā) 前端
有過(guò)編程經(jīng)驗(yàn)的同學(xué),對(duì)于移位操作應(yīng)該很熟悉了,日常工作中或多或少都有用到,當(dāng) 移位位數(shù)是負(fù)數(shù) 或者 移位位數(shù)超過(guò)了 類型的最大二進(jìn)制位時(shí),和正常移位處理是不一樣的,下面將詳細(xì)說(shuō)明這兩種情況,在此之前,先了解下正常的移位操作。

[[432672]]

有過(guò)編程經(jīng)驗(yàn)的同學(xué),對(duì)于移位操作應(yīng)該很熟悉了,日常工作中或多或少都有用到,當(dāng) 移位位數(shù)是負(fù)數(shù) 或者 移位位數(shù)超過(guò)了 類型的最大二進(jìn)制位時(shí),和正常移位處理是不一樣的,下面將詳細(xì)說(shuō)明這兩種情況,在此之前,先了解下正常的移位操作

正數(shù)的左移和右移

正數(shù)的左移是二進(jìn)制位向左移動(dòng),右邊留空的位置補(bǔ) 0,右移是二進(jìn)制位向右移動(dòng),左邊留空的位置補(bǔ) 0 ( 符號(hào)位為 0 )

  • 左移

左移操作,最高位的符號(hào)位會(huì)出現(xiàn) 0 或 1 , 因此結(jié)果會(huì)出現(xiàn)正數(shù)和負(fù)數(shù)的情況

新建測(cè)試文件 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; 

執(zhí)行 g++ -g -Wall -std=c++11 -o base base.cpp 命令編譯代碼,再執(zhí)行 ./base 運(yùn)行程序,結(jié)果如下

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

上述代碼中,變量 a 的值為 7,對(duì)應(yīng)的二進(jìn)制是 0000 0000 0000 0000 0000 0000 0000 0111

左移 2 位:二進(jìn)制向左移動(dòng) 2 位,右邊補(bǔ)充 2 位 0 ,左邊丟棄超出的 2 位二進(jìn)制, 結(jié)果是 0000 0000 0000 0000 0000 0000 0001 1100, 對(duì)應(yīng)的十進(jìn)制數(shù)是 28

左移 30 位 的流程如下圖

由上圖可知,二進(jìn)制向左移動(dòng) 30 位后, 左邊 30 位二進(jìn)制 0000 0000 0000 0000 0000 0000 0000 01 因超出被丟棄,同時(shí)最右邊剩下的 2 位二進(jìn)制 11 左移 30 位,右邊空的位置補(bǔ)充 30 位 0,最終的結(jié)果是 1100 0000 0000 0000 0000 0000 0000 0000, 對(duì)應(yīng)的十進(jìn)制數(shù)是 -1073741824

可以看出,正數(shù) 7 左移 30 位后,二進(jìn)制的符號(hào)位變成了 1 ,也即正數(shù)變成了負(fù)數(shù)了

  • 右移

正數(shù)右移,最小為 0 , 不會(huì)出現(xiàn)負(fù)數(shù),下面是右移的測(cè)試代碼

修改 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; 

編譯并運(yùn)行上面程序,結(jié)果如下:

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

上述實(shí)例代碼中,變量 a 的值為 7,對(duì)應(yīng)的二進(jìn)制是 0000 0000 0000 0000 0000 0000 0000 0111

右移 1 位:二進(jìn)制向右移動(dòng) 1 位,左邊補(bǔ)充一位 0 ,右邊丟棄超出的一位二進(jìn)制, 結(jié)果是 0000 0000 0000 0000 0000 0000 0000 0011, 對(duì)應(yīng)的十進(jìn)制數(shù)是 3

右移 31 位:二進(jìn)制向右移動(dòng) 31 位,左邊補(bǔ)充 31 位 0 ,右邊丟棄超出的 31 位二進(jìn)制,結(jié)果是 0000 0000 0000 0000 0000 0000 0000 0000, 對(duì)應(yīng)的十進(jìn)制是 0

負(fù)數(shù)的左移和右移

負(fù)數(shù)的左移是二進(jìn)制位向左移動(dòng),右邊留空的位置補(bǔ) 0,右移是二進(jìn)制位向右移動(dòng),左邊留空的位置補(bǔ) 1 ( 符號(hào)位為 1 ),這一點(diǎn)跟正數(shù)是不一樣的

計(jì)算機(jī)中是用補(bǔ)碼的形式進(jìn)行各種運(yùn)算的,正數(shù)的補(bǔ)碼是其自身,負(fù)數(shù)的補(bǔ)碼是將其正數(shù)按位取反加 1

  • 左移

負(fù)數(shù)左移,符號(hào)位可能會(huì)變成0,因此結(jié)果會(huì)出現(xiàn)正數(shù)和負(fù)數(shù)的情況,一直左移的話,最終會(huì)變成 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; 

編譯并運(yùn)行上面程序,結(jié)果如下:

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

上面代碼中,變量 b 的值為 -3,對(duì)應(yīng)的二進(jìn)制是 1111 1111 1111 1111 1111 1111 1111 1101

左移 1 位:整個(gè)二進(jìn)制串向左移動(dòng) 1 位,右邊補(bǔ)充 0 ,左邊丟棄超出的一位二進(jìn)制,結(jié)果是 1111 1111 1111 1111 1111 1111 1111 1010,對(duì)應(yīng)十進(jìn)制數(shù) -6

左移 30 位 的流程如下

由上圖可知,左移 30 位,左邊的 30 位二進(jìn)制 1111 1111 1111 1111 1111 1111 1111 11 因超出數(shù)值最大位數(shù)而被丟棄,原來(lái)最右邊的 01 移到了最左邊,緊接著后面的 30 個(gè)空位全部補(bǔ) 0 ,最終的結(jié)果是 0100 0000 0000 0000 0000 0000 0000 0000 ,對(duì)應(yīng)十進(jìn)制是 1073741824

可以看出,負(fù)數(shù) -3 左移 30 位后,二進(jìn)制的符號(hào)位變成了 0 ,由開(kāi)始的負(fù)數(shù)變成了正數(shù)了

  • 右移

負(fù)數(shù)右移是在左邊補(bǔ) 1, 所以結(jié)果不會(huì)出現(xiàn)正數(shù)的情況,如果一直右移,最終二進(jìn)制位會(huì)全部變成 1,即十進(jìn)制的 -1 ( 二進(jìn)制全 1 在補(bǔ)碼中表示 -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; 

編譯并運(yùn)行上面程序,結(jié)果如下:

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

上面代碼中,變量 b 的值為 -3,對(duì)應(yīng)的二進(jìn)制是 1111 1111 1111 1111 1111 1111 1111 1101

右移 1 位:二進(jìn)制位向右移動(dòng) 1 位,左邊補(bǔ)充 1 ,右邊丟棄一位超出的二進(jìn)制,結(jié)果為 1111 1111 1111 1111 1111 1111 1111 1110,對(duì)應(yīng)的十進(jìn)制是 -2

右移 31 位 的流程如下

根據(jù)上圖可知,右移 31 位,最右邊的 31 位二進(jìn)制 1111 1111 1111 1111 1111 1111 1111 110 因超出數(shù)值最大位數(shù)而被丟棄, 原來(lái)左邊的 1 移到了最右邊,左邊補(bǔ) 31 位 1,最后結(jié)果為:1111 1111 1111 1111 1111 1111 1111 1111 , 對(duì)應(yīng)的十進(jìn)制數(shù) -1

移位數(shù)超過(guò)類型最大位數(shù)

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

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

修改 base.cpp 文件,內(nèi)容如下:

  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; 

編譯并執(zhí)行,結(jié)果如下

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

變量 a 的值為 7,對(duì)應(yīng)的二進(jìn)制是 0000 0000 0000 0000 0000 0000 0000 0111

右移 32 位:因移位位數(shù)等于 int32_t 最大位數(shù),所以實(shí)際移位數(shù)為 32 % 32 = 0,右移 0 位 表示沒(méi)有移位,所以結(jié)果還是 7

右移 33 位:移位位數(shù)大于 int32_t 最大位數(shù),故實(shí)際移位數(shù)為 33 % 32 = 1,右移 1 位,左邊補(bǔ) 0 ,右邊丟棄超出的位,結(jié)果是: 0000 0000 0000 0000 0000 0000 0000 0011,對(duì)應(yīng)的十進(jìn)制是 3

左移 34 位:移位位數(shù)大于 32 ,實(shí)際移位數(shù)為 34 % 32 = 2,左移 2 位,右邊補(bǔ) 0 ,左邊丟棄超出的位,結(jié)果是:0000 0000 0000 0000 0000 0000 0001 1100,對(duì)應(yīng)的十進(jìn)制是 28

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

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

移位的位數(shù)是負(fù)值

當(dāng)移位的位數(shù)是負(fù)值時(shí),實(shí)際移位的位數(shù)是:用被移位數(shù)值類型的最大位數(shù)和移位位數(shù)相加,如果結(jié)果還是負(fù)數(shù),結(jié)果繼續(xù) 加上被移位數(shù)值類型的最大位數(shù),直到結(jié)果不為負(fù)數(shù)為止,此時(shí)的結(jié)果即為最終移位的位數(shù)

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

當(dāng)移位位數(shù)是 -60,計(jì)算最終移位位數(shù),32 + ( -60 ) = -28,由于結(jié)果還是負(fù)數(shù),所以繼續(xù)相加,32 + ( -28 ) = 4,此次結(jié)果不為負(fù)數(shù)了,所以最終移位的位數(shù)是 4

修改 base.cpp 文件,內(nèi)容如下:

  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; 

編譯代碼并執(zhí)行,結(jié)果如下

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

變量 a 的值為 7,對(duì)應(yīng)的二進(jìn)制是 0000 0000 0000 0000 0000 0000 0000 0111

右移 -31 位:移位數(shù)是負(fù)數(shù),實(shí)際右移 32 + ( -31 ) = 1 位,結(jié)果為:0000 0000 0000 0000 0000 0000 0000 0011,對(duì)應(yīng)的十進(jìn)制是 3

右移 -60 位:移位數(shù)是負(fù)數(shù),實(shí)際右移 32 + 32 + ( -60 ) = 4 位,結(jié)果為:0000 0000 0000 0000 0000 0000 0000 0000,對(duì)應(yīng)的十進(jìn)制是 0

小結(jié)

 

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

 

責(zé)任編輯:武曉燕 來(lái)源: Linux開(kāi)發(fā)那些事兒
相關(guān)推薦

2013-07-29 17:04:18

2021-08-27 15:03:51

PythonC語(yǔ)言數(shù)組

2014-02-19 16:26:26

VDI部署

2010-03-24 15:40:39

網(wǎng)管運(yùn)維管理摩卡軟件

2020-10-27 07:34:41

基站手機(jī)蜂窩網(wǎng)絡(luò)

2013-08-20 09:48:59

2022-02-18 15:07:29

goroutinepanic協(xié)程

2022-11-24 11:09:03

自然語(yǔ)言處理(智能語(yǔ)音

2009-12-03 13:32:04

Virtuozzo捆綁

2009-04-22 08:54:25

2015-09-06 09:09:13

2014-06-20 10:34:42

開(kāi)源

2011-11-25 09:48:04

天線無(wú)線

2013-08-19 16:17:48

CIO

2009-09-02 20:18:17

域名劫持域名安全

2024-03-28 08:13:51

GPTsOpenAI人工智能

2015-11-10 09:09:23

代碼程序員成長(zhǎng)

2011-04-07 09:33:22

2023-03-03 11:12:34

Kubernetes控制器后端

2019-03-18 10:02:16

緩存更新數(shù)據(jù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)