Float- und Double-Datentyp in Java

220

Der Float-Datentyp ist ein 32-Bit-IEEE 754-Gleitkomma mit einfacher Genauigkeit, und der doppelte Datentyp ist ein 64-Bit-IEEE 754-Gleitkomma mit doppelter Genauigkeit.

Was heißt das? Und wann sollte ich float anstelle von double verwenden oder umgekehrt?

Löwe
quelle
8
Sie sollten Floats anstelle von Double verwenden, wenn die Speichernutzung kritisch ist. Wenn Sie genauere Berechnungen benötigen, verwenden Sie Doppel.
Everv0id
12
@ Everv0id: Ich bin mir keiner Situation sicher, in der der Speicher so knapp war, dass man die Genauigkeit für den Platz opfern musste. (Sie verwenden Java , um Himmels willen ...) Es mag Situationen geben, in denen dies erforderlich ist, aber in meiner Praxis habe ich es sehr selten gesehen. Wenn Sie näher erläutern möchten, warum Sie dies für eine gute Idee halten, wäre es eine würdige Ergänzung, eine Antwort mit einem Beispiel zu geben.
Makoto
5
@ Makoto eigentlich habe ich noch nie Floats benutzt, nur Doppel. Es könnte jedoch (theoretisch) Anwendungen geben, die große Mengen an Gleitkommazahlen beibehalten sollten, sodass die doppelte Speichernutzung kritisch sein könnte. Theoretisch ofc; In der Praxis kann man immer noch einen Server kaufen .
Everv0id
3
Ich habe 4-Byte- und sogar 2-Byte-Zahlen mit fester Genauigkeit verwendet, um Speicherplatz zu sparen, aber wenn Sie nicht Milliarden davon haben, ist es unwahrscheinlich, dass es sich lohnt. Die Zeit, die Sie benötigen, um "double" anstelle von "float" zu schreiben (es hat einen Buchstaben mehr), ist 1000x mehr wert als der zusätzliche Speicher, den Sie verwenden. Wenn Sie jedoch einen präzisionsbedingten Fehler verwenden, doubleanstatt ihn zu floatretten, lohnt es sich .
Peter Lawrey

Antworten:

259

Die Wikipedia-Seite ist ein guter Anfang.

Um zusammenzufassen:

  • floatwird in 32 Bits mit 1 Vorzeichenbit, 8 Exponentenbits und 23 Bits des Signifikanten dargestellt (oder was aus einer wissenschaftlichen Notationsnummer folgt: 2.33728 * 10 12 ; 33728 ist der Signifikand).

  • double wird in 64 Bit mit 1 Vorzeichenbit, 11 Exponentenbits und 52 Signifikantenbits dargestellt.

Standardmäßig verwendet Java die doubleDarstellung seiner Gleitkommazahlen (daher wird ein Literal 3.14eingegeben double). Es ist auch der Datentyp, der Ihnen einen viel größeren Nummernbereich bietet, daher würde ich seine Verwendung dringend empfehlen float.

Es kann bestimmte Bibliotheken geben, die Ihre Nutzung tatsächlich erzwingen float, aber im Allgemeinen - es sei denn, Sie können garantieren, dass Ihr Ergebnis klein genug ist, um in floatden vorgeschriebenen Bereich zu passen , ist es am besten, sich dafür zu entscheiden double.

Wenn Sie Genauigkeit benötigen - zum Beispiel können Sie keinen ungenauen Dezimalwert haben (wie 1/10 + 2/10) oder Sie tun etwas mit Währung (z. B. 10,33 USD im System), verwenden Sie a BigDecimal, das a unterstützen kann beliebig präzise und handhaben solche Situationen elegant.

