如何将一个字节转换为其二进制字符串表示形式?

118

例如,一个字节 B 中的位是 10000010,我该如何将这些位字面上分配给字符串 str,即 str = "10000010"

编辑

我从二进制文件中读取了字节,并将其存储在字节数组 B 中。我使用 System.out.println(Integer.toBinaryString(B[i]))。问题是

(a) 当位以 (最左侧的) 1 开头时,输出不正确,因为它将 B[i] 转换为负整数值。

(b) 如果位以 0 开头,则输出会忽略 0,例如,假设 B[0] 为 00000001,则输出为 1 而不是 00000001


2
我很困惑,这是个诡计吗? - Dave Newton
1
你是在询问如何将一个 byte 转换为二进制字符串吗? - SLaks
我刚刚为另一个线程添加了一个答案,可以将BooleanByteShortCharIntLong类型的值转换为二进制数字字符串。https://dev59.com/WWox5IYBdhLWcg3wFAjW#54950845 - chaotic3quilibrium
如果您告诉 String#Format() 使用 8 的宽度,它可能能够处理这个问题。同样地,System.out.printf() 也可以。 - NomadMaker
14个回答

1
一个简单的答案可以是:

System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})); // 0
System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})); // 1
System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0})); // 256
System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0})); // 65536
System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0})); // 16777216
System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0})); // 4294967296
System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0})); // 1099511627776
System.out.println(new BigInteger(new byte[]{0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0})); // 281474976710656
System.out.println(new BigInteger(new byte[]{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0})); // 72057594037927936
System.out.println(new BigInteger(new byte[]{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0})); // 18446744073709551616
System.out.println(new BigInteger(new byte[]{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0})); // 4722366482869645213696
System.out.println(new BigInteger(new byte[]{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})); // 1208925819614629174706176
System.out.println(Long.MAX_VALUE);                                              // 9223372036854775807

0
我们都知道Java不提供像无符号关键字那样的东西。此外,根据Java规范,一个字节原语表示介于-128和127之间的值。例如,如果将byte转换为int,Java将解释第一个bit作为sign并使用符号扩展。
那么,如何将大于127的字节转换为其二进制字符串表示形式?没有任何障碍阻止您将byte简单地视为8位,并将这些位解释为介于0255之间的值。此外,您需要记住,除非明确说明,否则无法强制您的解释对其他人的方法产生影响。如果一个方法接受一个byte,那么该方法接受介于−128127之间的值。
所以解决这个问题的最佳方法是通过调用 Byte.toUnsignedInt() 方法将 byte 值转换为 int 值,或者将其强制转换为 int 原始类型 (int) signedByte & 0xFF。以下是一个示例:
public class BinaryOperations
{
    public static void main(String[] args)
    {
        byte forbiddenZeroBit = (byte) 0x80;

        buffer[0] = (byte) (forbiddenZeroBit & 0xFF);
        buffer[1] = (byte) ((forbiddenZeroBit | (49 << 1)) & 0xFF);
        buffer[2] = (byte) 96;
        buffer[3] = (byte) 234;

        System.out.println("8-bit header:");
        printBynary(buffer);
    }

    public static void printBuffer(byte[] buffer)
    {
        for (byte num : buffer) {
            printBynary(num);
        }
    }

    public static void printBynary(byte num)
    {
        int aux = Byte.toUnsignedInt(num);
        // int aux = (int) num & 0xFF; 
        String binary = String.format("%8s', Integer.toBinaryString(aux)).replace(' ', '0');
        System.out.println(binary);
    }
}

输出

8-bit header:
10000000
11100010
01100000
11101010

0

对于那些需要大量将字节转换为二进制字符串的人,这里有一个提示:使用查找表而不是一直使用字符串操作。这比一遍又一遍地调用转换函数要快得多。

public class ByteConverterUtil {

  private static final String[] LOOKUP_TABLE = IntStream.range(0, Byte.MAX_VALUE - Byte.MIN_VALUE + 1)
                                                        .mapToObj(intValue -> Integer.toBinaryString(intValue + 0x100).substring(1))
                                                        .toArray(String[]::new);

  public static String convertByte(final byte byteValue) {
    return LOOKUP_TABLE[Byte.toUnsignedInt(byteValue)];
  }

  public static void main(String[] args){
    System.out.println(convertByte((byte)0)); //00000000
    System.out.println(convertByte((byte)2)); //00000010
    System.out.println(convertByte((byte)129)); //10000001
    System.out.println(convertByte((byte)255)); //11111111
  }


}

-1

我猜想,如果你有一个Byte对象,那么你可以直接调用toString()方法来获取其值。或者,看一下api,使用byteValue()方法也可以。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接