Can we make unsigned byte in Java

前端 未结 16 1004
青春惊慌失措
青春惊慌失措 2020-11-22 08:02

I am trying to convert a signed byte in unsigned. The problem is the data I am receiving is unsigned and Java does not support unsigned byte, so when it reads the data it tr

相关标签:
16条回答
  • 2020-11-22 08:38

    Yes and no. Ive been digging around with this problem. Like i understand this:

    The fact is that java has signed interger -128 to 127.. It is possible to present a unsigned in java with:

    public static int toUnsignedInt(byte x) {
        return ((int) x) & 0xff;
    }
    

    If you for example add -12 signed number to be unsigned you get 244. But you can use that number again in signed, it has to be shifted back to signed and it´ll be again -12.

    If you try to add 244 to java byte you'll get outOfIndexException.

    Cheers..

    0 讨论(0)
  • 2020-11-22 08:39

    Complete guide for working with unsigned bytes in Java:

    Unsigned byte in Java

    (Source for this answer.)


    The Java Language does not provide anything like the unsigned keyword. A byte according to the language spec represents a value between −128 - 127. For instance, if a byte is cast to an int Java will interpret the first bit as the sign and use sign extension.

    That being said, nothing prevents you from viewing a byte simply as 8 bits and interpret those bits as a value between 0 and 255. Just keep in mind that there's nothing you can do to force your interpretation upon someone else's method. If a method accepts a byte, then that method accepts a value between −128 and 127 unless explicitly stated otherwise.

    Here are a couple of useful conversions / manipulations for your convenience:

    Conversions to / from int

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

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

    (Or, if you're on Java 8+, use Byte.toUnsignedInt.)

    Parsing / formatting

    Best way is to use the above conversions:

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

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

    Arithmetics

    The 2-complement representation "just works" for addition, subtraction and multiplication:

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

    Division requires manual conversion of operands:

    byte ratio = (byte) ((b1 & 0xFF) / (b2 & 0xFF));
    
    0 讨论(0)
  • 2020-11-22 08:40

    The fact that primitives are signed in Java is irrelevant to how they're represented in memory / transit - a byte is merely 8 bits and whether you interpret that as a signed range or not is up to you. There is no magic flag to say "this is signed" or "this is unsigned".

    As primitives are signed the Java compiler will prevent you from assigning a value higher than +127 to a byte (or lower than -128). However, there's nothing to stop you downcasting an int (or short) in order to achieve this:

    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"
    }
    
    0 讨论(0)
  • 2020-11-22 08:42

    If you have a function which must be passed a signed byte, what do you expect it to do if you pass an unsigned byte?

    Why can't you use any other data type?

    Unsually you can use a byte as an unsigned byte with simple or no translations. It all depends on how it is used. You would need to clarify what you indend to do with it.

    0 讨论(0)
  • 2020-11-22 08:48

    Although it may seem annoying (coming from C) that Java did not include unsigned byte in the language it really is no big deal since a simple "b & 0xFF" operation yields the unsigned value for (signed) byte b in the (rare) situations that it is actually needed. The bits don't actually change -- just the interpretation (which is important only when doing for example some math operations on the values).

    0 讨论(0)
  • 2020-11-22 08:48

    There is no unsigned byte in Java, but if you want to display a byte, you can do,

    int myInt = 144;
    
    byte myByte = (byte) myInt;
    
    char myChar = (char) (myByte & 0xFF);
    
    System.out.println("myChar :" + Integer.toHexString(myChar));
    

    Output:

    myChar : 90
    

    For more information, please check, How to display a hex/byte value in Java.

    0 讨论(0)
提交回复
热议问题