**Accessing Unsigned Data**

The Java programming language does not provide direct support for unsigned numeric values (other than char). But there are many instances in which you may need to extract unsigned information from a data stream or file, or pack data to create file headers or other structured information with unsigned fields. The **ByteBuffer** API does not provide direct support for this, but it’s not difficult to do. You just need to be careful about precision.

**Two’s Complement Representation**

All of the integer types are represented by binary numbers of varying bit widths. For example, the byte value for **126** in binary is **01111110**, where each position represents a power of two, starting with **2^0** or **1** at the rightmost bit. The next bit position to the left would be **2^1**, or **2**, continuing toward the left with **2^2**, or **4**, then **8**, **16**, **32**, and so on. So **126** has **1** bits set at positions **1** to **6** (counting from 0 at the right); thus, **126** is the sum of **2^1+2^2+2^3+2^4+2^5+2^6+2^7** which is **2+4+8+16+32+64**.

All of the integer types (except char) are signed(negative and positive) integers. This means that they can represent negative values as well as positive ones. Java uses an encoding known as **two’s complement**, which means that negative numbers are represented by inverting (**‘1’** changes to **‘0’** and **‘0’** changes to **‘1’**) all of the bits in a value(known as one’s complement), then adding **1** to the result. For example, **–126** is represented by inverting all of the bits in **126**, or **01111110**, which yields **10000001**, then adding **1**, which results in **10000010**, or **–126**. To decode a negative number, first invert all of the bits, then add **1**. For example, **–126**, or **10000010** inverted, yields **01111101**, or **125**, so when you add **1** you get **126**.

The reason Java (and most other computer languages) uses two’s complement is easy to see when you consider the issue of zero crossing. Assuming a byte value, zero is represented by **00000000**. In one’s complement, simply inverting all of the bits creates **11111111**, which creates negative zero. The trouble is that negative zero is invalid in integer math. This problem is solved by using two’s complement to represent negative values. When using two’s complement, **1** is added to the complement, producing **100000000**(9 bits). This produces a **1** bit too far to the left to fit back into the byte value, resulting in the desired behavior, where **–0** is the same as **0**, and **11111111** is the encoding for **–1**. Although we used a byte value in the preceding example, the same basic principle applies to all of Java’s integer types.

**Byte to Unsigned Int**

Byte is a signed 8-bit type(using two’s complement to encode negative values) that has a range from **–128** to **127**(256 values).

For positive numbers the leftmost bit is **‘0’** and for negative numbers the leftmost bit is **‘1’**. Assume you have **‘150’** as an unsigned byte. That is represented as **‘10010110’**. This binary value, when expressed as a signed two’s complement number, turns out to be **‘-106‘**(150-256). Any unsigned byte values over **128(0 to 127)** will be affected by the difference since the left-most bit is used in this way by the two’s complement scheme.

To convert a byte to an unsigned int value, use (byte value & **0xff**). The hex literal **0xff** is an equal int(255). Java represents int as **32** bits(00000000 00000000 00000000 11111111). When you do a bit wise AND(&) with this value(255) on any number, it is going to mask all but the lowest 8 bits of the number. The AND produces a 1 bit if both operands are also 1. A zero is produced in all other cases.

When you do a bitwise AND of **0xff** and any value from 0 to **255**, the result is the exact same as the value. And if any value higher than **255** still the result will be within **0-255**. Following methods may be useful when you must deal with unsigned data in **ByteBuffer**.

**Program**

**Program Source**

import java.nio.ByteBuffer; public class Javaapp { public static void main(String[] args) { ByteBuffer buf = ByteBuffer.allocate(12); buf.put((byte)150); buf.putShort((short)63000); buf.putInt((int)3100460000L); buf.flip(); System.out.println("Signed Byte : "+buf.get()); System.out.println("Signed Short : "+buf.getShort()); System.out.println("Signed Int : "+buf.getInt()); buf.flip(); System.out.println("Unsigned Byte Value From Int : "+(buf.get()&0xff)); System.out.println("Unsigned Short Value From Int : "+(buf.getShort()&0xffff)); System.out.println("Unsigned Int Value From Long : "+(buf.getInt()&0xffffffffL)); } }

**Unsigned Data Accessing Methods**

public static short getUnsignedByte (ByteBuffer bb) { return (short)(bb.get() & 0xff); } public static int getUnsignedShort (ByteBuffer bb) { return (bb.getShort( ) & 0xffff); } public static long getUnsignedInt (ByteBuffer bb) { return (long)(bb.getInt( ) & 0xffffffffL); }