C++入門教程(16):二進制的運算

小古銀的官方網站(完整教程):http://www.xiaoguyin.com/
C++入門教程視頻:https://www.bilibili.com/vide...ios


加法

010 + 010爲例子:加號兩邊的數值的右邊第一位都是0,相加得0;中間那一位都是1,相加得2,因此須要進位,結果變爲0;左邊第一位都是0,相加得0,再加上進的位,因此結果是1。那麼最後結果就是100。也就是十進制的2 + 2的結果是4ide

注意:而C++中的二進制的運算都是有一個前提條件,就是必須固定位數再進行運算,若是進位時超出位數那麼超出部分將會被捨棄。例如要相加的二進制數值是3位數,110 + 010,按照加法運算結果應該是1000,由於位數已經固定三位,左邊超出的一位將被捨棄,因此結果是000大數據

提示:二進制表示數值時,左邊的0是能夠省略的,把左邊的0寫出來是爲了方便講解,如二進制的00000010能夠省略寫成二進制的10,至關於十進制的00123456也能夠簡寫成123456。因爲C++的二進制運算是固定位數的,因此就算你省略了左邊的0,程序也是知道左邊應該補上多少個0。網站

基礎示例

#include <iostream>

int main(void)
{
    std::cout << "0b010 + 0b010 = " << (0b010 + 0b010) << std::endl;

    unsigned int value = 4294967295;
    std::cout << (value + 1) << std::endl;

    return 0;
}

輸出結果:code

0b010 + 0b010 = 4
0

基礎講解

二進制的010加上二進制的010結果是二進制的100,也就是十進制2加上十進制2等於十進制的4視頻

unsigned int是保存非負整數的int類型,它的最大值是4294967295,也就是二進制32位都是1的值,並且unsigned int是用固定的32位二進制來保存數據的,因此當它加上1的時候,就會由於進位而超出一個位,而超出的這個位就會被捨棄,所以輸出結果就是0教程

減法

101 - 011爲例子:第一位相減結果是0,而第二位0減去1須要向高位借一位,所以第二位結果是1,但三位結果是0,則結果是010。也就是十進制的5 - 3結果是2get

注意:因爲運算須要固定位數,因此上面內容一樣也適用於減法運算,可是須要注意的是二進制只有0和1而沒有正負的概念。以010 - 011做爲例子:第一位結果是1,並且向第二位借了一位;而第二位此時已經不能正常運算了,此時雖然沒有第四位,可是它能夠從第四位借一位,第四位向誰借就無論了,反正第三位能夠計算了,那麼第二位就能夠向第三位借一位,第二位結果是1,第三位結果是1。最後結果就是二進制的111io

基礎示例

#include <iostream>

int main(void)
{
    std::cout << "0b101 - 0b010 = " << (0b101 - 0b011) << std::endl;

    unsigned int value = 0;
    std::cout << (value - 1) << std::endl;

    return 0;
}

輸出結果:入門

0b101 - 0b010 = 2
4294967295

基礎講解

二進制的101減去二進制的011結果是二進制的010,也就是十進制的5減去3等於的2

因爲固定了32位的二進制運算,按照上面的運算方法得出的結果是二進制的32位都是1,也就是unsigned int的最大值,因此對應的十進制結果就是4294967295

二進制的乘法和除法

二進制的乘法和除法比較複雜,並且對C++基礎知識幫助不大,就不講解了。如下講解的運算是二進制特有的運算。

左移運算和右移運算

以二進制0110舉例:0110左移一位就是在右邊添加1位0,得出01100,因爲固定位數,因此左邊超出的1位被捨棄,結果就是11000110左移兩位就是在右邊添加2位0,得出011000,因爲固定位數,因此左邊超出的2位被捨棄,結果就是1000,以此類推。右移也是同理,0110右移1位就是0011,右移2位就是0001

在C++中左移的運算符號是<<,右移的運算符號是>>0110左移2位的代碼就是0110 << 20110右移2位的代碼就是0110 >> 2

一個有意思的規律:例如0001 + 0001的結果是00100010 + 0010的結果是01000011 + 0011的結果是0110。能夠看出:一個數乘以2就等於這個數左移一位,而一個數左移兩位就是這個數乘以2的2次方,以此類推。而右移也是同理。