Makoto
quelle
4
Ist nicht 233728 == Mantisse im gegebenen Beispiel? Ich meine, wo sonst ist der ganzzahlige Teil gespeichert?
JaLoveAst1k
1
@ mathguy54: In wissenschaftlicher Notation wäre 2 die ganze Zahl und .33728 die Mantisse. Hier ist ein Hinweis darauf.
Makoto
5
Ich habe nach Informationen zu Floats und Doubles gesucht und diese gefunden und musste kommentieren: Wenn Sie etwas mit einer Währung tun, die keine gebrochenen Cent beinhaltet, ist die Verwendung von BigDecimal lächerlich. Die gemeinsame Währung sind diskrete Daten, daher sollten Sie einen ganzzahligen Datentyp verwenden. (Dies ist einer der häufigsten Fehler, die junge Programmierer machen - da wir ein. Verwenden, um Dollar von Cent zu trennen, denken sie, dass es ein Gleitkommawert ist. Das ist es nicht.)
Trixie Wolf
2
@TrixieWolf, könnten Sie genauer sein, haben Sie vorgeschlagen, zwei Ganzzahlen (Ganzzahl- und Dezimalteile) zu verwenden? Und Sie sprechen über die gemeinsame Währung, was ist mit dem Rest? Einige Beträge werden mit 6 Dezimalstellen ausgewertet, sodass Sie dies nicht einfach tun können *100. Bitte, Sie haben hier einen Punkt, aber könnten Sie genauer sein :)
AxelH
9
@AxelH Abgesehen von den Mittelwerten der Finanzberechnungen, bei denen gebrochene Cent existieren können, ist Geld immer diskret. Sie würden einen Ganzzahltyp verwenden, um die Daten zu speichern. 5,34 $ würden also als 534 gespeichert. Der Dollaranteil ist in Ganzzahlmathematik val / 100, und die Cent sind in Ganzzahlmathematik val% 100, wobei% sich auf die Restoperation bezieht. Für Geld mit mehr Stellen nach der Dezimalstelle sollte es immer noch als Integral gespeichert werden, da es diskret ist. Selbst wenn es nicht diskret ist, möchten Sie häufig die meiste Zeit auf einen diskreten Speicher zurückgreifen, da es präzise ist, damit Sie kein Geld durch Rundungsfehler verlieren.
Trixie Wolf
72

Ein Schwimmer gibt Ihnen ca. 6-7 Dezimalstellen Genauigkeit, während ein Doppel ca. 15-16. Auch der Zahlenbereich ist für Double größer.

Ein Double benötigt 8 Byte Speicherplatz, während ein Float nur 4 Byte benötigt.

Henry
quelle
13

Gleitkommazahlen, auch als reelle Zahlen bezeichnet, werden bei der Auswertung von Ausdrücken verwendet, die eine gebrochene Genauigkeit erfordern. Beispielsweise führen Berechnungen wie Quadratwurzel oder Transzendentale wie Sinus und Cosinus zu einem Wert, dessen Genauigkeit einen Gleitkommatyp erfordert. Java implementiert den Standardsatz (IEEE - 754) von Gleitkommatypen und Operatoren. Es gibt zwei Arten von Gleitkommatypen, float und double, die Zahlen mit einfacher bzw. doppelter Genauigkeit darstellen. Ihre Breite und Bereiche werden hier gezeigt:


   Name     Width in Bits   Range 
    double  64              1 .7e308 to 1.7e+308
    float   32              3 .4e038 to 3.4e+038


schweben

Der Typ float gibt einen Wert mit einfacher Genauigkeit an, der 32 Bit Speicher verwendet. Die einfache Genauigkeit ist auf einigen Prozessoren schneller und nimmt halb so viel Platz ein wie die doppelte Genauigkeit. Sie wird jedoch ungenau, wenn die Werte entweder sehr groß oder sehr klein sind. Variablen vom Typ float sind nützlich, wenn Sie eine Bruchkomponente benötigen, aber kein hohes Maß an Präzision benötigen.

Hier einige Beispiele für Deklarationen von Float-Variablen:

float hightemp, lowtemp;


doppelt

