为了账号安全,请及时绑定邮箱和手机立即绑定

我们能用Java做无符号字节吗?

我们能用Java做无符号字节吗?

沧海一幻觉 2019-07-06 16:05:12
我们能用Java做无符号字节吗?我正在尝试转换一个无符号字节。问题是,我接收到的数据是无符号的,而Java不支持无符号字节,所以当它读取数据时,它将其视为已签名的数据。我尝试通过下面从Stack溢出获得的解决方案来转换它。public static int unsignedToBytes(byte a){     int b = a & 0xFF;     return b;}但是当它再次以字节转换时,我得到了相同的有符号数据。我试图将此数据用作Java函数的参数,该函数只接受一个字节作为参数,因此不能使用任何其他数据类型。我怎样才能解决这个问题?
查看完整描述

3 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

我不太明白你的问题。

我刚刚尝试过这样做,对于字节-12(有符号值),它返回整数244(等效于无符号字节值,但键入为int):

  public static int unsignedToBytes(byte b) {
    return b & 0xFF;
  }

  public static void main(String[] args) {
    System.out.println(unsignedToBytes((byte) -12));
  }

这就是你想做的吗?

Java不允许将244表示为byte值,如C.表示上面的正整数。Byte.MAX_VALUE(127)您必须使用其他整数类型,如shortintlong.


查看完整回答
反对 回复 2019-07-06
?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

原语是用Java签名的,这与它们在内存/传输中的表示方式无关-字节仅为8位,是否将其解释为有符号范围取决于您。没有魔法标志可以说“这是签名的”或“这是未签名的”。

在对原语进行签名时,Java编译器将阻止您将大于+127的值分配给一个字节(或低于-128)。但是,没有什么可以阻止您为了实现这一点而降低int(或Short):

int i = 200; // 0000 0000 0000 0000 0000 0000 1100 1000 (200)byte b = (byte) 200; 
// 1100 1000 (-56 by Java specification, 200 by convention)/*
 * Will print a negative int -56 because upcasting byte to int does
 * so called "sign extension" which yields those bits:
 * 1111 1111 1111 1111 1111 1111 1100 1000 (-56)
 *
 * But you could still choose to interpret this as +200.
 */System.out.println(b); // "-56"/*
 * Will print a positive int 200 because bitwise AND with 0xFF will
 * zero all the 24 most significant bits that:
 * a) were added during upcasting to int which took place silently
 *    just before evaluating the bitwise AND operator.
 *    So the `b & 0xFF` is equivalent with `((int) b) & 0xFF`.
 * b) were set to 1s because of "sign extension" during the upcasting
 *
 * 1111 1111 1111 1111 1111 1111 1100 1000 (the int)
 * &
 * 0000 0000 0000 0000 0000 0000 1111 1111 (the 0xFF)
 * =======================================
 * 0000 0000 0000 0000 0000 0000 1100 1000 (200)
 */System.out.println(b & 0xFF); // "200"/*
 * You would typically do this *within* the method that expected an 
 * unsigned byte and the advantage is you apply `0xFF` only once
 * and than you use the `unsignedByte` variable in all your bitwise
 * operations.
 *
 * You could use any integer type longer than `byte` for the `unsignedByte` variable,
 * i.e. `short`, `int`, `long` and even `char`, but during bitwise operations
 * it would get casted to `int` anyway.
 */void printUnsignedByte(byte b) {
    int unsignedByte = b & 0xFF;
    System.out.println(unsignedByte); // "200"}


查看完整回答
反对 回复 2019-07-06
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

Java语言没有提供类似于unsigned关键词。一个byte根据语言规范,表示−128-127之间的一个值。例如,如果byte被铸造成intJava将第一位解释为符号和使用符号延伸.

尽管如此,没有什么可以阻止您查看byte简单地将其解释为8位,并将这些位解释为0到255之间的值。请记住,你无法将你的解释强加于别人的方法。如果方法接受byte,则该方法接受−128和127之间的值,除非另有明确说明。

为了您的方便,这里有几个有用的转换/操作:

到/从int的转换

// From int to unsigned byteint i = 200;                    
// some value between 0 and 255byte b = (byte) i;              
// 8 bits representing that value


// From unsigned byte to intbyte b = 123;                   
// 8 bits representing a value between 0 and 255int i = b & 0xFF;               
// an int representing the same value

(或者,如果您使用Java 8+,请使用Byte.toUnsignedInt.)

解析/格式化

最好的方法是使用上述转换:

// Parse an unsigned bytebyte b = (byte) Integer.parseInt("200");


// Print an unsigned byteSystem.out.println("Value of my unsigned byte: " + (b & 0xFF));

算术

对于加法、减法和乘法,2-补码表示“只起作用”:

// two unsigned bytesbyte b1 = (byte) 200;byte b2 = (byte) 15;byte sum  = (byte) (b1 + b2); 
 // 215byte diff = (byte) (b1 - b2);  
 // 185byte prod = (byte) (b2 * b2); 
  // 225

除法需要人工转换操作数:

byte ratio = (byte) ((b1 & 0xFF) / (b2 & 0xFF));


查看完整回答
反对 回复 2019-07-06
  • 3 回答
  • 0 关注
  • 593 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信