Warum gibt es in Java verschiedene Primitive Datentypen für Zahlen?

5 Antworten

Grundsätzlich werden mindestens 2 Datentypen gebraucht: Ein Integer-Datentyp und ein Fließkomma-Datentyp. Hintergrund ist, dass Fließkomma nicht alle Zahlen darstellen kann und bei jeder Operation gerundet wird - sodass man niemals verlässlich auf Gleichheit (==) prüfen kann.

Die Größen der Datentypen (8,16,32,64 bit) sind mit Sicherheit historisch entstanden und verfolgen das Ziel, Speicher zu sparen. Warum 64 Bit "verschwenden", wenn 8 Bit reichen?

Ansonsten kenne ich Java nur als 32 Bit orientierte Sprache - also das vom internen Aufbau her alles auf 32 Bit Basis gemacht wird. Ein Byte wäre dann im Prinzip auch nur ein Int. Aber da bin ich mir nicht sicher, ob es generell so ist.

Woher ich das weiß:Studium / Ausbildung

sophie082005  03.08.2018, 04:00

Ich habe zwei kleine Fehlerlein in deiner Antwort gefunden. ^^

Grundsätzlich werden mindestens 2 Datentypen gebraucht: Ein Integer-Datentyp und ein Fließkomma-Datentyp.

Fließkomma bringt zwar enorme Vorteile mit sich, ist aber eigentlich nur Luxus und wird nicht zwingend benötigt. Du kannst auch jeden Integertypen zum Festkommarechnen nutzen oder wenn alle Stricke reißen auch standardisierte Gleitpunktzahlen emulieren.

Da es in der Frage aber ausdrücklich um Java ging, werden natürlich genau genommen alle Java-typischen Datentypen benötigt.

Hintergrund ist, dass Fließkomma nicht alle Zahlen darstellen kann und bei jeder Operation gerundet wird - sodass man niemals verlässlich auf Gleichheit (==) prüfen kann.

Die einzige Ausnahme sind hier konstante Werte:

static final double FEHLERCODE = 123.456;

// ...

double wert = zauberei();

if (wert == FEHLERCODE) {
  // Wir werden alle sterben!!!
} else {
  // Tue etwas mit "wert" ...
}

In so einem Fall ist es natürlich sinnlos extra eine Differenz mit einem Epsilon-Wert zu vergleichen.

Außerdem ist die gängige Methode

if (Math.abs(a - b) < 0.0001) {
  // a und b sind ausreichend ähnlich
}

sehr sehr sehr fehleranfällig, und zwar in vielerlei Hinsicht, weshalb man von dieser Art der Gleitpunktvergleiche, laut meinem Lehrer, absehen sollte. Zumindest, wenn man nicht zu 100% sicher sein kann, in welchem Bereich die Werte von a und b liegen können.

Isendrak  03.08.2018, 00:44
sodass man niemals verlässlich auf Gleichheit (==) prüfen kann.

Deshalb ist das "übliche" Verfahren hierbei zu überprüfen, ob zwei Zahlenwerte des Typs double bzw. float "hinreichend gleich" sind.

Z.B. so:

class floatComparsion{
    public static boolean almostEquals(float x, float y){
        return Math.abs(x - y) < 0.00000001;
    }
    public static boolean almostEquals(double x, double y){
        return Math.abs(x - y) < 0.00000001;
    }
    public static boolean almostEquals(double x, float y){
        return Math.abs(x - y) < 0.00000001;
    }
    public static boolean almostEquals(float x, double y){
        return Math.abs(x - y) < 0.00000001;
    }
}

Nur so als "Fußnote". ^^

Aus dem gleichem Grund, aus dem es verschiedene Arten von Fahrzeugen gibt - LKWs, PKWs, Motoräder, Boote, Fahrräder, Flugzeuge...

Für die verschiedenen Zwecke das jeweils optimale Mittel.

Warum Fließkomma und Ganzzahlen benötigt werden, wurde ja bereits hinreichend erklärt.

Warum verschiedene Präzision (Speichergrößen)? Genau aus diesem Grund, Speicher(platz) ist teuer. Wenn ich die höhere Präzision nicht benötige aber sehr viele Elemente habe, dann nehme ich einen kleineren Typen.

Was bei 1000 Elementen noch nicht so gravierend erscheinen mag, wirkt sich bei 10^12 (und mehr) Elementen dann doch im Geldbeutel aus.

Jeder dieser Datentypen nimmt unterschiedlich viel Speicherplatz ein. Für den konkreten Fall solltest du schauen, welcher Datentyp am geeignetsten ist, um Speicherplatz einsparen zu können.

Hallöchen, aus dem Urlaub! XD

Gleitpunkttypen erleichtern das Leben enorm. Als Zählvariablen in Schleifen führen sie aber zu sehr unangenehmen Fehlern:

for (int i = 1; i <= 10; i += 1) {
    /* wird 10 mal ausgeführt */
}

System.out.println();

for (float f = 0.1f; f <= 1.0f; f += 0.1f) {
    /* wird (meistens) nur 9 mal ausgeführt */
}

Gemein, oder? ^^

LG, Sophie <3

Woher ich das weiß:Hobby