聊聊java中的二进制问题

简介: java中的进制也算是面试中经常会遇到的一个知识点,不管是计算问题,还是涉及到的基础知识。因此这篇文章对其进行一个整理。主要参考了慕课网上的视频,特在此说明。不管是你初学者还是工作中,又或者是找工作中。本文都能对你有所帮助。本篇文章主要解决以下几个问题:1、二进制的历史2、java中的进制转换3、java中的移位运算4、数据大小端问题5、进制在java中的使用下面我们就针对这些问题,来分析一下java中的进制。

一、二进制的历史


这一小节优点闲扯淡的感觉,要说二进制的历史其实可以追述到一个大数学家莱布尼茨。当时有一个法国传教士白晋来到了咱们中国,走的时候带走了中国的一本古书《易经》,白晋回到德国之后,莱布尼茨就看了《易经》里面的伏羲八卦图。突然灵机一动(动没动是我瞎猜的),就发明了二进制。不管不管怎么样二进制的由来或多或少都收到了中国伏羲八卦图的影响。

v2-511c0d7eee4e8536aa25011d6d72c85d_1440w.jpg这就是伏羲八卦图,怎么想到的我也不知道,不过你仔细观察看一下,最上面的乾卦三横实线,顺时针转动,实线变虚线。你可以想象成从000到111的变化。


二、java中的进制转换


其实常见的进制转换主要有以下几种:

(1)十进制转二进制

(2)十进制转八进制

(3)十进制转十六进制

(4)二进制转十进制

(5)八进制转十进制

(6)十六进制转十进制


十进制的范围就是0-9,二进制的范围是0-1,八进制的范围是0-7,十六进制的范围是0-f。java提供了工具类来实现进制的转换。因此在笔试的时候你可以直接使用。

public class Test{
    public static void main(String[] args) {
        int a=20;
        //十进制转其他进制
        String a_to_hex=Integer.toHexString(a);
        String a_to_octal=Integer.toOctalString(a);
        String a_to_binary=Integer.toBinaryString(a);
        //其他进制转十进制
        String hex_to_10 = Integer.valueOf("f",16).toString();
        String octal_to_10 = Integer.valueOf("17",8).toString();
        String binary_to_10 = Integer.valueOf("101",2).toString();  
        System.out.println("十进制20转二进制:"+a_to_hex);
        System.out.println("十进制20转八进制:"+a_to_octal);
        System.out.println("十进制20转十六进制:"+a_to_binary);
        System.out.println("二进制101转十进制:"+binary_to_10);
        System.out.println("八进制17转十进制:"+octal_to_10);
        System.out.println("十六进制f转十进制:"+hex_to_10); 
    }
}

然后我们运行一下就可以直接看到结果了。比较简单。


三、java中的位操作


java中为了使得运算方便而且快速,可以直接进行位操作进行运算。常见的有以下六种:

v2-5c4fe80f7ab20c14538e14c72cacc408_1440w.jpg

v2-70e26a24545bd63c0e454db51311cc30_1440w.jpg

v2-42eaae943b4fd4ceecb4934c8dd4f4b7_1440w.jpg

v2-46c5e3cf8d7fcaafdecc154fd62a2e70_1440w.jpg

v2-a8d99e10844ad2cca7b63cb489cbc773_1440w.jpg

v2-e4eb7a3521b85a0e8becbabac29537ed_1440w.jpgv2-ac00be6509c21a7565d8544acf92ca60_1440w.jpg

上面这几张图,主要是概念用法。下面我们看位运算的几个应用:


(1) 判断int型变量a是奇数还是偶数 a&1 = 0 偶数 a&1 = 1 奇数

(2) 取int型变量a的第k位 (k=0,1,2……sizeof(int)),即a>>k&1 (先右移再与1)

(3) 将int型变量a的第k位清0,即a=a&~(1<<k) (10000 取反后为00001 )

(4) 将int型变量a的第k位置1,即a=a|(1<<k)

(5) int型变量循环左移k次,即a=a<<k|a>>16-k (设sizeof(int)=16)

(6) int型变量a循环右移k次,即a=a>>k|a<<16-k (设sizeof(int)=16)

(7)对于一个数 x >= 0,判断是不是2的幂。

boolean power2(int x){
    return ( (x&(x-1))==0) && (x!=0);
}

