java 32位无符号整数_Java中32位无符号数的取法

2023-05-16

场景描述:

Java 中基本类型都是有符号数值,如果接收到了 C/C++ 处理的无符号数值字节流,将出现转码错误。

解决方式:

使用 long 型的 64 位十六进制数 0xFFFFFFFFL,对取得的 32 位(4字节)的整型数值,做按位与(&)操作,

并以 long 型保存这个无符号数值,如下:

long vUnsigned = bf.getInt() & 0xFFFFFFFFL;

注:0xFFFFFFFFL 的高32位默认补0,末尾的 L 代表 long 型。

注:事实上,Java的 Integer 中已经实现此方法:

/**

* Converts the argument to a {@code long} by an unsigned

* conversion. In an unsigned conversion to a {@code long}, the

* high-order 32 bits of the {@code long} are zero and the

* low-order 32 bits are equal to the bits of the integer

* argument.

*

* Consequently, zero and positive {@code int} values are mapped

* to a numerically equal {@code long} value and negative {@code

* int} values are mapped to a {@code long} value equal to the

* input plus 232.

*

* @param x the value to convert to an unsigned {@code long}

* @return the argument converted to {@code long} by an unsigned

* conversion

* @since 1.8

*/

public static long toUnsignedLong(int x) {

return ((long) x) & 0xffffffffL;

}

package sparkstreaming_action.socket.main;

import java.nio.ByteBuffer;

public class UnsignedIntTest {

public static void main(String[] args) {

/** 使用 ByteBuffer 存放 64 位无符号整数的字节码

* 1. 默认实例化 HeapByteBuffer

* 2. 以 Byte[] 形式存放数据

* 3. Byte 取值范围:-128 ~ 127

* 4. 字节数组的低位索引号 对应 二进制的高位

*/

ByteBuffer bf = ByteBuffer.allocate(64);

/**

* 如下二进制(无符号 32 位整数值):

* 10000000 00000100 00000010 00000001

* 代表无符号十进制整数:

* 2147746305

* 代表有符号十进制整数:

* -2147220991

*

* 将此十进制数按字节存入字节数组缓存中

* 1. 前 32 位置 0

* 2. 后 32 位存放数值

*/

bf.put(0, Byte.valueOf("0")); // 00000000

bf.put(1, Byte.valueOf("0")); // 00000000

bf.put(2, Byte.valueOf("0")); // 00000000

bf.put(3, Byte.valueOf("0")); // 00000000

bf.put(4, Byte.valueOf("-128")); // 10000000

bf.put(5, Byte.valueOf("4")); // 00000100

bf.put(6, Byte.valueOf("2")); // 00000010

bf.put(7, Byte.valueOf("1")); // 00000001

/** 1. 以 Long 型读取8字节整数

* 此时读取正确,为32位的无符号整数

*/

System.out.println("--------------------read 8 bytes, unsigned value------------------------");

long vLong = bf.getLong(0); // 从 index 0 开始读

System.out.println(vLong);

System.out.println(Long.toBinaryString(vLong));

System.out.println(Long.toBinaryString(2147746305L));

/** 2. 以 Int 型读取4字节(低位)整数

* 此时将带有符号位,读取位32位有符号整数,不是预期读到的数据

*

* *那么,如何只读4字节就能读到32位无符号整数呢?

*/

System.out.println("--------------------read lower 4 bytes, signed value---------------------");

int vInt = bf.getInt(4); // 从 index 4 开始读

System.out.println(vInt);

System.out.println(Integer.toBinaryString(vInt));

System.out.println(Integer.toBinaryString(-2147220991));

/** 3. 只读4字节,并且读到32位无符号整数

* 使用 & 操作符,转成Long型,并取低32位

*/

System.out.println("--------------------read lower 4 bytes, unsigned value---------------------");

用 Int 型 0xFFFFFFFF 按位与,并不能行的通,如果不涉及符号位则可用

//long vUnsigned = bf.getInt(4) & 0xFFFFFFFF;

// 使用 Long 型 0xFFFFFFFFL,按位与,与下面的代码效果相同

//long vUnsigned = bf.getInt(4) & (long)(Math.pow(2, 32) - 1);

long vUnsigned = bf.getInt(4) & 0xFFFFFFFFL;

System.out.println(vUnsigned);

System.out.println(Long.toBinaryString(vUnsigned));

System.out.println(Long.toBinaryString(2147746305L));

System.out.println("--------------------0xFFFFFFFF and 0xFFFFFFFFL---------------------");

System.out.println("0xFFFFFFFF is 32 bits Int value: " + 0xFFFFFFFF); // -1

System.out.println("0x0FFFFFFFF is 32 bits Int value: " + 0x0FFFFFFFF); // -1

System.out.println("0xFFFFFFFFL is 64 bits Long value: " + 0xFFFFFFFFL); // 4294967295

}

}

--------------------read 8 bytes, unsigned value------------------------

2147746305

10000000000001000000001000000001

10000000000001000000001000000001

--------------------read lower 4 bytes, signed value---------------------

-2147220991

10000000000001000000001000000001

10000000000001000000001000000001

--------------------read lower 4 bytes, unsigned value---------------------

2147746305

10000000000001000000001000000001

10000000000001000000001000000001

--------------------0xFFFFFFFF and 0xFFFFFFFFL---------------------

0xFFFFFFFF is 32 bits Int value: -1

0x0FFFFFFFF is 32 bits Int value: -1

0xFFFFFFFFL is 64 bits Long value: 4294967295

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java 32位无符号整数_Java中32位无符号数的取法 的相关文章

随机推荐