欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++有符號(hào)和無(wú)符號(hào)整數(shù)的位移操作過程

 更新時(shí)間:2025年09月18日 08:34:56   作者:MzKyle  
C++中位移操作對(duì)有符號(hào)與無(wú)符號(hào)整數(shù)處理不同:無(wú)符號(hào)左移補(bǔ)0,右移也補(bǔ)0;有符號(hào)右移補(bǔ)符號(hào)位(算術(shù)移位),左移可能觸發(fā)未定義行為,需注意類型轉(zhuǎn)換與跨平臺(tái)兼容性

在C++中,位移操作(左移<<和右移>>)是對(duì)整數(shù)二進(jìn)制位的直接操作,但其行為在有符號(hào)整數(shù)(signed)無(wú)符號(hào)整數(shù)(unsigned) 中存在顯著差異。

這種差異源于計(jì)算機(jī)對(duì)整數(shù)的存儲(chǔ)方式(補(bǔ)碼)和語(yǔ)言標(biāo)準(zhǔn)對(duì)操作的規(guī)定,理解這些差異是編寫正確位運(yùn)算代碼的關(guān)鍵。

一、位移操作的基本概念

位移操作的本質(zhì)是將整數(shù)的二進(jìn)制位向指定方向(左或右)移動(dòng)指定的位數(shù),空出的位由特定規(guī)則填充。在C++中,位移操作符的語(yǔ)法為:

  • 左移:a << n 表示將a的二進(jìn)制位向左移動(dòng)n位,右側(cè)空出的位補(bǔ)0;
  • 右移:a >> n 表示將a的二進(jìn)制位向右移動(dòng)n位,左側(cè)空出的位填充規(guī)則因整數(shù)是否有符號(hào)而不同。

需要注意的是:

  • 位移的位數(shù)n必須是非負(fù)整數(shù),且不能大于等于操作數(shù)的位數(shù)(如32位整數(shù)位移32位及以上屬于未定義行為);
  • 位移操作的結(jié)果類型與左操作數(shù)的類型一致(如int位移后仍為int)。

二、無(wú)符號(hào)整數(shù)(unsigned)的位移:邏輯移位

無(wú)符號(hào)整數(shù)的位移是邏輯移位(Logical Shift),即不考慮符號(hào)位,僅根據(jù)“空位補(bǔ)0”的規(guī)則處理,行為在C++標(biāo)準(zhǔn)中是完全明確的。

1. 無(wú)符號(hào)左移(unsigned << n)

左移時(shí),二進(jìn)制位整體向左移動(dòng)n位,右側(cè)空出的n位全部補(bǔ)0,左側(cè)超出類型位數(shù)的高位被直接丟棄。

舉例:假設(shè)unsigned int為32位,分析unsigned int a = 0x0000000F(二進(jìn)制00000000 00000000 00000000 00001111)的左移:

  • a << 1:左移1位后,右側(cè)補(bǔ)0,結(jié)果為0x0000001E(二進(jìn)制00000000 00000000 00000000 00011110);
  • a << 4:左移4位后,右側(cè)補(bǔ)4個(gè)0,結(jié)果為0x000000F0(二進(jìn)制00000000 00000000 00000000 11110000);
  • a << 28:左移28位后,高位超出32位的部分被丟棄,結(jié)果為0xF0000000(二進(jìn)制11110000 00000000 00000000 00000000)。

規(guī)律:無(wú)符號(hào)左移n位等價(jià)于“a * 2^n”(若結(jié)果未超出類型范圍)。

2. 無(wú)符號(hào)右移(unsigned >> n)

右移時(shí),二進(jìn)制位整體向右移動(dòng)n位,左側(cè)空出的n位全部補(bǔ)0,右側(cè)超出的n位被直接丟棄。

舉例:仍以32位unsigned int a = 0xF0000000(二進(jìn)制11110000 00000000 00000000 00000000)為例:

  • a >> 1:右移1位后,左側(cè)補(bǔ)0,結(jié)果為0x78000000(二進(jìn)制01111000 00000000 00000000 00000000);
  • a >> 4:右移4位后,左側(cè)補(bǔ)4個(gè)0,結(jié)果為0x0F000000(二進(jìn)制00001111 00000000 00000000 00000000);
  • a >> 28:右移28位后,左側(cè)補(bǔ)28個(gè)0,結(jié)果為0x0000000F(二進(jìn)制00000000 00000000 00000000 00001111)。

規(guī)律:無(wú)符號(hào)右移n位等價(jià)于“a / 2^n”(向下取整)。

三、有符號(hào)整數(shù)(signed)的位移:算術(shù)移位為主

有符號(hào)整數(shù)(如int、long long)在內(nèi)存中以補(bǔ)碼形式存儲(chǔ)(最高位為符號(hào)位:0表示正數(shù),1表示負(fù)數(shù))。其位移行為與無(wú)符號(hào)不同,尤其是右移,C++標(biāo)準(zhǔn)將其定義為“實(shí)現(xiàn)定義”(implementation-defined),但主流編譯器(如GCC、Clang、MSVC)均采用算術(shù)移位(Arithmetic Shift)規(guī)則。

