您現在的位置是:首頁 > 舞蹈首頁舞蹈
關於二進位制的計算方法和原碼、反碼、補碼等操作
2的10次方除以3的餘數是多少
二。原碼、反碼、補碼
1
什麼是原碼反碼補碼
按照二進位制進行儲存
運算
:
按照二進位制補碼方式參與運算
原碼
:
透過8421碼快速計算資料大小
(
推薦使用計算器
)
直觀的看資料的大小
反碼
:
在轉換補碼的過程中的中間值
補碼
:
參與運算
2
有符號數表示法怎麼做
有符號數
:
資料有正負之分就是有符號數
,
資料無正負之分就是無符號數
例如
:
+
7
-
7
有符號數的組成
:
符號位
+
數值位
例如
int
a
=+
7
;
所佔位元組數4b
32
位
第一個0就是符號位
0
表示正數
1
表示負數
0
0000000
00000000
00000000
00000111
回顧
:
int表示範圍
2
的32次方個數
-
2
的31次方
到
+
2
的31次方
-
1
//有一位是符號位 所以31次方
那麼
+
7
和
-
7
在計算機中如何儲存
程式碼表示
:
//int a=+7;
int
a
=
0b00000000000000000000000000000111
;
//原反補 一樣
System
。
out
。
println
(
a
);
//十進位制表示形式 7
//int b=-7;
int
a
=
0b10000000000000000000000000000111
;
System
。
out
。
println
(
a
);
//十進位制表示形式 -2147483641
/*
如何表示: 是負數所以符號位是1
0b10000000000000000000000000000111 ?
十進位制表示是 -2147483641 並沒有顯示-7
解釋:計算機儲存有符號數是按照補碼的形式存進去的。
0b10000000000000000000000000000111 不是補碼 -7是原碼
總結:
1,計算機儲存有符號數都是按照補碼的形式儲存的
2,正數的原碼,反碼,補碼都是一樣的
3,負數的原碼,反碼,補碼不一樣,
所以如果你直接寫int b=-7 計算機會幫你把它轉成補碼儲存
0b10000000000000000000000000000111這個資料是-7的原碼
如果你儲存這個資料計算機就會把該資料當成補碼去存
(該資料是-7的原碼 會被認為是其他資料透過計算之後的補碼)
原: 符號位+數值位(資料的絕對值)
反: 除了符號位不變 其它全部是1變0,0變1
補: 在反碼的基礎上+1;
再次計算-7
原: 0b10000000000000000000000000000111
反: 0b11111111111111111111111111111000
補: 0b11111111111111111111111111111001 //+1
*/
int
b
=
0b11111111111111111111111111111001
;
System
。
out
。
pirintln
(
b
);
// 會幫你轉換成原碼然後再顯示十進位制 -7;
/*
計算機存的時候是存的0b11111111111111111111111111111001
在輸出十進位制顯示的時候要回推成十進位制的-7
1,補碼-1 得到反碼
0b11111111111111111111111111111001
-1
0b11111111111111111111111111111000
2,剩下符號位不變其餘 1變0,0變1
0b10000000000000000000000000000111
*/
三、位邏輯運算子
1、概念
位運算:(二進位制位或者是bit位)
計算機中所有的計算到計算機底層中都會變成位運算(二進位制位的運算) 位運算可以提高程式的效率,而且以後我們研究jdk或者某些框架的原碼裡邊有很多地方都會用到位運算
2、分類
雙目運算子:連線兩個運算元
&: 按位與 規則: 兩個同為1時候才為1
|: 按位或 規則: 兩個中只要有一個為1結果就是1
^: 按位異或 規則: 兩個中不同為1 相同為0
單目運算子: 運算元只有一個
~: 按位取反 規則: 1變0,0變1(包括符號位在內)
注意:位運算連線的運算元是——數值型別(二進位制)
位運算表示式的結果是——數值型別
1
按位與
&
規則
:
兩個同為1時候才為1
// 3 & 4 的結果
分析
:
/*
1 要先轉換成二進位制位 並且全是二進位制的補碼形式! //正數原反補 一樣
3 補碼 0b00000000000000000000000000000011
4 補碼 0b00000000000000000000000000000100
2 操作 ——————————————————
結果0b00000000000000000000000000000000 //十進位制也就是0
*/
int
a
=
3
&
4
;
System
。
out
。
println
(
a
);
2
按位或
|
規則
:
兩個中只要有一個為1結果就是1
// 3 | 4 的結果
/*
1 要先轉換成二進位制位 並且全是二進位制的補碼形式! //正數原反補 一樣
3 補碼 0b00000000000000000000000000000011
4 補碼 0b00000000000000000000000000000100
2 操作 ——————————————————-
結果 0b00000000000000000000000000000111 //十進位制也就是7
*/
int
a
=
3
|
4
;
System
。
out
。
pirintln
(
a
);
3
按位異或
^
規則
:
兩個中不同為1
相同為0
// 3 ^ 4 的結果
/*
1 要先轉換成二進位制位 並且全是二進位制的補碼形式! //正數原反補 一樣
3 補碼 0b00000000000000000000000000000011
4 補碼 0b00000000000000000000000000000100
2 操作 ——————————————————-
結果 0b00000000000000000000000000000111 //十進位制也就是7
*/
int
a
=
3
^4
;
System
。
out
。
println
(
a
);
一個數據對相同的資料異或兩次其值不變
a兩次異或b結果不變
a^b^b
==
a
int
a
=
3
;
int
b
=
4
;
System
。
out
。
println
(
a^b^b
);
/*
3 補碼 0b00000000000000000000000000000011
4 補碼 0b00000000000000000000000000000100
—————————————————————— 第一次異或不同為1 相同為0
結果 0b00000000000000000000000000000111
4 0b00000000000000000000000000000100
——————————————————————第二次異或不同為1 相同為0
0b00000000000000000000000000000011 //補碼 3
*/
4
按位取反
1
變0
,
0
變1
(
包括符號位在內
)
// ~3 的結果
/*
1 要先轉換成二進位制位 並且全是二進位制的補碼形式! //正數原反補 一樣
3 補碼 0b00000000000000000000000000000011
2 操作 ——————————————————-補碼按位取反還是補碼
結果 0b11111111111111111111111111111100 //補碼
//首先符號位是1 是負數 其次 這是補碼 要算反碼
現在已知道補碼求原碼
補碼:0b11111111111111111111111111111100
- 1
————————————————————-
反碼:0b11111111111111111111111111111011 //符號位不變 取反
原碼:0b10000000000000000000000000000100 //原碼 十進位制顯示 -4
*/
int
a
=
~3
;
System
。
out
。
println
(
a
);
5
互為取反
int
a
=
~6
;
System
。
out
。
println
(
a
);
//-7
//0b00000000000000000000000000000110 +6
//0b11111111111111111111111111111001 取反:結果是負數 是補碼
//0b11111111111111111111111111111000 反碼
//0b10000000000000000000000000000111 原碼:-(1+2+4)=-7
//6取反就是-7 那麼-7取反呢
System
。
out
。
println
(
~
-
7
);
//6
//0b10000000000000000000000000000111 -7原碼
//0b11111111111111111111111111111000 -7反碼
//0b11111111111111111111111111111001 -7補碼
//0b00000000000000000000000000000110 -7取反 結果是整數 2+4=6
3、案例:資料互動
需求:
已知兩個整數變數a = 10,b = 20,使用程式實現這兩個變數的資料交換;不允許出現第三方變數
思路:
使用異或,一個數據對相同的資料異或兩次其值不變
程式碼:
public
static
void
main
(
String
[]
args
) {
int
a
=
10
;
int
b
=
20
;
a
=
a
^
b
;
//a = 10 ^ 20;
b
=
a
^
b
;
//b = 10 ^ 20 ^ 20;
a
=
a
^
b
;
//a = 10 ^ 20 ^ 10;
System
。
out
。
println
(
a
);
System
。
out
。
println
(
b
);
}
注意:
以後編碼中,更多的還是選擇定義第三方變數
四、位移運算子
1、分類
位移運算子的分類
<<
:
左移
規則
:
讓運算元乘以2的n次冪
n是移動的位數
>>
:
右移
規則
:
讓運算元除以2的n次冪
n是移動的位數
>>>
:
無符號右移
規則
:
讓運算元除以2的n次冪
n是移動的位數xxxxxxxxxx
#
四、位移運算子##
1
、分類位移運算子的分類
<<
:
左移
規則
:
讓運算元乘以2的n次冪
n是移動的位數
>>
:
右移
規則
:
讓運算元除以2的n次冪
n是移動的位數
>>>
:
無符號右移
規則
:
讓運算元除以2的n次冪
n是移動的位數java
2、左位移操作 <<
規則
:
讓運算元乘以2的n次冪
n是移動的位數
左邊符號位丟棄
右邊補0
格式
:
運算元
<<
往左位移的位數
(
操作的是二進位制位
)
int
a
=
3
<<
2
;
//運算元 3*2^2 =3*4=12
System
。
out
。
println
(
a
);
/*
補碼 0b00000000000000000000000000000011
位移 0b000000000000000000000000000011
右邊空出兩位補0 左邊的兩位就被擠掉了
結果:0b00000000000000000000000000001100
符號位是0 是正數 原反補一致
//十進位制表示 12
*/
負數左移
int
b
=-
3
<<
2
;
System
。
out
。
println
(
b
);
/*
-3
原碼 0b10000000000000000000000000000011
反碼 0b11111111111111111111111111111100
補碼 0b11111111111111111111111111111101
左移 0b111111111111111111111111111101
補齊:0b11111111111111111111111111110100 補碼 -1
反碼 0b11111111111111111111111111110011
原碼 0b10000000000000000000000000001100 原碼 1100=-12
*/
int
i
=
21
;
//00000000000000000000000000010101
int
x1
=
i
<<
2
;
//21*2^2=84 //00000000000000000000000001010100 =4+16+64=84
int
x2
=
i
<<
3
;
//21*2^3=168 //00000000000000000000000010101000 =8+32+128=168
int
x3
=
i
<<
26
;
//21*2^26=1409286144 //01010100000000000000000000000000
int
x4
=
i
<<
27
;
//21*2^27=-1476395008 //10101000000000000000000000000000 變成負數了
int
i
=-
21
;
//10000000000000000000000000010101 原碼
//11111111111111111111111111101010 反碼
//11111111111111111111111111101011 補碼(反碼+1)
int
x1
=
i
<<
2
;
//-21*2^2=-84
//11111111111111111111111111101011 補碼
//11111111111111111111111110101100 位移補0 求原碼
//11111111111111111111111110101011 反碼
//10000000000000000000000001010100 原碼 結果是 4+16+64=84 符號是1 結果是-84
int
x2
=
i
<<
3
;
//-21*2^3=-168
int
x3
=
i
<<
26
;
//-21*2^26=-1409286144
int
x4
=
i
<<
27
;
//-21*2^27=1476395008
//11111111111111111111111111101011 補碼
//01011000000000000000000000000000 位移27位 補0 符號位0 變成正數
結論
:
<<
在一定的範圍內每向左移動移動一位相當於
*
2
最高效的計算
2
*
8
2
<<
3
或者
8
<<
1
3、右位移操作 >>
規則
:
讓運算元除以2的n次冪
n是移動的位數
格式
:
運算元
>>
往右位移的位數
(
操作的是二進位制位
)
int
a
=
32
>>
2
;
//運算元 32/2^2 =32/4=8
System
。
out
。
println
(
a
);
/*
32補碼 0b00000000000000000000000000100000
位移 0b000000000000000000000000001000
左邊邊空出兩位補0(符號位是啥補啥) 右邊的兩位就被擠掉了
結果:0b00000000000000000000000000001000
符號位是0 是正數 原反補一致
//十進位制表示 8
*/
負數情況
int
b
=-
32
>>
2
;
//運算元 -32/2^2 =-32/4=-8
System
。
out
。
println
(
a
);
/*
-32原碼: 0b10000000000000000000000000100000
取反
反碼: 0b11111111111111111111111111011111 (符號位不變 其他1變0 0變1)
+ 1
補碼: 0b11111111111111111111111111100000
右位移: 0b111111111111111111111111111000
左邊邊空出兩位補1(符號位是啥補啥 現在符號位是1 補1) 右邊的兩位就被擠掉了
結果補碼:0b11111111111111111111111111111000 //這個也是補碼
當輸出顯示的時候要回推顯示原碼形式
0b11111111111111111111111111111000
- 1
反碼:0b11111111111111111111111111110111
原碼:0b10000000000000000000000000001000 //十進位制表示 -8
*/
int
i
=
21
;
//00000000000000000000000000010101
int
x1
=
i
>>
2
;
//00000000000000000000000000000101 1+4=5
int
x2
=
i
>>
3
;
//00000000000000000000000000000010 2=2;
int
x3
=
i
>>
26
;
//00000000000000000000000000000000 0
int
x4
=
i
>>
27
;
//00000000000000000000000000000000 0
int
i
=-
21
;
//10000000000000000000000000010101 原碼
//11111111111111111111111111101010 反碼
//11111111111111111111111111101011 補碼(反碼+1)
int
x1
=
i
>>
2
;
//11111111111111111111111111101011 補碼
//11111111111111111111111111111010 右移2位 符號位是啥補啥 已知補碼求原碼先求反碼(補碼-1)
//11111111111111111111111111111001 反碼
//10000000000000000000000000000110 //結果是 2+4=6 符號位是1是負數 =-6
int
x2
=
i
>>
3
;
//-3
int
x3
=
i
>>
26
;
//-1
int
x4
=
i
>>
27
;
//-1
//11111111111111111111111111101011 補碼
//11111111111111111111111111111111 右移27位 符號位是啥補啥 已知補碼求原碼先求反碼(補碼-1)
//11111111111111111111111111111110 反碼
//10000000000000000000000000000001 結果是 1 符號位是1是負數 =-1
結論
:
>>
在一定的範圍內每向右移動移動一位相當於
/
2
4、無符號右移: >>>