Die doppelte Genauigkeit, wie durch das Schlüsselwort double angegeben, verwendet 64 Bit zum Speichern eines Werts. Die doppelte Genauigkeit ist bei einigen modernen Prozessoren, die für mathematische Hochgeschwindigkeitsberechnungen optimiert wurden, tatsächlich schneller als die einfache Genauigkeit. Alle transzendentalen mathematischen Funktionen wie sin (), cos () und sqrt () geben doppelte Werte zurück. Wenn Sie die Genauigkeit vieler iterativer Berechnungen beibehalten müssen oder Zahlen mit großen Werten bearbeiten, ist double die beste Wahl.

Ihr gewinnt
quelle
Diese Antwort ist klar geklärt, wann wir float und double verwenden sollen. Warum nicht?
Sie gewinnen
8
Weder floatnoch doubleTypen werden in Java am besten für Währungen verwendet, da sie die Möglichkeit für Rundungsfehler eröffnen. Dieser Artikel geht detaillierter: javapractices.com/topic/TopicAction.do?Id=13
PPartisan
1
"Float kann nützlich sein, wenn Dollar und Cent dargestellt werden." - Nein, nein, nein, nein, nein, nein, nein. Speichern Sie niemals Währung als Floats / Doubles.
Reduzierung der Aktivität
2

Java scheint jedoch eine Tendenz zu haben, double für Berechnungen zu verwenden:

In dem Programm, das ich heute geschrieben habe, haben die Methoden nicht funktioniert, als ich float verwendet habe, aber jetzt funktionieren sie hervorragend, wenn ich float durch double ersetzt habe (in der NetBeans-IDE):

package palettedos;
import java.util.*;

class Palettedos{
    private static Scanner Z = new Scanner(System.in);
    public static final double pi = 3.142;

    public static void main(String[]args){
        Palettedos A = new Palettedos();
        System.out.println("Enter the base and height of the triangle respectively");
        int base = Z.nextInt();
        int height = Z.nextInt();
        System.out.println("Enter the radius of the circle");
        int radius = Z.nextInt();
        System.out.println("Enter the length of the square");
        long length = Z.nextInt();
        double tArea = A.calculateArea(base, height);
        double cArea = A.calculateArea(radius);
        long sqArea = A.calculateArea(length);
        System.out.println("The area of the triangle is\t" + tArea);
        System.out.println("The area of the circle is\t" + cArea);
        System.out.println("The area of the square is\t" + sqArea);
    }

    double calculateArea(int base, int height){
        double triArea = 0.5*base*height;
        return triArea;
    }

    double calculateArea(int radius){
        double circArea = pi*radius*radius;
        return circArea;
    }

    long calculateArea(long length){
        long squaArea = length*length;
        return squaArea;
    }
}
Raymond Wachaga
quelle
Ich hatte heute das gleiche Problem. Was kann der Grund für diese Tendenz sein?
Shachi
2

Dies wird einen Fehler geben:

public class MyClass {
    public static void main(String args[]) {
        float a = 0.5;
    }
}

/MyClass.java:3: Fehler: Inkompatible Typen: Mögliche verlustbehaftete Konvertierung von Double zu Float Float a = 0,5;

Dies wird einwandfrei funktionieren

public class MyClass {
    public static void main(String args[]) {
        double a = 0.5;
    }
}

Dies wird auch einwandfrei funktionieren

public class MyClass {
    public static void main(String args[]) {
        float a = (float)0.5;
    }
}

Grund : Java speichert reelle Zahlen standardmäßig doppelt, um eine höhere Genauigkeit zu gewährleisten.

Double benötigt mehr Platz, ist aber während der Berechnung präziser und float benötigt weniger Platz, ist aber weniger präzise.

Himanshu Singh
quelle
1

Gemäß den IEEE-Standards ist float eine 32-Bit-Darstellung einer reellen Zahl, während double eine 64-Bit-Darstellung ist.

In Java-Programmen wird normalerweise meistens der doppelte Datentyp verwendet. Dies dient nur zur Vermeidung von Überläufen, da der Zahlenbereich, der mit dem doppelten Datentyp aufgenommen werden kann, größer ist als der Bereich, in dem float verwendet wird.