1. 有符號(hào)左移(signed << n)

有符號(hào)左移的行為與無(wú)符號(hào)左移基本一致:二進(jìn)制位向左移動(dòng)n位,右側(cè)空出的n位補(bǔ)0,左側(cè)超出類型位數(shù)的高位(包括符號(hào)位)被丟棄。

注意:若左移后符號(hào)位發(fā)生變化(如正數(shù)左移后符號(hào)位變?yōu)?),結(jié)果可能超出該類型能表示的范圍,此時(shí)屬于未定義行為(undefined behavior)。

舉例:32位int(范圍-2^31 ~ 2^31-1):

  • 正數(shù)左移:int a = 0x0000000F(15),a << 1 結(jié)果為0x0000001E(30),符號(hào)位仍為0(合法);
  • 負(fù)數(shù)左移:int b = -0x0000000F(-15,補(bǔ)碼0xFFFFFFF1),b << 1 結(jié)果為0xFFFFFFE2(-30),符號(hào)位仍為1(合法);
  • 未定義行為:int c = 0x40000000(1073741824),c << 1 結(jié)果為0x80000000(-2147483648),符號(hào)位從0變?yōu)?,屬于未定義行為(不同編譯器可能有差異)。

2. 有符號(hào)右移(signed >> n)

有符號(hào)右移是最容易產(chǎn)生差異的操作。主流編譯器采用算術(shù)移位:右側(cè)超出的n位被丟棄,左側(cè)空出的n位補(bǔ)符號(hào)位(正數(shù)補(bǔ)0,負(fù)數(shù)補(bǔ)1)。

這種規(guī)則的目的是保持位移后數(shù)值的“符號(hào)一致性”,尤其對(duì)負(fù)數(shù)而言,右移后仍為負(fù)數(shù)。

舉例1:正數(shù)右移
int a = 0x0000000F(15,二進(jìn)制00000000 00000000 00000000 00001111):

  • 符號(hào)位為0,右移時(shí)左側(cè)補(bǔ)0;
  • a >> 1:結(jié)果為0x00000007(7,二進(jìn)制00000000 00000000 00000000 00000111);
  • a >> 4:結(jié)果為0x00000000(0,二進(jìn)制00000000 00000000 00000000 00000000)。

舉例2:負(fù)數(shù)右移
int b = -0x0000000F(-15,補(bǔ)碼0xFFFFFFF1,二進(jìn)制11111111 11111111 11111111 11110001):

  • 符號(hào)位為1,右移時(shí)左側(cè)補(bǔ)1;
  • b >> 1:右移1位后,左側(cè)補(bǔ)1,結(jié)果為0xFFFFFFF8(-8,二進(jìn)制11111111 11111111 11111111 11111000);
  • b >> 4:右移4位后,左側(cè)補(bǔ)4個(gè)1,結(jié)果為0xFFFFFFF0(-16,二進(jìn)制11111111 11111111 11111111 11110000)。

規(guī)律:有符號(hào)右移n位對(duì)正數(shù)等價(jià)于“a / 2^n”(向零舍入);對(duì)負(fù)數(shù)等價(jià)于“a / 2^n”(向下取整,如-15 >> 1 = -8,而-15 / 2 = -7)。

四、有符號(hào)與無(wú)符號(hào)位移的核心差異對(duì)比

操作類型無(wú)符號(hào)整數(shù)(unsigned)有符號(hào)整數(shù)(signed)
左移(<<)邏輯移位,右側(cè)補(bǔ)0,高位丟棄邏輯移位(同無(wú)符號(hào)),但可能觸發(fā)未定義行為
右移(>>)=邏輯移位,左側(cè)補(bǔ)0,低位丟棄算術(shù)移位(主流編譯器),左側(cè)補(bǔ)符號(hào)位
符號(hào)影響無(wú)符號(hào)位,位移后仍為非負(fù)符號(hào)位不變(算術(shù)移位),負(fù)數(shù)位移后仍為負(fù)
應(yīng)用場(chǎng)景位運(yùn)算(如哈希、編碼)帶符號(hào)的數(shù)值計(jì)算(如除法近似)

五、實(shí)際開發(fā)中的注意事項(xiàng)

1.避免對(duì)有符號(hào)整數(shù)進(jìn)行右移依賴

由于有符號(hào)右移是“實(shí)現(xiàn)定義”,若代碼需要跨編譯器兼容,應(yīng)避免依賴其行為。如需邏輯右移,可先轉(zhuǎn)換為無(wú)符號(hào)類型(如(unsigned int)a >> n)。

2.負(fù)數(shù)轉(zhuǎn)換為無(wú)符號(hào)的妙用

