一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 詳談Java中的二進制及基本的位運算

詳談Java中的二進制及基本的位運算

2020-12-03 08:59Java教程網 Java教程

下面小編就為大家帶來一篇詳談Java中的二進制及基本的位運算。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

二進制是計算技術中廣泛采用的一種數制。二進制數據是用0和1兩個數碼來表示的數。它的基數為2,進位規則是“逢二進一”,借位規則是“借一當二”,由18世紀德國數理哲學大師萊布尼茲發現。當前的計算機系統使用的基本上是二進制系統,數據在計算機中主要是以補碼的形式存儲的。計算機中的二進制則是一個非常微小的開關,用“開”來表示1,“關”來表示0。

那么java中的二進制又是怎么樣的呢?讓我們一起來揭開它神秘的面紗吧。

一、java內置的進制轉換

有關十進制轉為二進制,和二進制轉為十進制這種基本的運算方法這里就不展開講了。

在java中內置了幾個方法來幫助我們進行各種進制的轉換。如下圖所示(以integer整形為例,其他類型雷同):

詳談Java中的二進制及基本的位運算

1,十進制轉化為其他進制:

?
1
2
3
二進制:integer.tohexstring(int i);
八進制:integer.tooctalstring(int i);
十六進制:integer.tobinarystring(int i);

2,其他進制轉化為十進制:

?
1
2
3
二進制:integer.valueof("0101",2).tostring;
八進制:integer.valueof("376",8).tostring;
十六進制:integer.valueof("ffff",16).tostring;

3,使用integer類中的parseint()方法和valueof()方法都可以將其他進制轉化為10進制。

不同的是parseint()方法的返回值是int類型,而valueof()返回值是integer對象。

二、基本的位運算

二進制可以和十進制一樣加減乘除,但是它還有更簡便的運算方式就是——位運算。比如在計算機中int類型的大小是32bit,可以用32位的二進制數來表示,所以我們可以用位運算來對int類型的數值進行計算,當然你也可以用平常的方法來計算一些數據,這里我主要為大家介紹位運算的方法。我們會發現位運算有著普通運算方法不可比擬的力量。更多位運算應用請轉移到我下篇博文《神奇的位運算》

首先,看一下位運算的基本操作符:

詳談Java中的二進制及基本的位運算

優點:

特定情況下,計算方便,速度快,被支持面廣
如果用算數方法,速度慢,邏輯復雜
位運算不限于一種語言,它是計算機的基本運算方法

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

(一)按位與&

兩位全為1,結果才為1

0&0=0;0&1=0;1&0=0;1&1=1

例如:51&5 即0011 0011 & 0000 0101 =0000 0001 因此51&5=1.

特殊用法

(1)清零。如果想將一個單元清零,即使其全部二進制位為0,只要與一個各位都是零的數值相與,結果為零。

(2)取一個數中指定位。

例如:設x=10101110,取x的低四位,用x&0000 1111=0000 1110即可得到。

方法:找一個數,對應x要取的位,該數的對應位為1,其余位為零,此數與x進行“與運算”可以得到x中的指定位。

(二)按位或 |

只要有一個為1,結果就為1。

0|0=0; 0|1=1;1|0=1;1|1=1;

例如:51|5 即0011 0011 | 0000 0101 =0011 0111 因此51|5=55

特殊用法

常用來對一個數據的某些位置1。

方法:找到一個數,對應x要置1的位,該數的對應位為1,其余位為零。此數與x相或可使x中的某些位置1。

(三)異或 ^

兩個相應位為“異”(值不同),則該位結果為1,否則為0

0^0=0; 0^1=1; 1^0=1; 1^1=0;

例如:51^5 即0011 0011 ^ 0000 0101 =0011 0110 因此51^5=54

特殊用法

(1) 與1相異或,使特定位翻轉

方法:找一個數,對應x要翻轉的位,該數的對應為1,其余位為零,此數與x對應位異或即可。

例如:x=1010 1110,使x低四位翻轉,用x^0000 1111=1010 0001即可得到。

(2) 與0相異或,保留原值

例如:x^0000 0000 =1010 1110

(3)兩個變量交換值

1.借助第三個變量來實現

c=a;a=b;b=c;

2.利用加減法實現兩個變量的交換

a=a+b;b=a-b;a=a-b;

3.用位異或運算來實現,也是效率最高的

原理:一個數異或本身等于0 ;異或運算符合交換律

a=a^b;b=a^b;a=a^b

(四)取反與運算~

對一個二進制數按位取反,即將0變為1,1變0

