---
title: 'Inselupdate: Vorzeichenlos arbeiten'
url: 'https://www.tutego.de/blog/javainsel/2012/06/inselupdate-vorzeichenlos-arbeiten'
markdown: 'https://www.tutego.de/blog/javainsel/2012/06/inselupdate-vorzeichenlos-arbeiten.md'
date: '2012-06-16'
description: 'Bis auf char sind in Java alle integralen Datentypen vorzeichenbehaftet und kodiert im Zweierkomplement. Bei einem byte stehen 8 Bit für die Kodierung eines Wertes zur Verfügung, jedoch sind es eigentlich nur 7 Bit, denn über ein Bit erfolgt die Kodierung des Vorzeichens. Der Wertebereich ist von -…'
taxonomy:
  category:
    - Insel
    - 'Java 8'
---

# Inselupdate: Vorzeichenlos arbeiten

![Illustration einer tropischen Insel mit Palmen und einem hohen Berg](https://www.tutego.de/blog/javainsel/user/themes/tutego/images/insel-cover.jpg)# Java Blog für Programmierer

[Java Blog für Programmierer](https://www.tutego.de/blog/javainsel/)

## Inselupdate: Vorzeichenlos arbeiten

16.06.2012 · [Christian Ullenboom](https://www.tutego.de/blog/javainsel/author/admin/)

Bis auf char sind in Java alle integralen Datentypen vorzeichenbehaftet und kodiert im Zweierkomplement. Bei einem byte stehen 8 Bit für die Kodierung eines Wertes zur Verfügung, jedoch sind es eigentlich nur 7 Bit, denn über ein Bit erfolgt die Kodierung des Vorzeichens. Der Wertebereich ist von -128 bis +127. Über einen Umweg ist es möglich, den vollen Wertebereich auszuschöpfen und so zu tun, als ob Java vorzeichenlose Datentypen hätte.

**byte als vorzeichenlosen Datentyp nutzen**

Eine wichtige Eigenschaft der expliziten Typanpassung bei Ganzzahltypen ist es, dass die überschüssigen Bytes einfach abgeschnitten werden. Betrachten wir die Typanpassung an einem Beispiel:

```java
int l = 0xABCD6F;

byte b = (byte) 0xABCD6F;

System.out.println( Integer.toBinaryString( l ) ); // 101010111100110101101111

System.out.println( Integer.toBinaryString( b ) ); // 1101111
```

Liegt eine Zahl im Bereich von 0 bis 255, so kann ein byte diese durch seine 8 Bit grundsätzlich speichern. Java muss jedoch mit der expliziten Typanpassung gezwungen werden, das Vorzeichenbit zu ignorieren. Erst dann entspricht die Zahl 255 acht gesetzten Bits, denn sie mit byte b = 255; zu belegen, funktioniert nicht.

Damit die Weiterverarbeitung gelingt, muss noch eine andere Eigenschaft berücksichtigt werden. Sehen wir uns dazu folgende Ausgabe an:

```java
byte b1 = (byte) 255;

byte b2 = -1;

System.out.println( b1 ); // -1

System.out.println( b2 ); // -1
```

Das Bitmuster ist in beiden Fällen gleich, alle Bits sind gesetzt. Dass die Konsolenausgabe aber negativ ist, hat mit einer anderen Java-Eigenschaft zu tun: Java konvertiert das Byte, welches vorzeichenbehaftet ist, in ein int (der Parametertyp bei `toBinaryString()` ist int) und bei dieser Konvertierung wandert das Vorzeichen weiter. Das folgende Beispiel zeigt das bei der Binärausgabe:

```java
byte b = (byte) 255;
int i = 255;
System.out.printf( "%d %s%n", b, Integer.toBinaryString(b) );

// -1 11111111111111111111111111111111
System.out.printf( "%d %s%n", i, Integer.toBinaryString(i) );

// 255 11111111
```

Die Belegung der unteren 8 Bit vom byte b und int i ist identisch. Aber während beim int die oberen 3 Byte wirklich `null` sind, füllt Java durch die automatische Anpassung des Vorzeichens bei der Konvertierung von byte nach int im Zweierkomplement auf die oberen drei Byte mit 255 auf. Soll ohne Vorzeichen weitergerechnet werden stört das. Diese Automatisch Anpassung nimmt Java immer vor, wenn mit byte/short gerechnet wird und nicht nur wie in unserem Beispiel, wenn eine Methoden den Datentyp int fordert.

Um bei der Weiterverarbeitung einen Datenwert zwischen 0 und 255 zu bekommen, also das Byte eines int vorzeichenlos zu sehen, schneiden wir mit der Und-Verknüpfung die unteren 8 Bit heraus – alle anderen Bits bleiben also ausgenommen:

```java
byte b = (byte) 255;

System.out.println( b ); // -1

System.out.println( b & 0xff ); // 255
```

**Bibliotheksmethoden für vorzeichenlose Behandlung**

Immer ein & 0xff an einen Ausdruck zu setzen um die oberen Bytes auszublenden ist zwar nicht sonderlich aufwändig, aber schön ist das auch nicht. Hübscher sind Methoden wie `toUnsignedInt(byte)`, die mit dem Namen deutlich dokumentieren, was hier eigentlich passiert. In Java 8 gibt es daher einige Neuerungen.

Neue Methoden in Byte:

```java
26. static int toUnsignedInt(byte x)
```

27. static long `toUnsignedLong(byte x)`In `Integer`:
28. static long `toUnsignedLong(int x)`
29. static `String` `toUnsignedString(int i, int radix)`
30. static `String` `toUnsignedString(int i)`

    ```java

    ```
31. static int parseUnsignedInt(String s, int radix)
32. static int compareUnsigned(int x, int y)
33. static int divideUnsigned(int dividend, int divisor)
34. static int remainderUnsigned(int dividend, int divisor)

    ```

    In Long:
    ```
35. `String` `toUnsignedString(long i, int radix)`
36. static `String` `toUnsignedString(long i)`
37. static long `parseUnsignedLong(String s, int radix)`

    ```java

    ```
38. static int compareUnsigned(long x, long y)

    ```

    ```
39. static long `divideUnsigned(long dividend, long divisor)`
40. static long `remainderUnsigned(long dividend, long divisor)`In Short:

```java
44. static int toUnsignedInt(short x)
```

45. static long `toUnsignedLong(short x)`Neben den einfachen Methoden `toUnsignedXXX()`-Methoden in den Wrapper-Klassen gesellen sich Methoden hinzu, die auch die Konvertierung in einem `String` bzw. das Parsen eines Strings ermöglichen. Bei `Integer` und Long lassen sich ebenfalls neue Methoden ablesen, die Vergleiche, Division und Restwertbildung vorzeichenlos durchführen.

Kategorien: [Insel](https://www.tutego.de/blog/javainsel/category/insel/), [Java 8](https://www.tutego.de/blog/javainsel/category/java-8/)

[← Alle Beiträge](https://www.tutego.de/blog/javainsel/)

---

## Navigation

- Previous: [Schwere Fehler in der JVM, nun behoben](https://www.tutego.de/blog/javainsel/2012/06/schwere-fehler-in-der-jvm-nun-behoben.md)
- Next: [Überlaufe](https://www.tutego.de/blog/javainsel/2012/06/berlaufe.md)
