小古銀的官方網(wǎng)站(完整教程):http://www.xiaoguyin.com/
C++入門教程視頻:https://www.bilibili.com/video/av20868986/
加法
以010 + 010為例子:加號兩邊的數(shù)值的右邊第一位都是0,相加得0;中間那一位都是1,相加得2,所以需要進位,結(jié)果變?yōu)?;左邊第一位都是0,相加得0,再加上進的位,所以結(jié)果是1。那么最后結(jié)果就是100。也就是十進制的2 + 2的結(jié)果是4。
注意:而C++中的二進制的運算都是有一個前提條件,就是必須固定位數(shù)再進行運算,如果進位時超出位數(shù)那么超出部分將會被舍棄。例如要相加的二進制數(shù)值是3位數(shù),110 + 010,按照加法運算結(jié)果應(yīng)該是1000,因為位數(shù)已經(jīng)固定三位,左邊超出的一位將被舍棄,所以結(jié)果是000。
提示:二進制表示數(shù)值時,左邊的0是可以省略的,把左邊的0寫出來是為了方便講解,如二進制的00000010可以省略寫成二進制的10,相當(dāng)于十進制的00123456也可以簡寫成123456。由于C++的二進制運算是固定位數(shù)的,所以就算你省略了左邊的0,程序也是知道左邊應(yīng)該補上多少個0。
基礎(chǔ)示例
#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;
}
輸出結(jié)果:
0b010 + 0b010 = 4
0
基礎(chǔ)講解
二進制的010加上二進制的010結(jié)果是二進制的100,也就是十進制2加上十進制2等于十進制的4。
unsigned int是保存非負整數(shù)的int類型,它的最大值是4294967295,也就是二進制32位都是1的值,而且unsigned int是用固定的32位二進制來保存數(shù)據(jù)的,所以當(dāng)它加上1的時候,就會因為進位而超出一個位,而超出的這個位就會被舍棄,因此輸出結(jié)果就是0。
減法
以101 - 011為例子:第一位相減結(jié)果是0,而第二位0減去1需要向高位借一位,因此第二位結(jié)果是1,但三位結(jié)果是0,則結(jié)果是010。也就是十進制的5 - 3結(jié)果是2。
注意:由于運算需要固定位數(shù),所以上面內(nèi)容同樣也適用于減法運算,但是需要注意的是二進制只有0和1而沒有正負的概念。以010 - 011作為例子:第一位結(jié)果是1,而且向第二位借了一位;而第二位此時已經(jīng)不能正常運算了,此時雖然沒有第四位,但是它可以從第四位借一位,第四位向誰借就不管了,反正第三位可以計算了,那么第二位就可以向第三位借一位,第二位結(jié)果是1,第三位結(jié)果是1。最后結(jié)果就是二進制的111。
基礎(chǔ)示例
#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;
}
輸出結(jié)果:
0b101 - 0b010 = 2
4294967295
基礎(chǔ)講解
二進制的101減去二進制的011結(jié)果是二進制的010,也就是十進制的5減去3等于的2。
由于固定了32位的二進制運算,按照上面的運算方法得出的結(jié)果是二進制的32位都是1,也就是unsigned int的最大值,所以對應(yīng)的十進制結(jié)果就是4294967295。
二進制的乘法和除法
二進制的乘法和除法比較復(fù)雜,而且對C++基礎(chǔ)知識幫助不大,就不講解了。以下講解的運算是二進制特有的運算。
左移運算和右移運算
以二進制0110舉例:0110左移一位就是在右邊添加1位0,得出01100,由于固定位數(shù),所以左邊超出的1位被舍棄,結(jié)果就是1100;0110左移兩位就是在右邊添加2位0,得出011000,由于固定位數(shù),所以左邊超出的2位被舍棄,結(jié)果就是1000,以此類推。右移也是同理,0110右移1位就是0011,右移2位就是0001。
在C++中左移的運算符號是<<,右移的運算符號是>>。0110左移2位的代碼就是0110 << 2,0110右移2位的代碼就是0110 >> 2。
一個有意思的規(guī)律:例如0001 + 0001的結(jié)果是0010,0010 + 0010的結(jié)果是0100,0011 + 0011的結(jié)果是0110??梢钥闯觯阂粋€數(shù)乘以2就等于這個數(shù)左移一位,而一個數(shù)左移兩位就是這個數(shù)乘以2的2次方,以此類推。而右移也是同理。
特殊的情況,2的10次方就是1左移10位,結(jié)果就是二進制的10000000000,也就是十進制的1024。
基礎(chǔ)示例
#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;
}
輸出結(jié)果:
80
0
5
0
基礎(chǔ)講解
十進制的10左移3位,也就是十進制的10乘以2的3次方,結(jié)果就是十進制的80。
變量value1保存的數(shù)左移一位,由于unsigned int類型用32位二進制來保存數(shù)據(jù),所以當(dāng)它左移一位時,左邊的1因為超出而被舍棄,結(jié)果就是0。
十進制的10右移1位,也就是十進制的10除以2的1次方,結(jié)果就是十進制的5。
變量value2保存的數(shù)右移一位,由于unsigned int類型用32位二進制來保存數(shù)據(jù),所以當(dāng)它右移一位時,右邊的1因為超出而被舍棄,結(jié)果就是0。
與運算
在C++中,與運算的運算符號是&。
1 & 1的結(jié)果是1;1 & 0或者0 & 1的結(jié)果是0,0 & 0的結(jié)果也是0。
而二進制運算0110 & 0100的結(jié)果是0100??梢钥闯雠c運算就是二進制各個位上對應(yīng)的數(shù)進行與運算,都是1的時候結(jié)果是1,有一個0或者都是0的時候結(jié)果是0。
或運算
在C++中,或運算的運算符號是|。
1 | 1的結(jié)果是1;1 | 0或者0 | 1的結(jié)果是1,0 | 0的結(jié)果也是0。
而二進制運算0110 | 0100的結(jié)果是0110。可以看出或運算就是二進制各個位上對應(yīng)的數(shù)進行或運算,都是1或者有一個是1的時候結(jié)果是1,都是0的時候結(jié)果是0。
異或運算
在C++中,異或運算的運算符號是^。
1 ^ 1的結(jié)果是0;1 ^ 0或者0 ^ 1的結(jié)果是1,0 ^ 0的結(jié)果也是0。也就是說,異或相同的數(shù)結(jié)果是0,異或不同的數(shù)結(jié)果是1,而二進制運算0110 ^ 0100的結(jié)果是0010。
取反運算
在C++中,取反運算的運算符號是~。取反運算就是二進制各個位上的數(shù),0變?yōu)?,1變?yōu)?。例如二進制運算~0110的結(jié)果是1001。
注意:取反運算時,需要注意它的數(shù)據(jù)類型,不同的數(shù)據(jù)類型的位數(shù)都不相同,而上面也說過左邊多出來的0可以省略,所以就算是同一個數(shù),如0b1101,二進制位數(shù)是4位時結(jié)果是0b0010,二進制位數(shù)是8位時結(jié)果是0b11110010,它們的值是不一樣的。所以,取反必須要注意它的數(shù)據(jù)類型喲~。
基礎(chǔ)示例
#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;
}
輸出結(jié)果:
4
6
2
4294967295
基礎(chǔ)講解
二進制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
保存過大數(shù)據(jù)時注意范圍
unsinged int用二進制32位來保存數(shù)據(jù),如果用unsinged int的變量保存更大的數(shù)據(jù)會怎么樣呢?
基礎(chǔ)示例
#include <iostream>
int main(void)
{
unsigned int value = 0b1'0000'0000'0000'0000'0000'0000'0000'0001;
std::cout << value << std::endl;
return 0;
}
輸出結(jié)果:
1
基礎(chǔ)講解
可以看出,用二進制32位的空間保存33位的數(shù)據(jù),它只會保存前32位數(shù)據(jù),第33位數(shù)據(jù)會被舍棄。所以,用變量保存數(shù)據(jù)時要注意不要保存過大的數(shù)值。