`
fantaxy025025
  • 浏览: 1351496 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

[转]java中byte转换int,为何与0xff进行与运算

 
阅读更多

 

碰到了读取byte转化int的问题,正好收拾下原理。

需要了解不同平台的编码方式,了解原码反码补码,等。

 

原码反码补码的转换

------------------------------------------------------------------------------

在剖析该问题前请看如下代码
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的二进制采用的是补码形式

在这里先温习下计算机基础理论

byte是一个字节保存的,有8个位,即8个0、1。
8位的第一个位是符号位, 
也就是说0000 0001代表的是数字1 
1000 0000代表的就是-1 
所以正数最大位0111 1111,也就是数字127 
负数最大为1111 1111,也就是数字-128

上面说的是二进制原码,但是在java中采用的是补码的形式,下面介绍下什么是补码

1、反码:
        一个数如果是正,则它的反码与原码相同;
        一个数如果是负,则符号位为1,其余各位是对原码取反;

2、补码:利用溢出,我们可以将减法变成加法
       对于十进制数,从9得到5可用减法:
       9-4=5    因为4+6=10,我们可以将6作为4的补数
       改写为加法:
       9+6=15(去掉高位1,也就是减10)得到5.

       对于十六进制数,从c到5可用减法:
       c-7=5    因为7+9=16 将9作为7的补数
       改写为加法:
       c+9=15(去掉高位1,也就是减16)得到5.

    在计算机中,如果我们用1个字节表示一个数,一个字节有8位,超过8位就进1,在内存中情况为(100000000),进位1被丢弃。

    ⑴一个数为正,则它的原码、反码、补码相同
    ⑵一个数为负,刚符号位为1,其余各位是对原码取反,然后整个数加1
    
- 1的原码为                10000001
- 1的反码为                11111110
                                                   + 1
- 1的补码为                11111111

0的原码为                 00000000
0的反码为                 11111111(正零和负零的反码相同)
                                          +1
0的补码为               100000000(舍掉打头的1,正零和负零的补码相同)

Integer.toHexString的参数是int,如果不进行&0xff,那么当一个byte会转换成int时,由于int是32位,而byte只有8位这时会进行补位,
例如补码11111111的十进制数为-1转换为int时变为11111111111111111111111111111111好多1啊,呵呵!即0xffffffff但是这个数是不对的,这种补位就会造成误差。
和0xff相与后,高24比特就会被清0了,结果就对了。

----
Java中的一个byte,其范围是-128~127的,而Integer.toHexString的参数本来是int,如果不进行&0xff,那么当一个byte会转换成int时,对于负数,会做位扩展,举例来说,一个byte的-1(即0xff),会被转换成int的-1(即0xffffffff),那么转化出的结果就不是我们想要的了。

而0xff默认是整形,所以,一个byte跟0xff相与会先将那个byte转化成整形运算,这样,结果中的高的24个比特就总会被清0,于是结果总是我们想要的。

Author: orangelizq
email: orangelizq@163.com

 

-----------------------------------------------------------------------------------------

java byte 与int的互相转换

(me:

  这里还是有问题的,比如从win平台读取的4字节的byte到int,还是有问题。

  解决方法后面补上。

1.byte uses 1 byte while int uses4 bytes.

2. integer literals like "45" are of byte int not byte.
If you want a literal to be a byte, you have to
cast it: "(byte)45".

3. When values are promoted as part of an expression
or as parameters to a method call, they may be
promoted to int, but never to byte.

4. Many parts of the Java language used int, but none
of them use byte. For example, the length of an
array is an int. 

/**
     * Convert  an int to a byte array
     *
     * @param value int
     * @return byte[]
     */
public static byte[] intToByteArray(int value) {
        byte[] b = new byte[4];
        for (int i = 0; i < 4; i++) {
            int offset = (b.length - 1 - i) * 8;
            b[i] = (byte) ((value >>> offset) & 0xFF);
        }
        return b;
    }

    /**
     * Convert the byte array to an int starting from the given offset.
     *
     * @param b The byte array
     * @param offset The array offset,如果byte数组长度就是4,则该值为0
     * @return The integer
     */
    public static int byteArrayToInt(byte[] b, int offset) {
        int value = 0;
        for (int i = 0; i < 4; i++) {
            int shift = (4 - 1 - i) * 8;
            value += (b[i + offset] & 0x000000FF) << shift;
        }
        return value;
    }

 

 

分享到:
评论

相关推荐

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

    1. **byte转int**:将一个byte转换为int,可以通过与0xFF进行按位与操作(AND),然后根据位移规则进行左移或右移操作。例如,`byte b = 10; int i = b & 0xFF;` 这里`b & 0xFF`操作的目的是保证只有低8位参与运算,...

    Java任意长度byte数组转换为int数组的方法

    对于不正常的情况,比如3个byte转换为int,则第一个左移16位,第二位与0xff后左移8位,第三位与0xff,然后进行或运算即可。同理可运用于2个byte。对于1个byte,直接强制转换为int即可。 但是,当我们遇到一个byte...

    在Java中int和byte[]的相互转换

    在Java编程语言中,有时我们需要将整型(int)数据与字节数组(byte[])之间进行转换,这在处理网络通信、序列化或存储数据时尤为常见。本文将深入探讨Java中int与byte[]的转换方法。 首先,让我们理解为什么需要进行...

    基于java中byte数组与int类型的转换(两种方法)

    在Java编程中,将`int`类型转换为`byte`数组以及从`byte`数组还原回`int`类型是常见的操作,特别是在网络编程中。这是因为网络传输的数据通常以字节流的形式存在,而`int`等基本数据类型需要进行适当的序列化才能...

    java基本类型与byte数组互相转换

    在Java编程语言中,基本类型的变量(如`short`、`int`、`long`、`char`、`double`和`float`)和`byte`数组之间的相互转换是一项非常实用的技术,尤其是在网络通信、文件读写等场景下。下面将详细介绍如何进行这些...

    java byte数组与int,long,short,byte的转换实现方法

    本文将详细介绍如何在Java中将`byte`数组与其他基本数据类型(如`int`、`long`、`short`、`byte`)之间进行转换。 首先,我们来看`byte`到`int`的转换。Java中的`byte`类型是8位的,取值范围是-128到127。如果要将...

    学习文档_JAVA中Integer和Byte转换.doc

    在进行位运算时,Java会将byte类型自动扩展为int类型进行操作,这是因为byte的范围较小,位运算需要更大的数据类型来容纳结果。 以下是一个将4字节数组转换为有符号整数的方法: ```java int ByteToSignedInt(byte...

    java int转byte和long转byte的方法

    在Java编程中,有时我们需要将整型(int)和长整型(long)的数据转换为字节(byte),这在处理网络传输、二进制序列化或内存优化等场景中尤其常见。以下是一些关于如何在Java中进行这些转换的方法。 首先,让我们看下...

    Java 字节数组类型(byte[])与int类型互转方法

    总结,Java中的`int`到`byte[]`和`byte[]`到`int`的转换涉及位运算,包括位移和按位与。理解这些基本的位运算对于处理二进制数据至关重要。在实际开发中,确保数据类型的正确转换是保证程序正常运行的关键步骤。

    C语言如何将int转byte类型

    `-128-127的int都可以转成byte.txt` 可能包含了将这个范围内的 `int` 值转换为 `byte` 的例子,而 `INT转byte,直接%255.txt` 可能展示了仅对非负 `int` 值取模的方法。`byte是00~FF,int是0000 0000~FFFF FFFF.txt`...

    java转换C生产dat文件

    ### Java与C语言之间的Dat文件转换及类型对齐 #### 概述 在跨语言编程环境中,例如Java程序需要处理由C语言生成的数据文件(dat文件),常常会遇到数据类型不一致导致的数据解析问题,尤其是当涉及到二进制数据时。...

    hex2byte byte2hex

    - 遍历输入数组`b`,对于每一个`byte`,先通过位运算`& 0xFF`确保只考虑低八位有效值,然后调用`Integer.toHexString()`方法将其转换为十六进制字符串。 - 如果转换得到的字符串长度为1,则在其前面添加一个"0"以...

    Cnic.Convert.rar_byte_数据类型转换

    在标题"Cnic.Convert.rar_byte_数据类型转换"中,我们可以看出这是关于在Java或者其他类似语言中进行数据类型转换的一个资源,特别是涉及`Int`、`Byte[]`和`Long`之间转换的方法。描述中提到的“位移”方法是一种...

    byte数组转化为hex

    总结来说,Java中字节数组与16进制字符串之间的转换涉及到位运算、字符映射以及字符串处理。了解这些概念对于处理二进制数据至关重要,特别是在网络编程、文件读写和数据序列化等场景中。希望以上内容能帮助你更好地...

    JAVA 进制转换 参考代码

    这里我们将深入探讨如何在Java中进行进制转换,以及如何实现从16进制到62进制的转换,这在生成固定策略的短链中非常常见。 首先,让我们理解基本的进制转换概念。进制是指数值系统中代表数字的符号数量。我们最熟悉...

    JAVA中IP和整数相互转化的方法

    在Java编程中,IP地址和整数之间的转换是网络编程中的常见操作。这涉及到将IP地址(IPv4格式,如192.168.1.1)表示为一个整数,以及将整数还原为IP地址。下面将详细解释这两种转化方法,并提供相关的Java代码示例。 ...

    Java实现IEE754 Float类型数据

    3. **计算尾数**:通过位操作获取尾数位的值,并转换为实际的小数值。 4. **特殊值处理**: - 当指数位为0且尾数位不为0时,代表的是次正规数(Subnormal Number),需要特别处理。 - 当指数位和尾数位均为0时,...

    二进制与各种类型的数据转换.pdf

    例如,整数`int temp = 0x0F070301`在内存中以16进制表示为`0x0f x07 0x03 x01`,转换成二进制即为`00001111 00000111 00000011 00000001`。 2. **整数转byte数组** - 当需要将整数转换为byte数组时,可以通过逐位...

    数组的转换函数

    它通过逐位右移并应用位与运算(& 0xff)来获取每个字节的值,然后将这些字节存储在数组的相应位置。数组的顺序是从高字节到低字节,这与大端字节序相符。 2. `longToBytes(long n, byte[] array, int offset)`:此...

    C#各种数据类型转换

    本文将详细介绍C#中涉及的一些常见数据类型转换方法,包括但不限于字符串与字符数组、字节数组与字符串之间的转换等。 #### 1. 字符串转换为字符数组 ```csharp public static char[] String2CharArray(string in_...

Global site tag (gtag.js) - Google Analytics