Java中的Byte转为无符号的Integer

Java的Byte都是有符号的(singed),而Byte又是8位的,如何转为无符号( unsigned)的呢?

 

素材:

byte   a=11010110 (singed : -42  、 unsigned :214)

 

尝试:

方法一:直接转-- (int)a (失败)

 

转换前 11010110


(转换,牵涉到符号位的扩展。因为扩展前符号位是1,所以扩展后,高位都是1)


转换后 11111111 11111111 11111111  11010110 ( - 42 )

 

原码--- 补码 转换

各位取反,在加1,转换成 原码
             11111111 11111111 11111111 11010110
(符号) 负

(取反) 00000000 00000000 00000000 00101001

(加1 ) 00000000 00000000 00000000 00101010
 

方法二:通过IO流 (成功)

 

   我常用IO流来进行一些 进制的转换 。   O(∩_∩)O~

 

import java.io.ByteArrayInputStream;

public class Test{

    public static void main(String[] args) {

    	byte[] bytes =  new byte[]{(byte)-42};
    	
    	ByteArrayInputStream in = new ByteArrayInputStream(bytes);
    	
    	int result = in.read();
    	System.out.println("无符号数: \t"+result);
    	System.out.println("2进制bit位: \t"+Integer.toBinaryString(result));
    }
}

    输出

无符号数:    214
2进制bit位: 11010110
 

  方法三:当然是看看 ByteArrayInputStream 的源码了。

 

    ByteArrayInputStream的read源码:

    public synchronized int read() {
	           return (pos < count) ? (buf[pos++] & 0xff) : -1;
    }

    原来是 & 运算呀!!!

 

   修改IO的方式的写法:

public class Test{

    public static void main(String[] args) {

    	byte bytes = -42;
    	
    	int result = bytes&0xff;
    	System.out.println("无符号数: \t"+result);
    	System.out.println("2进制bit位: \t"+Integer.toBinaryString(result));
    }
}

 

    稍微解释一下:

    (byte) -42 & 0xff 

      STEP01:(byte)-42 进行扩展:

      11111111 11111111 11111111  11010110

 

 

    STEP02:与运算:

      00000000 00000000 00000000 11111111  ( 0xff 也是 0x000000ff)

       &

    11111111 11111111 11111111 11010110  

 

      结果:

      00000000 00000000  00000000 11010110 (即是整数214)

 

 

    之所以会弄这个古怪的的问题,是因为我想得到中文字符串的byte流的二进制形式。想窥探一下不同的编码集的异同。

 

    记录一下: 读JDK源码,很有收获!!

