`
chriszeng87
  • 浏览: 720240 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java中byte的符号位(转)

    博客分类:
  • Java
阅读更多
在Java中byte类型是有符号的,而Java中又没有提供无符号的byte类型,因此在其表示范围为-128-127之间。而这样对于一些I/O处理程序来说需要对考虑符号位问题,通常的做法可能是:
    int unsignedByte = signedByte >=0 ? signedByte : signedByte + 256;
  

     这里我们发现,由于byte的符号位的关系,我们不得不采用长度更长的int类型来处理符号位带来的问题。因此,我们会觉得byte由于要考虑符号位其范围变小了,所以,我们只好通过int来处理。在这个类型的转换过程中,任意长度的int类型会截断其高位的字节来适应byte类型,因为int类型要比byte类型宽。这也就是为什么一个int的127转换成了byte还是一个127。


    不过,我们考虑另外一种情况,就是当一个int值大过byte表示的数值范围的时候,这个时候问题就出现了。比如,int的128转换成一个byte类型会是-128。这是因为补码运算的关系造成的。首先,128写成16进制是0x00000080,当做int到byte的类型转换的时候,前面的0被截断形成0x80。在二进制中0x80可以写成10000000,如果这是一个无符号数哪么一切正常,但是如果是一个有符号数就会经过补码运算。对于负数而言,其补码运算就是反码(就是1转换成0并且反正既然)加一。哪么,10000000的补码就是01111111加一,即10000000=128(十进制)。因此,byte0x80事实上表示的也

就是-128了。类似的int类型的129就是byte类型的-127,而int类型的130则是byte类型的-126,等等,直到int的255对应为byte的-1。


     哪么如果到了256呢?此时,地位的字节被0来填充,简而言之256就是0x00000100。因此,转换成byte就是0,这个转换循环也就是256个。因此,我们根据上述原理,得出如下规律:
byte byteValue=0;  
int temp = intValue % 256;  
if ( intValue < 0) {  
  byteValue =  (byte)(temp < -128 ? 256 + temp : temp);  
}  
else {  
  byteValue =  (byte)(temp > 127 ? temp - 256 : temp);  

上述过程中,我们既可以把有符号的byte转换成无符号的byte(用int类型存储),也可以把有符号但可能超出byte范围的数据转换成有符号的byte。

在剖析该问题前请看如下代码
public static String bytes2HexString(byte[] b) {
   String ret = "";
   for (int i = 0; i < b.length; i++) {
String hex = Integer.toHexString(b[ i ] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
ret += hex.toUpperCase();
   }
   return ret;
}
上面是将byte[]转化十六进制的字符串,注意这里b[ i ] & 0xFF将一个byte和 0xFF进行了与运算,然后使用Integer.toHexString取得了十六进制字符串,可以看出
b[ i ] & 0xFF运算后得出的仍然是个int,那么为何要和 0xFF进行与运算呢?直接 Integer.toHexString(b[ i ]);,将byte强转为int不行吗?答案是不行的.

其原因在于:
1.byte的大小为8bits而int的大小为32bits
2.java的二进制采用的是补码形式

问题1:java中没有实现这种“byte a = 0xB2 --> String b = “B2””转换的简单实现需要自己实现。
答:自己编写的转换函数,思路将byte的高低4位分开,分别转换为对应的字符然后合成返回的字符串。

java 代码
public static String byteToString(byte b) {   
byte high, low;   
byte maskHigh = (byte)0xf0;   
byte maskLow = 0x0f;   
 
high = (byte)((b & maskHigh) >> 4);   
low = (byte)(b & maskLow);   
 
StringBuffer buf = new StringBuffer();   
buf.append(findHex(high));   
buf.append(findHex(low));   
 
return buf.toString();   
}   
 
private static char findHex(byte b) {   
int t = new Byte(b).intValue();   
t = t < 0 ? t + 16 : t;   
 
if ((0 <= t) &&(t <= 9)) {   
return (char)(t + '0');   
}   
 
return (char)(t-10+'A');   
}   
 
未解决的疑问在java中不存在类似C中的无符号量,所以如果一个字节超过0x80其对应的整型值即为负值,但在高位右移4位后还是负值,且与对应的正值相差16,比如0xB2经过右移后的期望值是0x0B(11)但实际值是-5与预期的值相差16(这个16通过多次试验得出),对此现象为找到合理的解释。

问题2:“String a=”B2” --> byte b=0xB2”字符的byte转换为byte数据类型
答:思路通过Integer作为转换的中间桥梁

java 代码
public static int stringToByte(String in, byte[] b) throws Exception {   
if (b.length < in.length() / 2) {   
throw new Exception("byte array too small");   
}   
 
int j=0;   
StringBuffer buf = new StringBuffer(2);   
for (int i=0; i
buf.insert(0, in.charAt(i));   
buf.insert(1, in.charAt(i+1));   
int t = Integer.parseInt(buf.toString(),16);   
System.out.println("byte hex value:" + t);   
b[j] = (byte)t;   
i++;   
buf.delete(0,2);   
}   
 
return j;   
}   
 
问题3:整数(表示范围限定为两个字节unsigned short)通过Integer.byteValue()转换成byte[2],如果超出一个byte的表示范围将会截断高位的值。
答:思路一个byte能表示的最大整数为256(超过128为负值,超过256将被截断),所以取256的倍数为byte[0],256的余数为byte[1]。

java 代码
byte[] d = new byte[l+2];       
….       
buff.put(new Integer(l/256).byteValue());       
buff.put(new Integer(l%256).byteValue());   
分享到:
评论

相关推荐

    java byte相互转换详解左右位移

    java基本类型转byte,设计原码、补码、反码、左右位移等知识,赚点积分

    java数据类型转byte数组

    ip地址转4字节byte,char转2字节byte,byte数组转char,int整数转换为4字节的byte数组,byte数组转换为int整数,double类型转8字节数组,8位数组转double,long整数转换为8字节的byte数组,short整数转换为2字节的...

    C# byte转为有符号整数实例

    C#开发,收到下位机串口数据(温度信息),可能是正数也可能是负数,如何转换?...补充知识:c# byte数组转换 8位有符号整数 16位有符号整数 32位有符号整数 byte数组 byte[] aa = new byte[] { 0xF8

    Java byte 位移操作 注意事项

    & | ^ (加,减,乘,除,右移,左移,无符号右移,位与,位或,位异或)操作,均会是首先将byte转化为int, 再行运算。这一事实可能导致多种问题:  假设我们想进行如下byte运算: 1111 1000 右移1位,再与0000 ...

    JAVA基础之java的移位运算

    例如,如果要移走的值为负数,每一次右移都在左边补1,如果要移走的值为正数,每一次右移都在左边补0,这叫做符号位扩展(保留符号位)(sign extension ),在进行右移操作时用来保持负数的符号。例如,–8 &gt;&gt; 1 是...

    java基础入门教程

    网 络为中 心 的 计 算 时 代 转 移 ,而 购 买 Java则 是 他 的 重 大 战 略 决 策的实施 部 署 。因 此 ,Java的 诞 生 必 将 对 整 个 计 算 机 产 业 发 生 深远的 影 响,对 传 统 的 计 算 模型 提 出 了 新 的 ...

    Java输出通过InetAddress获得的IP地址数组详细解析

    由于byte被认为是unsigned byte,所以最高位的1将会被解释为符号位,另外Java中存储是按照补码存储,所以1000 0111会被认为是补码形式,转换成原码便是1111 0001,转换成十进制数便是-121

    Java基础知识之数据类型和操作符

    在Java中,操作符是用于执行各种算术和逻辑操作的符号。Java支持多种类型的操作符,包括算术操作符(如+、-、*、/)、比较操作符(如==、!=、&gt;、&lt;)、逻辑操作符(如&&、||、!)和赋值操作符(如=)。此外,Java还...

    Java 关键字、标识符、注释、常量与变量、数据类型,算术、赋值、比较、逻辑、位、三元运算符和流程控制、break、continue

    Java中常量的分类: 1,整数常量。所有整数 2,小数常量。所有小数 3,布尔(boolean)型常量。较为特有,只有两个数值。true false。 4,字符常量。将一个数字字母或者符号用单引号( ' ' )标识。 5,字符串常量。...

    自考04747《Java语言程序设计(一)》简答题全集.doc

    x++表示在使用x之后,使x的值加1 〔2.5分〕 10、 Java中常用的运算符按功能分有哪些 Java运算符按功能分6种,具体如下 〔1分〕 算术运算符、关系运算符、逻辑运算符 〔2分〕 位运算符、赋值运算符、条件运算符 〔2分...

    最新自考04747《Java语言程序设计(一)》简答题全集资料.doc

    x++表示在使用x之后,使x的值加1 (2.5分) 10、 Java中常用的运算符按功能分有哪些 Java运算符按功能分6种,具体如下 (1分) 算术运算符、关系运算符、逻辑运算符 (2分) 位运算符、赋值运算符、条件运算符 (2分...

    Java 基本知识之基本数据类型

    byte 数据类型是8位、有符号的,以二进制补码表示的整数; 最小值是-128(-2^7); 最大值是127(2^7-1); 默认值是0; short 数据类型是 16 位、有符号的以二进制补码表示的整数 最小值是-32768(-2^15); 最大值...

    整理后java开发全套达内学习笔记(含练习)

    进行高精度运算可以用java.math包中BigDecimal类中的方法。 自动类型提升又称作隐式类型转换。 强制类型转换:int ti; (byte) ti ; 强制转换,丢弃高位 宣告变量名称的同时,加上“final”关键词来限定,这个...

    thrift初步了解

    byte:8 位有符号整数,对应 Java 的 byte i16:16 位有符号整数,对应 Java 的 short i32:32 位有符号整数,对应 Java 的 int i64:64 位有符号整数,对应 Java 的 long double:64 位浮点数,对应 Java 的 double...

    2.Java基础语法.ppt

    字节型 byte 1个字节(8位) -128—127 0 短整型 short 2个字节(16位) -32768—32767 0 整形 int 4个字节(32位) +-2(的31次方)约21亿 0 长整形 long 8个字节(64位) -2(的63次方)—2(的63次方)-1 0 ...

    JAVA字符编码问题总结

    每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出 256种状态,这被称为一个字节(byte)。  也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从 ...

    java经典面试2010集锦100题(不看你后悔)

    A) 在Java中标志符可以是字母、下划线、数字或$符号。 B) 在Java中布尔类型不能和数字之间不能来回转换,即false和true不对应任何零或非零的值。 C) 双精度类型double比单精度类型float具有更高的精度和更大的表示...

    java基础,笔记03

    将二进制形式的a逐位右移b位 最高位空出的b位补原来的符号位 无符号右移:&quot;a&gt;&gt;&gt;b;&quot;将二进制形式的a逐位右移b位 最高位空出的b位补0 十进制的10 &gt;二进制数是 int a 10; int i a; ...

    C#的简单 基本语法

    byte 8位无符号整数 short 16位整数 int 32位整数 long 64位整数 float 32位浮点数 double 64位浮点数 char 16位字符 string 多个16位字符 宽度窄的(即字节数少的)数据类型可以直接赋给较宽的数据类型,并...

    java餐桌点餐系统源码-encoding:计算机相关名词解释

    每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从...

Global site tag (gtag.js) - Google Analytics