(8)不用temp交换两个整数

void swap(int x , int y){
    x ^= y;
    y ^= x;
    x ^= y;
}

(9)计算绝对值

int abs( int x ){
    int y ;
    y = x >> 31 ;
    return (x^y)-y ; 
}

(10)取模运算转化成位运算 (在不产生溢出的情况下)

a % (2^n) 等价于 a & (2^n - 1)


(11)乘法运算转化成位运算 (在不产生溢出的情况下)

a * (2^n) 等价于 a<< n


四、大小端问题


1、小端法(Little-Endian)


低位字节排放在内存的低地址端即该值的起始地址,高位字节排放在内存的高地址端


2、高端法(Big-Endian)


高位字节排放在内存的低地址端即该值的起始地址,低位字节排放在内存的高地址端

为什么会有大小端呢?


在计算机中,每个地址单元都对应着一个字节(8bit)数据。java中int类型占据4个字节,long占据8个字节,计算机是由32位和64位之分的,处理器因此也就是有32位和64位之分,现在有一个32位的处理器,突然来了一个8字节64位的数据,这时候处理器就不能一下子处理了,于是就要把8个字节的数据分开存放,这一存放就要分出个高地了,谁在前面谁在后面的问题。


比如说下面的这个例子(前几天做的一道面试原题):

32bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x2000开始存放)为:

v2-68fadd9fbea1125490819e5d8a6eb2c8_1440w.png

因此这就是0x87654321存放。

而在Big-endian模式CPU内存中的存放方式则为:

v2-1643d87401495e74f5742e2cee973eaf_1440w.png

这个在大端模式下是正常的。牢记牢记。


五、进制的使用场景


上面在介绍的时候其实说了一部分,但是这里再简单的举个例子,最常见的例子就是序列化。我们知道客户端我们可以使用java语言编写,但是服务器就不一定了,可能是java,也可能是C++,这时候传输数据怎么办呢?这俩语言之间又相互不认识。这时候客户端java就可以把我们的数据切分序列化成二进制数,二进制数计算机到哪都能认识,这时候把二进制数发送到服务端,服务端按照一定的规则反序列化就OK了。


对于字符串来说那就是太简单了,我们直接getBytes就可以转化成byte。但是对于int该怎么办呢?我们给出一个例子,其他的可以自己测试一下。

public class Test{
    public static void main(String[] args) {
        byte[] result = int2byte(8421);
        for(byte i :result) {
            System.out.println(i);
        }
    }
    public static byte[] int2byte(int value) {
        //int是4个字节就初始化为4
        byte[] array = new byte[4];
        for(int i=0;i<4;i++) {
            array[i]= (byte)((value >> i*8) & 0xff);
        }
        return array;
    }
}

OK,进制中常见的问题先列出这么多,欢迎批评指正。



相关文章
|
1月前
|
Java
Java中整数(负数)的二进制表示
Java中整数(负数)的二进制表示
|
3月前
|
Java
Java打印二进制
Java打印二进制
42 0
|
1月前
|
Java
Java中将一个数转化为二进制
Java中将一个数转化为二进制
25 0
|
1月前
|
算法 Java 数据处理
Java:将一个数转化为二进制
Java:将一个数转化为二进制
|
1月前
|
机器学习/深度学习 Java 程序员
Java基础之二进制,八进制,十进制,十六进制相互转换
Java基础之二进制,八进制,十进制,十六进制相互转换
|
3月前
|
算法 C++ Java
Java每日一练(20230423) 数组元素统计、杨辉三角II、二进制求和
Java每日一练(20230423) 数组元素统计、杨辉三角II、二进制求和
29 0
Java每日一练(20230423) 数组元素统计、杨辉三角II、二进制求和
|
7月前
|
存储 Java
湖南大学Java编程题3. 计算int型二进制1的个数
湖南大学Java编程题3. 计算int型二进制1的个数
|
11月前
java202303java学习笔记第二十九天 十进制转换为二进制1
java202303java学习笔记第二十九天 十进制转换为二进制1
134 0
|
11月前
|
Java 编译器
在Java中关于二进制、八进制、十六进制的辨析
在Java中关于二进制、八进制、十六进制的辨析
108 0
|
机器学习/深度学习 算法 Java
二进制中1的个数(剑指offer 15)Java位运算
编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为 汉明重量).)。