<think>嗯,用户问的是Java中将32位的二次码换为4字节的BCD码。首先,我需要明确这两个术语的具体含义,可能用户有些术语使用不太准确,或者可能存在拼写错误,比如“二次码”是不是“二进制码”?因为常见的换通常是二进制到BCD码。不过也有可能用户指的是特定的编码方式,比如二次编码或者其他领域术语。但根据常见的编程问题,更可能是指二进制数据BCD码。 接下来,BCD码是Binary-Coded Decimal,也就是用4位二进制表示一个十进制数字,每个字节可以存两个十进制数。比如十进制的12用BCD码就是0001 0010,即0x12。所以4字节的BCD码可以存储8位十进制数字,比如0x12345678对应的十进制是12345678。而32位的二进制数最大可以表示到4294967295,有10位数字,这超过了4字节BCD码能存储的8位,所以这里可能存在矛盾。如果用户的问题中的32位二进制数换为4字节BCD码,那么可能需要处理数值范围的问题,或者可能用户的实际需求是换一个不超过8位十进制数的32位二进制数,或者需要截断或处理溢出。 那在Java中如何实现呢?步骤可能包括: 1. 将32位整数换为十进制数字字符串。例如,整数12345678成字符串"12345678"。 2. 检查字符串长度是否超过8位,如果超过,可能需要处理溢出或错误。 3. 将每两个数字分为一组,换为对应的BCD字节。例如,"12"转为0x12,"34"转为0x34等。 4. 如果数字个数是奇数,可能需要在前面补零,比如变成8位,或者后面补零,根据具体需求。 5. 将四个字节组合成4字节的BCD码数组。 另外,可能需要考虑大端序或小端序的问题,但通常BCD码是按顺序排列的,比如高位在前,低位在后。 例如,数字12345678换为BCD码的四个字节是0x12, 0x34, 0x56, 0x78。而如果是更小的数字,比如1234,则可能需要补前导零,变为00001234,然后得到0x00, 0x00, 0x12, 0x34?或者可能不需要补零,直接处理成1234对应的两个字节,但用户要求的是4字节,所以可能需要填充到8位,这样每个半字节对应一个数字。 但这里可能存在疑问,如果用户确实需要将32位的二进制数转为4字节BCD码,而32位二进制数的最大值是4294967295,也就是10位数字,这显然无法存入4字节BCD码(只能存8位)。所以可能用户的问题存在错误,或者需要处理截断,或者用户实际是指其他类型的换。 可能的情况包括: - 用户可能是指将32位的二进制数据(可能代表某种编码)换为BCD码,其中每个字节的高四位和低四位分别代表两位数字。 - 或者用户的问题中的“32位二次码”其实是某种特定编码,需要进一步确认,但如果是提问中的笔误,可能需要按照常规处理。 假设用户确实是想将32位的二进制整数换为BCD码,存储为4字节,但需要处理数值范围的问题。比如,只能处理最多8位十进制数的数值,即0到99999999。因此,在换前需要检查数值是否在有效范围内,否则会溢出。 可能的实现步骤: 1. 验证输入的32位整数值是否在0到99999999之间,否则抛出异常或处理错误。 2. 将整数换为8位的十进制字符串,左侧补零。例如,数字123换为"00000123"。 3. 将字符串拆分为四个两位数的组:"00", "00", "01", "23"。 4. 将每个两位数换为对应的BCD字节。例如,"00"转为0x00,"01"转为0x01,"23"转为0x23。 5. 将这四个字节组合成4字节的数组。 例如,数字12345678换为字符串"12345678",拆分为"12","34","56","78",换为字节数组{0x12, 0x34, 0x56, 0x78}。 Java代码示例可能如下: public static byte[] convertTo4ByteBCD(int value) { if (value < 0 || value > 99999999) { throw new IllegalArgumentException("Value must be between 0 and 99999999"); } String str = String.format("%08d", value); byte[] bcd = new byte[4]; for (int i = 0; i < 4; i++) { int high = Character.digit(str.charAt(2*i), 10); int low = Character.digit(str.charAt(2*i +1), 10); bcd[i] = (byte) ((high << 4) | low); } return bcd; } 但这里需要注意,Javaint类型是32位,但最大值为2147483647,即10位数字中的最大值,这已经超过了99999999(8位),所以当输入的value超过Integer.MAX_VALUE时,可能需要用long类型。但Javaint是32位,所以如果用户输入的是32位的二进制数,换为十进制可能超过int的范围(比如如果是无符号32位整数,最大值是4294967295,但Javaint是有符号的,所以如果用户处理的是无符号的32位值,需要用long来存储)。例如,当输入的32位二进制数作为无符号数时,其范围是0到4294967295,但换为BCD需要4字节的话,最多只能存到99999999,因此对于超过这个数值的情况,需要进行处理,比如抛出异常或者截断。 所以正确的做法可能需要使用long来保存输入的32位无符号整数: public static byte[] convertTo4ByteBCD(long value) { if (value < 0 || value > 99999999L) { throw new IllegalArgumentException("Value must be between 0 and 99999999"); } String str = String.format("%08d", value); byte[] bcd = new byte[4]; for (int i = 0; i < 4; i++) { int high = Character.digit(str.charAt(2*i), 10); int low = Character.digit(str.charAt(2*i +1), 10); bcd[i] = (byte) ((high << 4) | low); } return bcd; } 但这里又存在一个问题,当value超过Integer.MAX_VALUE(即2147483647)时,如果用户传入的是一个无符号的32位整数,比如用long类型处理,例如0xFFFFFFFFL(即4294967295),这已经超过了99999999,所以会抛出异常。 所以用户需要明确输入的范围是否符合4字节BCD码的容量,或者问题是否存在错误。如果用户的问题中的“32位二次码”实际上指的是某种其他编码方式,可能需要更多的信息。 总结来说,可能的步骤是: - 将数值换为8位十进制的字符串,补前导零。 - 每两位换为一个字节的BCD码。 - 组合成4字节数组。 此外,需要考虑数值是否在允许的范围内,否则处理溢出。 可能的错误情况包括数值过大,无法用4字节BCD码表示。例如,32位无符号整数的最大值是4294967295,需要10位十进制,而4字节BCD只能存8位,所以换时会有数据丢失,或者需要截断,但用户可能希望如何处理这种情况需要进一步确认。 因此,在回答时需要说明这些前提条件和潜在的问题,确保用户了解换的限制和可能的处理方式。</think>在Java中,将32位整数(二进制)换为4字节BCD码的过程需要理解两者的数据表示差异,并处理数值范围限制。以下是关键点及实现方法: --- ### **核心概念** 1. **BCD码**:用4位二进制表示一个十进制数字(0-9),每字节存储两个数字(高4位和低4位)。 - 例:十进制`12` → BCD码`0x12`(二进制`0001 0010`)。 2. **数值范围**: - 4字节BCD码最多存储8位十进制数(范围:`0`-`99999999`)。 - 32位无符号整数最大为`4294967295`(10位),超出BCD码容量,需处理溢出。 --- ### **实现步骤** 1. **范围检查**:确保输入值在`0`-`99999999`之间。 2. **格式化字符串**:将数值转为8位十进制字符串(补前导零)。 3. **逐字节换**:每两位数字转为1字节BCD码。 4. **处理字节顺序**:按大端序(高位在前)组合结果。 --- ### **代码示例** ```java public static byte[] convertIntTo4ByteBCD(long value) throws IllegalArgumentException { // 检查范围 if (value < 0 || value > 99_999_999L) { throw new IllegalArgumentException("数值需在0到99999999之间"); } // 转为8位十进制字符串,补前导零 String str = String.format("%08d", value); byte[] bcd = new byte[4]; // 每两位转为BCD字节 for (int i = 0; i < 4; i++) { int high = Character.getNumericValue(str.charAt(2 * i)); int low = Character.getNumericValue(str.charAt(2 * i + 1)); bcd[i] = (byte) ((high << 4) | low); } return bcd; } ``` --- ### **示例结果** - 输入:`12345678` - 输出BCD码:`{0x12, 0x34, 0x56, 0x78}` --- ### **注意事项** 1. **输入类型**:Java的`int`为有符号32位,最大仅`2147483647`。若需处理更大值(如无符号32位),需用`long`类型。 2. **溢出处理**:若数值超过`99999999`,需截断或抛异常,依具体场景决定。 3. **字节顺序**:示例使用大端序,若需小端序需调整字节数组顺序。 --- ### **常见问题** **Q:若数值超过8位如何处理?** A:直接换会导致数据丢失。需根据业务需求决定:截断(取后8位)、抛出异常或使用更多字节存储。 **Q:如何处理负数?** A:BCD码通常表示无符号数。负数需额外符号位或采用特定编码(如补码),需额外处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值