特殊的狀況,2的10次方就是1左移10位,結果就是二進制的10000000000,也就是十進制的1024

基礎示例

#include <iostream>

int main(void)
{
    std::cout << (10 << 3) << std::endl;

    unsigned int value1 = 0b1000'0000'0000'0000'0000'0000'0000'0000;
    std::cout << (value1 << 1) << std::endl;

    std::cout << (10 >> 1) << std::endl;

    unsigned int value2 = 0b1;
    std::cout << (value2 >> 1) << std::endl;

    return 0;
}

輸出結果:

80
0
5
0

基礎講解

十進制的10左移3位,也就是十進制的10乘以2的3次方,結果就是十進制的80。

變量value1保存的數左移一位,因爲unsigned int類型用32位二進制來保存數據,因此當它左移一位時,左邊的1由於超出而被捨棄,結果就是0。

十進制的10右移1位,也就是十進制的10除以2的1次方,結果就是十進制的5。

變量value2保存的數右移一位,因爲unsigned int類型用32位二進制來保存數據,因此當它右移一位時,右邊的1由於超出而被捨棄,結果就是0。

與運算

在C++中,與運算的運算符號是&

1 & 1的結果是1;1 & 0或者0 & 1的結果是0,0 & 0的結果也是0。

而二進制運算0110 & 0100的結果是0100。能夠看出與運算就是二進制各個位上對應的數進行與運算,都是1的時候結果是1,有一個0或者都是0的時候結果是0。

或運算

在C++中,或運算的運算符號是|

1 | 1的結果是1;1 | 0或者0 | 1的結果是1,0 | 0的結果也是0。

而二進制運算0110 | 0100的結果是0110。能夠看出或運算就是二進制各個位上對應的數進行或運算,都是1或者有一個是1的時候結果是1,都是0的時候結果是0。

異或運算

在C++中,異或運算的運算符號是^

1 ^ 1的結果是0;1 ^ 0或者0 ^ 1的結果是1,0 ^ 0的結果也是0。也就是說,異或相同的數結果是0,異或不一樣的數結果是1,而二進制運算0110 ^ 0100的結果是0010

取反運算

在C++中,取反運算的運算符號是~。取反運算就是二進制各個位上的數,0變爲1,1變爲0。例如二進制運算~0110的結果是1001

注意:取反運算時,須要注意它的數據類型,不一樣的數據類型的位數都不相同,而上面也說過左邊多出來的0能夠省略,因此就算是同一個數,如0b1101,二進制位數是4位時結果是0b0010,二進制位數是8位時結果是0b11110010,它們的值是不同的。因此,取反必需要注意它的數據類型喲~。

基礎示例

#include <iostream>

int main(void)
{
    std::cout << (0b0110 & 0b0100) << std::endl;
    std::cout << (0b0110 | 0b0100) << std::endl;
    std::cout << (0b0110 ^ 0b0100) << std::endl;

    unsigned int value = 0;
    std::cout << (~value) << std::endl;

    return 0;
}

輸出結果:

4
6
2
4294967295

基礎講解

二進制0100就是十進制的4,二進制的0110就是十進制的6,二進制的0010就是十進制2。二進制32位上全部位都是0,取反就是二進制32位上全部位都是1,也就是unsigned int類型的最大值4294967295

運算符在C++代碼中的簡化

  • 按位與:a = a & b能夠簡化成a &= b
  • 按位或:a = a | b能夠簡化成a |= b
  • 按位異或:a = a ^ b能夠簡化成a ^= b
  • 按位左移:a = a << b能夠簡化成a <<= b
  • 按位右移:a = a >> b能夠簡化成a >>= b

保存過大數據時注意範圍

unsinged int用二進制32位來保存數據,若是用unsinged int的變量保存更大的數據會怎麼樣呢?

基礎示例

#include <iostream>

int main(void)
{
    unsigned int value = 0b1'0000'0000'0000'0000'0000'0000'0000'0001;
    std::cout << value << std::endl;
    return 0;
}

輸出結果:

1

基礎講解

能夠看出,用二進制32位的空間保存33位的數據,它只會保存前32位數據,第33位數據會被捨棄。因此,用變量保存數據時要注意不要保存過大的數值。

相關文章
相關標籤/搜索