以下のエディターは、Java のバイナリおよび基本的な ビット操作 について詳しく説明する記事を提供します。編集者はこれがとても良いと思ったので、参考として共有します。編集者と一緒に見てみましょう
バイナリは、コンピューティング技術で広く使用されている数値体系です。バイナリデータとは、0と1の2桁で表される数値です。その基数は 2、キャリー ルールは「2 対 1」、借用ルールは「1 を借りて 2 に等しい」です。これは 18 世紀のドイツの数学哲学の巨匠ライプニッツによって発見されました。現在のコンピュータシステムは基本的に2進法を採用しており、データは主に2の補数符号の形でコンピュータ内に格納される。コンピューターの 2 進法は非常に小さなスイッチであり、「オン」は 1 を表し、「オフ」は 0 を表します。
では、Java ではバイナリはどのように見えるのでしょうか?その神秘のベールを一緒に解き明かしましょう。
1. Java の組み込み 10 進数変換
10 進数から 2 進数へ、および 2 進数から 10 進数へ変換する基本的な計算方法については、ここでは説明しません。
Java には、さまざまなベースの変換に役立つメソッドがいくつか組み込まれています。以下の図に示すように (整数整形を例として、他の型も同じです):
1、10 進数から他の基数に変換:
二进制:Integer.toHexString(int i); 八进制:Integer.toOctalString(int i); 十六进制:Integer.toBinaryString(int i);
2、他の基数から 10 進数に変換:
二进制:Integer.valueOf("0101",2).toString; 八进制:Integer.valueOf("376",8).toString; 十六进制:Integer.valueOf("FFFF",16).toString;
3. Integer クラスの parseInt() メソッドと valueOf() メソッドを使用して、他の基数を 10 進数に変換します。
違いは、parseInt() メソッドの戻り値が int 型であるのに対し、valueOf() メソッドの戻り値は Integer オブジェクトであることです。
2. 基本的なビット演算
2進数は10進数と同じように加算、減算、乗算、除算ができますが、より単純な演算方法であるビット演算もあります。たとえば、コンピュータの int 型のサイズは 32 ビットであり、32 ビットの 2 進数で表現できるため、ビット演算を使用して int 型の値を計算できます。 もちろん、一部の計算には通常の方法を使用することもできます。ここでは主にビット演算の方法を紹介します。ビット演算には、通常の演算方法とは比較にならない威力があることがわかります。ビット演算のその他の応用については、次のブログ投稿「マジカル ビット演算」に移動してください
まず、ビット演算の基本的な 演算子 を見てみましょう:
利点:
特定の状況下では、計算が簡単で高速で広くサポートされています
算術メソッドを使用すると、遅くて論理的に複雑です
ビット演算は1つの言語に限定されず、コンピューターの基本的な計算方法です
>>> ;>>>> ;>>>>>>>>>>>>>>>>>>>>> ;>>>> ;>>>>>>>>>>>>>>>>>>>>> ;>>
(1) ビット単位の AND &
2 つのビットが両方とも 1 の場合、結果は 1
0&0=0; 1&1=1; 例: 51&5、つまり 0011 0011 & 0000 0101 =0000 0001 したがって、51&5=1.
特別な使い方 (1) クリア。セルをゼロにクリアしたい場合は、バイナリ ビットがすべて 0 であっても、ビットがすべて 0 である値と AND 演算するだけで、結果は 0 になります。
(2) 数値内の指定された位置を取得します。
例: X=10101110 と仮定し、X の下 4 桁を取得し、次を使用します。
方法: x に取りたいビットに対応する数値を見つけます。その数値の対応するビットは 1 で、残りのビットは 0 です。この数値と x の AND 演算を実行して、x の指定されたビットを取得します。
(2) ビット単位の OR |どちらか 1 つが 1 である限り、結果は 1 になります。
0|0=0; 1|0=1; 1|1=1;
例: 51|5 は 0000 0101 =0011 0111 |
特別な使用法は、データの特定の位置に 1 を設定するためによく使用されます。
方法: 1 に設定される x のビットに対応する数値を見つけます。数値の対応するビットは 1 で、残りのビットは 0 です。この数値は x に対する相対値であるか、x 内の特定の位置を 1 に設定します。(3) 排他的 OR^
対応する 2 つのビットが「排他的」(異なる値) の場合、ビットの結果は 1 になり、それ以外の場合は 0
0^0=0 になります。 1; 1 ^0=1; 1^1=0;例: 51^5 は 0011 0011 ^ 0000 0101 =0011 0110 したがって、51^5=54 (1 ) 1 XOR と同じ、特定のビットを反転します方法:找一个数,对应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 (五)左移<< 将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0) 例如: 若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2。 例如: (六)右移>> 将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。若右移时舍高位不是1(即不是负数),操作数每右移一位,相当于该数除以2。 左补0还是补1得看被移数是正还是负。 例如: (七)无符号右移运算>>> 各个位向右移指定的位数,右移后左边空出的位用零来填充,移除右边的位被丢弃。 例如: 上述提到的负数,他的二进制位表示和正数略有不同,所以在位运算的时候也与正数不同。 负数以其正数的补码形式表示! 以上述的-14为例,来简单阐述一下原码、反码和补码。 原 码 一个整数按照绝对值大小转化成的二进制数称为原码 例如:00000000 00000000 00000000 00001110 是14的原码。 反 码 将二进制数按位取反,所得到的新二进制数称为原二进制数的反码。 例如:将00000000 00000000 00000000 00001110 每一位取反, 得11111111 11111111 11111111 11110001 注意:这两者互为反码 补 码 反码加1称为补码 现在我们得到-14的二进制表示,现在将它左移 分析:这个二进制的首位为1,说明是补码形式,现在我们要将补码转换为原码(它的正值) 跟原码转换为补码相反,将补码转换为原码的步骤: 补码减1得到反码:(11000111)前24位为1,此处省略 三、Java中进制运算 Java中二进制用的多吗? 平时开发中“进制转换”和“位操作”用的不多,Java处理的是高层。 在跨平台中用的较多,如:文件读写,数据通信。 来看一个场景: 如果客户机和服务器都是用Java语言写的程序,那么当客户机发送对象数据,我们就可以把要发送的数据序列化seriapzable,服务器端得到序列化的数据之后就可以反序列化,读出里面的对象数据。 随着客户机访问量的增大,我们不考虑服务器的性能,其实一个可行的方案就是把服务器的Java语言改成C语言。 C语言作为底层语言,反映速度都比Java语言要快,而此时如果客户端传递的还是序列化的数据,那么服务器端的C语言将无法解析,怎么办呢?我们可以把数据转为二进制(0,1),这样的话服务器就可以解析这些语言。 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 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 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> (一)数据类型转为字节 例如: 第一个(低端)字节: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.字符串->字节数组 2.字节数组->字符串 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 两种类型转化为字节的方法都介绍了,下面写个小例子检验一下: 运行结果: 以上がJava メディアン演算とバイナリの詳細なグラフィックとテキストの説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。~1=0 ;~0=1
2<<1 =4 10<<1=100
11(1011)<<2= 0010 1100=22
11(00000000 00000000 00000000 1011)整形32bit
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
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
11111111 11111111 11111111 11110001 +1=
11111111 11111111 11111111 11110010
-14(11111111 11111111 11111111 11110010)<<2 =
11111111 11111111 11111111 11001000
=?
反码取反得到原码(即该负数的正值)(00111000)
计算正值,正值为56
取正值的相反数,得到结果-56
结论:-14<<2 = -56int型8143(00000000 00000000 00011111 11001111)
=>byte[] b=[-49,31,0,0]
String s;byte[] bs=s.getBytes();
Byte[] bs=new byte[int];String s =new String(bs);或String s=new String(bs,encode);//encode指编码方式,如utf-8
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);
}
}