如之前的toHex函數(shù)中,負(fù)數(shù)轉(zhuǎn)換為unsigned int后,右移變?yōu)檫壿嬕莆唬ǜ呶谎a(bǔ)0),可正常處理補(bǔ)碼的所有位,避免無(wú)限循環(huán)(若用有符號(hào)右移,負(fù)數(shù)會(huì)因補(bǔ)1而永遠(yuǎn)不為0)。

3.警惕位移后的未定義行為

  • 位移位數(shù)為負(fù)或大于等于類型位數(shù)(如32位int移32位);
  • 有符號(hào)左移后符號(hào)位改變(超出表示范圍)。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 一些語(yǔ)言的按行讀取文件的代碼實(shí)現(xiàn)小結(jié)

    一些語(yǔ)言的按行讀取文件的代碼實(shí)現(xiàn)小結(jié)

    這篇文章主要介紹了一些語(yǔ)言的按行讀取文件的代碼實(shí)現(xiàn)小結(jié),這里羅列了Java和C語(yǔ)言和C++以及PHP的實(shí)現(xiàn)需要的朋友可以參考下
    2015-08-08
  • 利用Matlab制作三子棋游戲的示例代碼

    利用Matlab制作三子棋游戲的示例代碼

    三子棋是一種民間傳統(tǒng)游戲,又叫九宮棋、圈圈叉叉、一條龍、井字棋等。將正方形對(duì)角線連起來(lái),相對(duì)兩邊依次擺上三個(gè)雙方棋子,只要將自己的三個(gè)棋子走成一條線,對(duì)方就算輸了。本文將用Matlab制作這一經(jīng)典游戲,感興趣的可以試一試
    2022-03-03
  • c語(yǔ)言 漢諾塔算法代碼

    c語(yǔ)言 漢諾塔算法代碼

    c語(yǔ)言 漢諾塔算法代碼,需要的朋友可以參考一下
    2013-04-04
  • windows下vscode環(huán)境c++利用matplotlibcpp繪圖

    windows下vscode環(huán)境c++利用matplotlibcpp繪圖

    本文主要介紹了windows下vscode環(huán)境c++利用matplotlibcpp繪圖,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 使用pthread庫(kù)實(shí)現(xiàn)openssl多線程ssl服務(wù)端和客戶端

    使用pthread庫(kù)實(shí)現(xiàn)openssl多線程ssl服務(wù)端和客戶端

    使用pthread庫(kù)實(shí)現(xiàn)openssl多線程ssl服務(wù)端和客戶端,大家參考使用吧
    2014-01-01
  • C++ qt 使用jsoncpp json 讀寫操作

    C++ qt 使用jsoncpp json 讀寫操作

    JsonCpp是一個(gè)基于C++語(yǔ)言的開源庫(kù),用于C++程序的Json數(shù)據(jù)的讀寫操作,本文重點(diǎn)給大家介紹C++ qt 使用jsoncpp json 讀寫操作,感興趣的朋友跟隨小編一起看看吧
    2021-11-11
  • C++中用棧來(lái)判斷括號(hào)字符串匹配問題的實(shí)現(xiàn)方法

    C++中用棧來(lái)判斷括號(hào)字符串匹配問題的實(shí)現(xiàn)方法

    這篇文章主要介紹了C++中用棧來(lái)判斷括號(hào)字符串匹配問題的實(shí)現(xiàn)方法,是一個(gè)比較實(shí)用的算法技巧,包含了關(guān)于棧的基本操作,需要的朋友可以參考下
    2014-08-08
  • C程序?qū)崿F(xiàn)整數(shù)的素?cái)?shù)和分解問題

    C程序?qū)崿F(xiàn)整數(shù)的素?cái)?shù)和分解問題

    這篇文章主要介紹了C程序?qū)崿F(xiàn)整數(shù)的素?cái)?shù)和分解問題,對(duì)于算法的學(xué)習(xí)有不錯(cuò)的借鑒價(jià)值,需要的朋友可以參考下
    2014-09-09
  • C語(yǔ)言 詳細(xì)講解#pragma的使用方法

    C語(yǔ)言 詳細(xì)講解#pragma的使用方法

    #pragma 指令對(duì)每個(gè)編譯器給出了一個(gè)方法,在保持與C和C++語(yǔ)言完全兼容的情況下,給出主機(jī)或操作系統(tǒng)專有的特征。依據(jù)定義,編譯指示是機(jī)器或操作系統(tǒng)專有的, 且對(duì)于每個(gè)編譯器都是不同的
    2022-04-04
  • 詳解Matlab如何繪制?;鶊D

    詳解Matlab如何繪制?;鶊D

    ?;鶊D是一種特定類型的流程圖,圖中延伸的分支的寬度對(duì)應(yīng)數(shù)據(jù)流量的大小,通常應(yīng)用于能源、材料成分、金融等數(shù)據(jù)的可視化分析。本文將用Matlab繪制好看的?;鶊D,需要的可以參考一下
    2022-03-03

最新評(píng)論