~1=0 ;~0=1

(五)左移<<

將一個運算對象的各二進制位全部左移若干位(左邊的二進制位丟棄,右邊補0)

例如: 2<<1 =4 10<<1=100

若左移時舍棄的高位不包含1,則每左移一位,相當于該數乘以2。

例如:

11(1011)<<2= 0010 1100=22

11(00000000 00000000 00000000 1011)整形32bit

(六)右移>>

將一個數的各二進制位全部右移若干位,正數左補0,負數左補1,右邊丟棄。若右移時舍高位不是1(即不是負數),操作數每右移一位,相當于該數除以2。

左補0還是補1得看被移數是正還是負。

例如:4>>2=4/2/2=1

-14(即1111 0010)>>2 =1111 1100=-4

(七)無符號右移運算>>>

各個位向右移指定的位數,右移后左邊空出的位用零來填充,移除右邊的位被丟棄。

例如:-14>>>2

(即11111111 11111111 11111111 11110010)>>>2

=(00111111 11111111 11111111 11111100)=1073741820

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

上述提到的負數,他的二進制位表示和正數略有不同,所以在位運算的時候也與正數不同。

負數以其正數的補碼形式表示!

以上述的-14為例,來簡單闡述一下原碼、反碼和補碼。

原 碼

一個整數按照絕對值大小轉化成的二進制數稱為原碼

例如:00000000 00000000 00000000 00001110 是14的原碼。

反 碼

將二進制數按位取反,所得到的新二進制數稱為原二進制數的反碼。

例如:將00000000 00000000 00000000 00001110 每一位取反,

得11111111 11111111 11111111 11110001

注意:這兩者互為反碼

補 碼

反碼加1稱為補碼

11111111 11111111 11111111 11110001 +1=

11111111 11111111 11111111 11110010

現在我們得到-14的二進制表示,現在將它左移

-14(11111111 11111111 11111111 11110010)<<2 =

11111111 11111111 11111111 11001000

=?

分析:這個二進制的首位為1,說明是補碼形式,現在我們要將補碼轉換為原碼(它的正值)

跟原碼轉換為補碼相反,將補碼轉換為原碼的步驟:

補碼減1得到反碼:(11000111)前24位為1,此處省略
反碼取反得到原碼(即該負數的正值)(00111000)
計算正值,正值為56
取正值的相反數,得到結果-56
結論:-14<<2 = -56

三、java中進制運算

java中二進制用的多嗎?

平時開發中“進制轉換”和“位操作”用的不多,java處理的是高層。

在跨平臺中用的較多,如:文件讀寫,數據通信。

來看一個場景:

詳談Java中的二進制及基本的位運算

如果客戶機和服務器都是用java語言寫的程序,那么當客戶機發送對象數據,我們就可以把要發送的數據序列化seriapzable,服務器端得到序列化的數據之后就可以反序列化,讀出里面的對象數據。

隨著客戶機訪問量的增大,我們不考慮服務器的性能,其實一個可行的方案就是把服務器的java語言改成c語言。

c語言作為底層語言,反映速度都比java語言要快,而此時如果客戶端傳遞的還是序列化的數據,那么服務器端的c語言將無法解析,怎么辦呢?我們可以把數據轉為二進制(0,1),這樣的話服務器就可以解析這些語言。

詳談Java中的二進制及基本的位運算

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

java中基本數據類型有以下四種:

int數據類型:byte(8bit,-128~127)、short(16bit)、int(32bit)、long(64bit)

float數據類型:單精度(float,32bit ) 、雙精度(double,64bit)

boolean類型變量的取值有true、false(都是1bit)

char數據類型:unicode字符,16bit

對應的類類型:

integer、float、boolean、character、double、short、byte、long

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

(一)數據類型轉為字節

例如:int型8143(00000000 00000000 00011111 11001111)

=>byte[] b=[-49,31,0,0]

第一個(低端)字節:8143>>0*8 & 0xff=(11001111)=207(或有符號-49)

第二個(低端)字節:8143>>1*8 &0xff=(00011111)=31

第三個(低端)字節:8143>>2*8 &0xff=00000000=0

第四個(低端)字節:8143>>3*8 &0xff=00000000=0

我們注意到上面的(低端)是從右往左開始的,那什么是低端呢?我們從大小端的角度來說明。

小端法(pttle-endian)

位字節排放在內存的地址端即該值的起始地址,位字節排位在內存的地址端

大端法(big-endian)

位字節排放在內存的地址端即該值的起始地址,位字節排位在內存的地址端

