美文网首页
java中int与byte、long与byte之间的互相转换

java中int与byte、long与byte之间的互相转换

作者: 为爱放弃一切 | 来源:发表于2019-09-15 13:28 被阅读0次

    因为转换会用到运算符和补码的知识,下面先对运算符的使用做个简单的介绍。

    与(&)、非(~)、或(|)、异或(^)简介

    1.与运算符
    与运算符用符号“&”表示,其使用规律如下:
    两个操作数中位都为1,结果才为1,否则结果为0,例如下面的程序段。

        public static void main(String[] args) {
            int a = 129;
            int b = 128;
            System.out.println("a 和b 与的结果是:" + (a & b));
        }
    

    运行结果
    a 和b 与的结果是:128
    下面分析这个程序:
    “a”的值是129,转换成二进制就是10000001,而“b”的值是128,转换成二进制就是10000000。根据与运算符的运算规律,只有两个位都是1,结果才是1,可以知道结果就是10000000,即128。

    2.或运算符
    或运算符用符号“|”表示,其运算规律如下:
    两个位只要有一个为1,那么结果就是1,否则就为0,下面看一个简单的例子。

        public static void main(String[] args) {
            int a = 129;
            int b = 128;
            System.out.println("a 和b 或的结果是:" + (a | b));
        }
    

    运行结果
    a 和b 或的结果是:129
    下面分析这个程序段:
    a 的值是129,转换成二进制就是10000001,而b 的值是128,转换成二进制就是10000000,根据或运算符的运算规律,只有两个位有一个是1,结果才是1,可以知道结果就是10000001,即129。

    3.非运算符
    非运算符用符号“~”表示,其运算规律如下:
    如果位为0,结果是1,如果位为1,结果是0,下面看一个简单例子。

        public static void main(String[] args) {
            int a = 2;
            System.out.println("a 非的结果是:" + (~a));
        }
    

    运行结果
    a 非的结果是:-3

    4.异或运算符
    异或运算符是用符号“^”表示的,其运算规律是:
    两个操作数的位中,相同则结果为0,不同则结果为1。下面看一个简单的例子。

        public static void main(String[] args) {
            int a = 15;
            int b = 2;
            System.out.println("a 与 b 异或的结果是:" + (a ^ b));
        }
    

    运行结果
    a 与 b 异或的结果是:13
    分析上面的程序段:a 的值是15,转换成二进制为1111,而b 的值是2,转换成二进制为0010,根据异或的运算规律,可以得出其结果为1101 即13。

    补码反码介绍

    1.原码:
    一个byte是一个字节,一个字节是由8个位组成。其中最高位是符号位,范围就是127 ~ -128。

    即:0111 1111~1111 1111

    也就是说:0000 0001 代表的是1,

    1000 0000 代表的是-128。
    反码
    正数的反码是其本身(正数的符号位是0);

    负数的反码是:在原码的基础上,符号位不变,其他位取反。(负数的符号位是1)

    即:-128的原码是:1000 0000

    反码是:1111 1111

    补码
    补码是在原码的基础上,符号位不变,其他位取反+1。

    例如: 1的原码是:0000 0001
    反码是:0000 0001

    符号位不变,取反: 0111 1111

    +1(逢二进一)
    补码是:1111 1111

    下面开始上正菜

    以int和byte互转为例进行分析

        public static void main(String[] args) {
            int a = 129;
            // 第一组 第二组 第三组 第四组
            // 2的二进制表示完整为 "[00000000][00000000][00000000][00000010]"[]括号实际没有,为了看起来清楚加的
            byte[] b = new byte[4];
            // 向右移位是 低位舍弃,高位补符号位
            // 向右移位运算,移动24位后,高8位,被移动到低8位上,二、三、四组都会被丢弃
            b[0] = (byte) (a >> 24);
            // 向右移动16位,高16位到低16位地方,第三、四组会被舍弃,至于&0xff这里不容易看出来,b[3]那一行能看出来
            b[1] = (byte) ((a >> 16) & 0xff);
            // 移动8位第四组会被丢弃,结果还是0
            b[2] = (byte) ((a >> 8) & 0xff);
            // 不移动直接进行与(&)运算,0xff的二进制是第四位为8个1 其他是0的数,作用就是排除不想要的位
            // 这里来个例子 [00000000][00000100][00000100][00000010]假如有这么个二进制的数字
            // 如果你想取到[00000100]字节的值 , 先对其向右移动8位变为
            // [00000000][00000000][00000100][00000100]
            // 然后和0xff与运算,0xff二进制[00000000][00000000][00000000][11111111]
            // 与运算后的结果就为[00000000][00000000][00000000][00000100]
            // 这样需要的字节就拿到了
            b[3] = (byte) (a & 0xff);
            for (byte c : b) {
                System.out.print(Integer.toBinaryString(c & 0xff) + " ");
            }
            System.out.println();
            // 把字节转回Int和上面颠倒下,就不多说了。
            int i = 0;
            i += ((b[0] & 0xff) << 24);
            i += ((b[1] & 0xff) << 16);
            i += ((b[2] & 0xff) << 8);
            i += ((b[3] & 0xff));
            System.out.println(i);
        }
    

    问题:为什么要&0xff?

    首先0xff是十六进制的255,也就是二进制的1111 1111,对0xff取与,实际上就是要取这个数最低八位的值,截一个字节的长度。

    如果不用&0xff:

    ①计算机中是用补码的方式进行存储数据。

    ②如果不用&0xff,那么在进行负数的运算时就会出现问题,如:使用-1进行运算,-1的byte补码是:1111 1111,对应的十六进制数字是0xff;

                           -1的int补码(32位)是1111 1111 1111 1111 1111 1111,如果将byte转换为int,那么对应的十六进制数是0xffff。
    

    结果不正确(对于负数而言)。

    所以为了计算结果的正确性,我们就要对字节进行&0xff操作。

    算法实现

    public class Utilities {
        
        public static byte[] int2Bytes(int num) {
            byte[] byteNum = new byte[4];
            for (int ix = 0; ix < 4; ++ix) {
                int offset = 32 - (ix + 1) * 8;
                byteNum[ix] = (byte) ((num >> offset) & 0xff);
            }
            return byteNum;
        }
    
        public static int bytes2Int(byte[] byteNum) {
            int num = 0;
            for (int ix = 0; ix < 4; ++ix) {
                num <<= 8;
                num |= (byteNum[ix] & 0xff);
            }
            return num;
        }
    
        public static byte int2OneByte(int num) {
            return (byte) (num & 0x000000ff);
        }
    
        public static int oneByte2Int(byte byteNum) {
            return byteNum > 0 ? byteNum : (128 + (128 + byteNum));
        }
    
        public static byte[] long2Bytes(long num) {
            byte[] byteNum = new byte[8];
            for (int ix = 0; ix < 8; ++ix) {
                int offset = 64 - (ix + 1) * 8;
                byteNum[ix] = (byte) ((num >> offset) & 0xff);
            }
            return byteNum;
        }
    
        public static long bytes2Long(byte[] byteNum) {
            long num = 0;
            for (int ix = 0; ix < 8; ++ix) {
                num <<= 8;
                num |= (byteNum[ix] & 0xff);
            }
            return num;
        }
    
        public static void main(String[] args) {
            int num = 129;
            System.out.println("测试的int值为:" + num);
    
            byte[] int2bytes = Utilities.int2Bytes(num);
            System.out.printf("int转成bytes: ");
            for (int i = 0; i < 4; ++i) {
                System.out.print(int2bytes[i] + " ");
            }
            System.out.println();
    
            int bytes2int = Utilities.bytes2Int(int2bytes);
            System.out.println("bytes转行成int: " + bytes2int);
    
            byte int2OneByte = Utilities.int2OneByte(num);
            System.out.println("int转行成one byte: " + int2OneByte);
    
            int oneByte2Int = Utilities.oneByte2Int(int2OneByte);
            System.out.println("one byte转行成int: " + oneByte2Int);
            System.out.println();
    
            long longNum = 100000;
            System.out.println("测试的long值为:" + longNum);
    
            byte[] long2Bytes = Utilities.long2Bytes(longNum);
            System.out.printf("long转行成bytes: ");
            for (int ix = 0; ix < long2Bytes.length; ++ix) {
                System.out.print(long2Bytes[ix] + " ");
            }
            System.out.println();
    
            long bytes2Long = Utilities.bytes2Long(long2Bytes);
            System.out.println("bytes转行成long: " + bytes2Long);
        }
    }
    

    相关文章

      网友评论

          本文标题:java中int与byte、long与byte之间的互相转换

          本文链接:https://www.haomeiwen.com/subject/jqtgyctx.html