【问题标题】:Can one force String.valueOf() to return unsigned value in Java? [duplicate]可以强制 String.valueOf() 在 Java 中返回无符号值吗? [复制]
【发布时间】:2014-03-13 07:36:21
【问题描述】:

我有一个字节数组:

byte[] a = new byte[3];

我已经添加了一些字节。对于此示例,假设为 3、4 和 210。

我想打印这个字节串看起来像3 4 210,但我得到的是3 4 -46

我正在使用String.valueOf(a[i]) 进行转换。有没有办法强制这种转换给出无符号值?

提前致谢,

编辑:感谢对此问题的各种反馈。我没有意识到默认情况下 Java 字节是有符号值,因此怀疑 String.valueOf() 方法是问题所在。原来只是简单地使用

String.valueOf(a[i]&0xFF)

处理签名格式问题。

再次感谢您的反馈!

【问题讨论】:

  • Java 中没有无符号类型。如果您想打印210,那么为什么不直接使用int[]
  • 感谢您的宝贵时间和反馈。我每天都在学习这个Java。我没有意识到 Java 字节已签名。让我浏览一下回复并处理它们......

标签: java formatting


【解决方案1】:

Guava 提供了一个UnsignedBytes 类,可以进行这种转换。 statictoString(byte) 方法

返回 x 的字符串表示形式,其中 x 被视为无符号。

例如

System.out.println(UnsignedBytes.toString(a[i]));

a[i] = -46 将在哪里打印

210

在内部,这一切都是调用

public static int toInt(byte value) {
    return value & UNSIGNED_MASK; // UNSIGNED_MASK = 0xFF
}

并将int 转换为它返回的String


解释一下

someByte & 0xFF

由于 OxFF 是一个整数文字,someByte 的值被扩展为int。让我们以值-46 为例。它的二进制表示是

11111111111111111111111111010010

0xFF 的二进制表示是

11111111 // ie 255

如果你&这两个

11111111111111111111111111010010
00000000000000000000000011111111 
--------------------------------
00000000000000000000000011010010

等于

210

基本上你只保留int的低8位。

【讨论】:

  • 对这么简单的东西的依赖?
  • @seand 这就是为什么如果他们想复制它,我也提供了源代码。 (但 Guava 是大多数项目无论如何都应该拥有的那种库。)
【解决方案2】:

Java 字节数据类型范围是最小值 -128 和最大值 127(含)。 String.valueOf(a[i]) 不进行此转换。请改用int 类型。

【讨论】:

    【解决方案3】:

    byte 字节范围限制在 -128 到 127 之间, 所以对于 210,它给出 -46。所以使用 int 类型转换它

    【讨论】:

    • 您已经描述了问题,但看起来 OP 已经知道这一点。您对解决方案有什么建议吗?
    【解决方案4】:

    您遇到了 Java 著名的字节被视为有符号的问题,尽管现实世界中的大多数人更喜欢这些无符号字节。试试这个:

    int[] signedArr = new int[a.length];
    for (int i=0; i<a.length; ++i) {
      signedArr[i] = a[i] & 0xff;
    }
    

    然后你可以使用signedArr。

    【讨论】:

    • 这不是让 b 通过吗?
    • 您的答案在编辑之前更好。当所有 OP 想要做的就是打印值时,不需要整个数组。只需执行a[i] &amp; 0xff 部分并打印出来的内容。
    • @mharris7190 不,因为&amp; 将双方隐式转换为int
    猜你喜欢
    • 1970-01-01
    • 2011-04-07
    • 2020-12-22
    • 2011-05-15
    • 1970-01-01
    相关资源
    最近更新 更多