為什么會有大小端模式之分呢?

這是因為在計算機系統中,我們是以字節為單位的,每個地址單元都對應著一個字節,一個字節為8bit。但是在c語言中除了8bit的char之外,還有16bit的short型,32bit的long型(要看具體的編譯器),另外,對于位數大于8位的處理器,例如16位或者32位的處理器,由于寄存器寬度大于一個字節,那么必然存在著一個如果將多個字節安排的問題。因此就導致了大端存儲模式和小端存儲模式。例如一個16bit的short型x,在內存中的地址為0x0010,x的值為0x1122,那么0x11為高字節,0x22為低字節。對于大端模式,就將0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,剛好相反。我們常用的x86結構是小端模式,而keil c51則為大端模式。很多的arm,dsp都為小端模式。有些arm處理器還可以由硬件來選擇是大端模式還是小端模式。

例如:32bit的數0x12 34 56 78(十二進制)

在big-endian模式cpu的存放方式(假設從地址0x4000開始存放)為

內存地址

0x4000

0x4001

0x4002

0x4003

存放內容

0x78

0x56

0x34

0x12

在pttle-endian模式cpu的存放方式(假設從地址0x4000開始存放)為

內存地址

0x4000

0x4001

0x4002

0x4003

存放內容

0x12

0x34

0x56

0x78

(二)字符串轉化為字節

1.字符串->字節數組

?
1
2
string s;
byte[] bs=s.getbytes();

2.字節數組->字符串

?
1
2
3
byte[] bs=new byte[int];
string s =new string(bs);或
string s=new string(bs,encode);//encode指編碼方式,如utf-8

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

兩種類型轉化為字節的方法都介紹了,下面寫個小例子檢驗一下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
pubpc class btyetest {
 /*
 * int整型轉為byte字節
 */
 pubpc static byte[] inttobtyes(int in){
 byte[] arr=new byte[4];
 for(int i=0;i<4;i++){
  arr[i]=(byte)((in>>8*i) & 0xff);
 }
 return arr;
 }
 /*
 * byte字節轉為int整型
 */
 pubpc static int bytestoint(byte[] arr){
 int sum=0;
 for(int i=0;i<arr.length;i++){
  sum+=(int)(arr[i]&0xff)<<8*i;
 }
 return sum;
 }
 pubpc static void main(string[] args) {
 // todo auto-generated method stub
 byte[] arr=inttobtyes(8143);
 for(byte b:arr){
  system.out.print(b+" ");
 }
 system.out.println();
 system.out.println(bytestoint(arr));
 
 //字符串與字節數組
 string str="云開的立夏de博客園";
 byte[] barr=str.getbytes();
 
 string str2=new string(barr);
 system.out.println("字符串轉為字節數組:");
 for(byte b:barr){
  system.out.print(b+" ");
 
 }
 system.out.println();
 
 system.out.println("字節數組換位字符串:"+str2);
 
  
 }
 
}

運行結果:

詳談Java中的二進制及基本的位運算

以上這篇詳談java中的二進制及基本的位運算就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品一区二区国语对白 | 2021国产精品露脸在线 | 国产一级毛片外aaaa | 亚洲精品一区二区久久久久 | 天天天天天干 | 日韩在线一区二区三区 | 久热人人综合人人九九精品视频 | 蜜桃视频一区二区三区四区 | 啪一啪在线视频 | 国产宅男 | 17个农民工婉莹第一部 | 亚洲性视频在线观看 | 亚洲成人黄色 | 污污的动态图合集 | 四虎精品永久在线网址 | 国产高清露脸学生在线观看 | 我的青梅竹马是消防员2季未增删免费 | 亚洲精品91 | 深夜福利在线播放 | 欧美日韩一区二区三区在线观看 | 99久久精品99999久久 | 亚久久伊人精品青青草原2020 | 午夜精品久久久久久 | 2021日本三级理论影院 | 天堂俺去俺来也www久久婷婷 | 毛片群 | 粉嫩尤物在线456 | 亚洲国产99在线精品一区二区 | 欧美一区二区三区免费观看视频 | 国产美女亚洲精品久久久综合91 | 欧美又黄又激烈真实床戏 | 欧美精品三区 | 国产资源站 | 明星h文集合短篇小说 | 扒开放荡老师裙子猛烈的进入 | 五月九九| 韩国免费视频 | 免费操比视频 | 日本一道一区二区免费看 | 欧亚专线欧洲m码可遇不可求 | 91高清国产视频 |