Auch wenn eine hohe Präzision erforderlich ist, wird die Verwendung von Double empfohlen. Nur wenige Bibliotheksmethoden, die vor langer Zeit implementiert wurden, erfordern noch die Verwendung des Datentyps float als Muss (das liegt nur daran, dass er mit float implementiert wurde, sonst nichts!).

Wenn Sie jedoch sicher sind, dass Ihr Programm kleine Zahlen benötigt und bei Verwendung von float kein Überlauf auftritt, verbessert die Verwendung von float Ihre Speicherplatzkomplexität erheblich, da Floats die Hälfte des von double benötigten Speichers benötigen.

Rubal
quelle
0

Dieses Beispiel zeigt, wie das Vorzeichen (das Bit ganz links), der Exponent (die 8 folgenden Bits) und die Mantisse (die 23 Bits ganz rechts) aus einem Float in Java extrahiert werden.

int bits = Float.floatToIntBits(-0.005f);
int sign = bits >>> 31;
int exp = (bits >>> 23 & ((1 << 8) - 1)) - ((1 << 7) - 1);
int mantissa = bits & ((1 << 23) - 1);
System.out.println(sign + " " + exp + " " + mantissa + " " +
  Float.intBitsToFloat((sign << 31) | (exp + ((1 << 7) - 1)) << 23 | mantissa));

Der gleiche Ansatz kann für Doppelte verwendet werden (11-Bit-Exponent und 52-Bit-Mantisse).

long bits = Double.doubleToLongBits(-0.005);
long sign = bits >>> 63;
long exp = (bits >>> 52 & ((1 << 11) - 1)) - ((1 << 10) - 1);
long mantissa = bits & ((1L << 52) - 1);
System.out.println(sign + " " + exp + " " + mantissa + " " +
  Double.longBitsToDouble((sign << 63) | (exp + ((1 << 10) - 1)) << 52 | mantissa));

Bildnachweis: http://sj.github.io/java-float/

akustisch
quelle
0

Sie sollten double anstelle von float für präzise Berechnungen verwenden und float anstelle von double, wenn Sie weniger genaue Berechnungen verwenden. Float enthält nur Dezimalzahlen, Double enthält jedoch eine IEEE754-Gleitkommazahl mit doppelter Genauigkeit, wodurch es einfacher wird, Zahlen genauer zu enthalten und zu berechnen. Hoffe das hilft.

Boi Yeet
quelle
0

In regulären Programmierberechnungen verwenden wir kein float. Wenn wir sicherstellen, dass der Ergebnisbereich innerhalb des Bereichs des Float-Datentyps liegt, können wir einen Float-Datentyp zum Speichern von Speicher auswählen. Im Allgemeinen verwenden wir double aus zwei Gründen:

  • Wenn wir die Gleitkommazahl als Gleitkomma-Datentyp verwenden möchten, muss der Methodenaufrufer explizit F oder f hinzufügen, da standardmäßig jede Gleitkommazahl als doppelt behandelt wird. Dies erhöht die Belastung für den Programmierer. Wenn wir eine Gleitkommazahl als doppelten Datentyp verwenden, müssen wir kein Suffix hinzufügen.
  • Float ist ein Datentyp mit einfacher Genauigkeit, dh er belegt 4 Byte. Daher erhalten wir bei großen Berechnungen kein vollständiges Ergebnis. Wenn wir den doppelten Datentyp wählen, belegt er 8 Bytes und wir erhalten vollständige Ergebnisse.

Sowohl Float- als auch Double-Datentypen wurden speziell für wissenschaftliche Berechnungen entwickelt, bei denen Approximationsfehler akzeptabel sind. Wenn Genauigkeit das wichtigste Anliegen ist, wird empfohlen, die BigDecimal-Klasse anstelle von Float- oder Double-Datentypen zu verwenden. Quelle: - Float- und Double-Datentypen in Java

Rocco Jerry
quelle