Was ist falsch daran, == zum Vergleichen von Floats in Java zu verwenden?

177

Laut dieser java.sun-Seite == ist der Gleichheitsvergleichsoperator für Gleitkommazahlen in Java.

Wenn ich jedoch diesen Code eingebe:

if(sectionID == currentSectionID)

In meinem Editor und bei der statischen Analyse wird Folgendes angezeigt: "JAVA0078 Gleitkommawerte im Vergleich zu =="

Was ist falsch ==daran, Gleitkommawerte zu vergleichen? Was ist der richtige Weg, um es zu tun? 

user128807
quelle
29
Da der Vergleich von Floats mit == problematisch ist, ist es unklug, sie als IDs zu verwenden. Die Namen in Ihrem Beispielcode deuten darauf hin, dass Sie dies tun. Bevorzugt werden lange Ganzzahlen (Longs) und der De-facto-Standard für IDs.
Carl Manaster
4
Ja, war das nur ein zufälliges Beispiel oder verwenden Sie tatsächlich Floats als IDs? Gibt es einen Grund?
Per Wiklander
5
"Verwenden Sie für Float-Felder die Float.compare-Methode und für Double-Felder Double.compare. Die spezielle Behandlung von Float- und Double-Feldern wird durch das Vorhandensein von Float.NaN, -0.0f und den analogen Doppelkonstanten erforderlich. Weitere Informationen finden Sie in der Dokumentation zu Float.equals. " (Joshua Bloch: Effektives Java)
lbalazscs

Antworten:

211

Der richtige Weg, um Floats auf "Gleichheit" zu testen, ist:

if(Math.abs(sectionID - currentSectionID) < epsilon)

Dabei ist epsilon eine sehr kleine Zahl wie 0,00000001, abhängig von der gewünschten Genauigkeit.

Sieger
quelle
26
Unter dem Link in der akzeptierten Antwort ( cygnus-software.com/papers/comparingfloats/comparingfloats.htm ) erfahren Sie, warum ein festes Epsilon nicht immer eine gute Idee ist. Insbesondere wenn die Werte in den verglichenen Floats groß (oder klein) werden, ist das Epsilon nicht mehr geeignet. (Die Verwendung von epsilon ist in Ordnung, wenn Sie wissen, dass Ihre Float-Werte alle relativ vernünftig sind.)
PT
1
@PT Kann er epsilon mit einer Zahl multiplizieren und die Funktion ändern if(Math.abs(sectionID - currentSectionID) < epsilon*sectionID, um dieses Problem anzugehen?
Enthusiastgeek
3
Dies ist vielleicht sogar die beste Antwort, aber sie ist immer noch fehlerhaft. Woher bekommen Sie das Epsilon?
Michael Piefel
1
@MichaelPiefel heißt es schon: "je nach gewünschter Präzision". Floats sind von Natur aus wie physikalische Werte: Sie interessieren sich nur für eine begrenzte Anzahl von Positionen, abhängig von der totalen Ungenauigkeit. Alle darüber hinausgehenden Unterschiede werden als streitig angesehen.
ivan_pozdeev
Aber das OP wollte eigentlich nur auf Gleichheit testen und muss, da dies als unzuverlässig bekannt ist, eine andere Methode anwenden. Trotzdem kann ich mir nicht vorstellen, dass er überhaupt weiß, was seine „gewünschte Präzision“ ist. Wenn Sie also nur einen zuverlässigeren Gleichheitstest wünschen, bleibt die Frage: Woher beziehen Sie das Epsilon? Ich schlug vor, Math.ulp()in meiner Antwort auf diese Frage zu verwenden.
Michael Piefel
53

Gleitkommawerte können geringfügig abweichen, sodass sie möglicherweise nicht genau gleich sind. Wenn Sie beispielsweise einen Float auf "6.1" setzen und ihn dann erneut ausdrucken, erhalten Sie möglicherweise einen gemeldeten Wert von "6.099999904632568359375". Dies ist von grundlegender Bedeutung für die Funktionsweise von Floats. Daher möchten Sie sie nicht mit Gleichheit vergleichen, sondern innerhalb eines Bereichs vergleichen, dh wenn der Unterschied des Floats zu der Zahl, mit der Sie ihn vergleichen möchten, kleiner als ein bestimmter absoluter Wert ist.

Dieser Artikel im Register gibt einen guten Überblick darüber, warum dies der Fall ist. nützliche und interessante Lektüre.

Paul Sonier
quelle
@kevindtimm: Also werden Sie Ihre Gleichheitstests so durchführen, wenn (number == 6.099999904632568359375) jedes Mal, wenn Sie wissen möchten, dass number gleich 6.1 ist ... Ja, Sie sind richtig ... alles im Computer ist streng deterministisch, nur, dass die für Floats verwendeten Näherungswerte bei mathematischen Problemen nicht intuitiv sind.
Newtopian
Gleitkommawerte sind nur auf sehr spezifischer Hardware nicht deterministisch ungenau .
Stuart P. Bentley
1
@Stuart Ich könnte mich irren, aber ich glaube nicht, dass der FDIV-Fehler nicht deterministisch war. Die Antworten der Hardware entsprachen nicht den Spezifikationen, waren jedoch deterministisch, da dieselbe Berechnung immer das gleiche falsche Ergebnis lieferte
Schwerkraft
@Gravity Sie können argumentieren, dass jedes Verhalten angesichts bestimmter Einschränkungen deterministisch ist.
Stuart P. Bentley
Gleitkomma - Werte sind nicht ungenau. Jeder Gleitkommawert ist genau das, was er ist. Was ungenau sein kann , ist das Ergebnis einer Gleitkomma - Berechnung . Aber Vorsicht! Wenn Sie in einem Programm etwa 0,1 sehen, ist dies kein Gleitkommawert. Das ist ein Gleitkomma- Literal - eine Zeichenfolge, die der Compiler durch Berechnung in einen Gleitkommawert konvertiert .
Solomon Slow
22

Nur um den Grund für das zu nennen, was alle anderen sagen.

Die binäre Darstellung eines Floats ist irgendwie nervig.

In der Binärdatei kennen die meisten Programmierer die Korrelation zwischen 1b = 1d, 10b = 2d, 100b = 4d, 1000b = 8d

Nun, es funktioniert auch umgekehrt.

.1b = .5d, .01b = .25d, .001b = .125, ...

Das Problem ist, dass es keine genaue Möglichkeit gibt, die meisten Dezimalzahlen wie .1, .2, .3 usw. darzustellen. Alles, was Sie tun können, ist eine ungefähre Angabe in Binärform. Das System führt beim Drucken der Zahlen eine kleine Fudge-Rundung durch, sodass .1 anstelle von .10000000000001 oder .999999999999 angezeigt wird (die wahrscheinlich genauso nahe an der gespeicherten Darstellung liegen wie .1).

Aus Kommentar bearbeiten: Der Grund, warum dies ein Problem ist, sind unsere Erwartungen. Wir gehen davon aus, dass 2/3 irgendwann verfälscht wird, wenn wir es in Dezimalzahlen umwandeln, entweder .7 oder .67 oder .666667. Wir erwarten jedoch nicht automatisch, dass .1 auf die gleiche Weise wie 2/3 gerundet wird --und genau das passiert.

Übrigens, wenn Sie neugierig sind, ist die Zahl, die intern gespeichert wird, eine reine binäre Darstellung unter Verwendung einer binären "wissenschaftlichen Notation". Wenn Sie also anweisen, die Dezimalzahl 10.75d zu speichern, werden 1010b für die 10 und .11b für die Dezimalzahl gespeichert. Es würde also .101011 speichern, dann werden am Ende einige Bits gespeichert, um zu sagen: Verschieben Sie den Dezimalpunkt um vier Stellen nach rechts.

(Obwohl es technisch gesehen kein Dezimalpunkt mehr ist, ist es jetzt ein Binärpunkt, aber diese Terminologie hätte die Dinge für die meisten Menschen, die diese Antwort von Nutzen finden würden, nicht verständlicher gemacht.)

Bill K.
quelle
1
@Matt K - um, kein Fixpunkt; Wenn Sie "am Ende ein paar Bits speichern, um zu sagen, dass Sie die Dezimalpunktbits [N] nach rechts verschieben", ist dies Gleitkomma. Festpunkt nimmt die Position des Radixpunkts als fest an. Da im Allgemeinen der binamale (?) Punkt immer verschoben werden kann, um eine '1' ganz links zu erhalten, finden Sie im Allgemeinen einige Systeme, die die führende '1' weglassen und den so freigesetzten Raum widmen (1) Bit!), um den Bereich des Exponenten zu erweitern.
JustJeff
Das Problem hat nichts mit binärer oder dezimaler Darstellung zu tun. Mit dezimalem Gleitkomma haben Sie immer noch Dinge wie (1/3) * 3 == 0,999999999999999999999999999999.
Dan04
2
@ dan04 ja, da 1/3 keine dezimale ODER binäre Darstellung hat, hat es eine trinäre Darstellung und würde auf diese Weise korrekt konvertieren :). Die von mir aufgelisteten Zahlen (.1, .25 usw.) haben alle perfekte Dezimaldarstellungen, aber keine binäre Darstellung - und Menschen sind an solche mit "exakten" Darstellungen gewöhnt. BCD würde perfekt damit umgehen. Das ist der Unterschied.
Bill K
1
Dies sollte viel mehr positive Stimmen haben, da es das WIRKLICHE Problem hinter dem Problem beschreibt.
Levite
19

Was ist falsch daran, == zum Vergleichen von Gleitkommawerten zu verwenden?

Weil das nicht stimmt 0.1 + 0.2 == 0.3

AakashM
quelle
7
was ist mit Float.compare(0.1f+0.2f, 0.3f) == 0?
Wassermann Power
0,1f + 0,2f == 0,3f, aber 0,1d + 0,2d! = 0,3d. Standardmäßig ist 0,1 + 0,2 ein Doppel. 0,3 ist auch ein Doppel.
BurnabyRails
12

Ich denke, es gibt viel Verwirrung um Schwimmer (und Doppel), es ist gut, es zu klären.

  1. Es ist an sich nichts Falsches daran, Floats als IDs in standardkonformer JVM [*] zu verwenden. Wenn Sie einfach die Float-ID auf x setzen, nichts damit anfangen (dh keine Arithmetik) und später auf y == x testen, ist alles in Ordnung. Es ist auch nichts Falsches daran, sie als Schlüssel in einer HashMap zu verwenden. Was Sie nicht tun können, ist, Gleichheiten wie x == (x - y) + yusw. anzunehmen. Allerdings verwenden die Leute normalerweise ganzzahlige Typen als IDs, und Sie können beobachten, dass die meisten Leute hier von diesem Code abgeschreckt sind. Aus praktischen Gründen ist es daher besser, Konventionen einzuhalten . Beachten Sie, dass es so viele verschiedene doubleWerte wie lange gibt values, sodass Sie durch die Verwendung nichts gewinnen double. Das Generieren der "nächsten verfügbaren ID" kann bei Doppeln schwierig sein und erfordert einige Kenntnisse der Gleitkomma-Arithmetik. Die Mühe nicht wert.

  2. Andererseits ist es riskant, sich auf die numerische Gleichheit der Ergebnisse zweier mathematisch äquivalenter Berechnungen zu verlassen. Dies liegt an Rundungsfehlern und Genauigkeitsverlusten bei der Konvertierung von Dezimal- in Binärdarstellung. Dies wurde auf SO zu Tode diskutiert.

[*] Als ich "standardkonforme JVM" sagte, wollte ich bestimmte gehirngeschädigte JVM-Implementierungen ausschließen. Sehen Sie das .

quant_dev
quelle
Bei der Verwendung von Floats als IDs muss darauf geachtet werden, dass sie entweder mit ==anstatt verglichen werden equalsoder dass kein Float, der nicht mit sich selbst vergleichbar ist, in einer Tabelle gespeichert wird. Andernfalls kann ein Programm, das versucht zu zählen, wie viele eindeutige Ergebnisse aus einem Ausdruck erzeugt werden können, wenn verschiedene Eingaben eingegeben werden, jeden NaN-Wert als eindeutig betrachten.
Supercat
Das Obige bezieht sich auf Float, nicht auf float.
quant_dev
Worüber spricht man Float? Wenn man versucht, eine Tabelle mit eindeutigen floatWerten zu erstellen und diese zu vergleichen ==, führen die schrecklichen IEEE-754-Vergleichsregeln dazu, dass die Tabelle mit NaNWerten überflutet wird .
Supercat
floatTyp hat keine equalsMethode.
quant_dev
Ah - ich meinte nicht eine equalsInstanzmethode, sondern die statische Methode (ich denke innerhalb der FloatKlasse), die zwei Werte des Typs vergleicht float.
Supercat
9

Dies ist ein Problem, das nicht spezifisch für Java ist. Die Verwendung von == zum Vergleichen von zwei Floats / Doubles / einer beliebigen Dezimaltypnummer kann aufgrund der Art und Weise, wie sie gespeichert werden, möglicherweise Probleme verursachen. Ein Float mit einfacher Genauigkeit (gemäß IEEE-Standard 754) hat 32 Bit, die wie folgt verteilt sind:

1 Bit - Vorzeichen (0 = positiv, 1 = negativ)
8 Bit - Exponent (eine spezielle (Bias-127) Darstellung des x in 2 ^ x)
23 Bit - Mantisa. Die tatsächlich gespeicherte Nummer.

Die Mantisa verursacht das Problem. Es ist ein bisschen wie eine wissenschaftliche Notation, nur die Zahl in Basis 2 (binär) sieht aus wie 1.110011 x 2 ^ 5 oder ähnliches. In der Binärdatei ist die erste 1 immer eine 1 (mit Ausnahme der Darstellung von 0).

Um ein wenig Speicherplatz zu sparen (Wortspiel beabsichtigt), entschied IEEE daher, dass die 1 angenommen werden sollte. Zum Beispiel ist eine Mantisa von 1011 wirklich 1.1011.

Dies kann zu Vergleichsproblemen führen, insbesondere bei 0, da 0 möglicherweise nicht genau in einem Float dargestellt werden kann. Dies ist der Hauptgrund, warum von == abgeraten wird, zusätzlich zu den Gleitkomma-Mathematikproblemen, die in anderen Antworten beschrieben werden.

Java hat das einzigartige Problem, dass die Sprache auf vielen verschiedenen Plattformen universell ist, von denen jede ihr eigenes Float-Format haben kann. Umso wichtiger ist es, == zu vermeiden.

Der richtige Weg, um zwei Floats (nicht sprachspezifisch) auf Gleichheit zu vergleichen, ist wie folgt:

if(ABS(float1 - float2) < ACCEPTABLE_ERROR)
    //they are approximately equal

Dabei ist ACCEPTABLE_ERROR #defined oder eine andere Konstante gleich 0,000000001 oder die erforderliche Genauigkeit, wie Victor bereits erwähnt hat.

Einige Sprachen haben diese Funktionalität oder diese Konstante eingebaut, aber im Allgemeinen ist dies eine gute Angewohnheit.

CodeFusionMobile
quelle
3
Java hat ein definiertes Verhalten für Floats. Es ist nicht plattformabhängig.
Yishai
9

Ab heute ist der schnelle und einfache Weg, dies zu tun:

if (Float.compare(sectionID, currentSectionID) == 0) {...}

Die Dokumenten wird jedoch der Wert der Randdifferenz (ein Epsilon aus der Antwort von @Victor), der bei Berechnungen auf Floats immer vorhanden ist, nicht eindeutig angegeben. Dies sollte jedoch sinnvoll sein, da er Teil der Standard-Sprachbibliothek ist.

Wenn jedoch eine höhere oder angepasste Präzision erforderlich ist, dann

float epsilon = Float.MIN_NORMAL;  
if(Math.abs(sectionID - currentSectionID) < epsilon){...}

ist eine weitere Lösungsoption.

Alisa
quelle
1
In den von Ihnen verknüpften Dokumenten wird "der Wert 0, wenn f1 numerisch gleich f2 ist" angegeben, was bedeutet, dass dies (sectionId == currentSectionId)für Gleitkommazahlen nicht genau ist. Die Epsilon-Methode ist der bessere Ansatz, der in dieser Antwort enthalten ist: stackoverflow.com/a/1088271/4212710
typoerrpr
8

Schaumpunktwerte sind aufgrund eines Rundungsfehlers nicht zuverlässig.

Als solche sollten sie wahrscheinlich nicht als Schlüsselwerte verwendet werden, wie z. B. sectionID. Verwenden Sie stattdessen Ganzzahlen oder longwenn intnicht genügend mögliche Werte enthalten sind.

Eric Wilson
quelle
2
Einverstanden. Da es sich um IDs handelt, gibt es keinen Grund, die Gleitkomma-Arithmetik zu komplizieren.
Yohnny
2
Oder eine lange. Abhängig davon, wie viele eindeutige IDs in Zukunft generiert werden, ist ein int möglicherweise nicht groß genug.
Wayne Hartman
Wie genau ist Double im Vergleich zu Float?
Arvindh Mani
1
@ArvindhMani doubles sind viel präziser, aber sie sind auch Gleitkommawerte, daher sollte meine Antwort sowohl floatals auch enthalten double.
Eric Wilson
7

Zusätzlich zu früheren Antworten sollten Sie sich bewusst sein, dass mit -0.0fund +0.0f(sie sind ==aber nicht equals) und Float.NaN(es ist equalsaber nicht ) seltsame Verhaltensweisen verbunden sind== ) (ich hoffe, ich habe das richtig verstanden - argh, tun Sie es nicht!).

Edit: Lass uns nachsehen!

import static java.lang.Float.NaN;
public class Fl {
    public static void main(String[] args) {
        System.err.println(          -0.0f   ==              0.0f);   // true
        System.err.println(new Float(-0.0f).equals(new Float(0.0f))); // false
        System.err.println(            NaN   ==               NaN);   // false
        System.err.println(new Float(  NaN).equals(new Float( NaN))); // true
    }
} 

Willkommen bei IEEE / 754.

Tom Hawtin - Tackline
quelle
Wenn etwas == ist, sind sie bis auf das Bit identisch. Wie konnten sie nicht gleich sein ()? Vielleicht hast du es rückwärts?
mkb
@ Matt NaN ist etwas Besonderes. Double.isNaN (double x) in Java ist tatsächlich implementiert als {return x! = X; } ...
quant_dev
1
Bei Floats ==bedeutet dies nicht, dass Zahlen "mit dem Bit identisch" sind (dieselbe Zahl kann mit unterschiedlichen Bitmustern dargestellt werden, obwohl nur eine davon in normalisierter Form vorliegt). Auch -0.0fund 0.0fwerden durch verschiedene Bitmuster dargestellt (das Vorzeichenbit ist unterschiedlich), aber vergleichen Sie als gleich mit ==(aber nicht mit equals). Ihre Annahme, dass ==es sich um einen bitweisen Vergleich handelt, ist im Allgemeinen falsch.
Pavel Minaev
5

Sie können Float.floatToIntBits () verwenden.

Float.floatToIntBits(sectionID) == Float.floatToIntBits(currentSectionID)
aamadmi
quelle
1
Du bist auf dem richtigen Weg. floatToIntBits () ist der richtige Weg, aber es wäre einfacher, nur die integrierte Funktion equals () von Float zu verwenden. Siehe hier: stackoverflow.com/a/3668105/2066079 . Sie können sehen, dass der Standardwert equals () floatToIntBits intern verwendet.
dberm22
1
Ja, wenn es sich um Float-Objekte handelt. Sie können die obige Gleichung für Grundelemente verwenden.
aamadmi
4

Zuallererst schweben sie oder schweben sie? Wenn einer von ihnen ein Float ist, sollten Sie die Methode equals () verwenden. Wahrscheinlich ist es auch am besten, die statische Float.compare-Methode zu verwenden.

Omerkudat
quelle
4

Folgendes verwendet automatisch die beste Präzision:

/**
 * Compare to floats for (almost) equality. Will check whether they are
 * at most 5 ULP apart.
 */
public static boolean isFloatingEqual(float v1, float v2) {
    if (v1 == v2)
        return true;
    float absoluteDifference = Math.abs(v1 - v2);
    float maxUlp = Math.max(Math.ulp(v1), Math.ulp(v2));
    return absoluteDifference < 5 * maxUlp;
}

Natürlich können Sie mehr oder weniger als 5 ULPs auswählen ("Einheit an letzter Stelle").

Wenn Sie in die Apache Commons Bibliothek sind, die Precisionhat Klasse compareTo()und equals()sowohl mit Epsilon und ULP.

Michael Piefel
quelle
Wenn Sie float in double ändern, funktioniert diese Methode nicht wie isDoubleEqual (0.1 + 0.2-0.3, 0.0) == false
hychou
Es scheint, dass Sie eher 10_000_000_000_000_000L als Faktor benötigen double, um dies abzudecken.
Michael Piefel
3

Sie möchten vielleicht, dass es == ist, aber 123.4444444444443! = 123.4444444444442

KM.
quelle
3

Wenn Sie Floats verwenden müssen, kann das Schlüsselwort strictfp hilfreich sein.

http://en.wikipedia.org/wiki/strictfp

sdcvvc
quelle
Oder kann für verschiedene Architekturen noch nützlicher sein.
Joey Rohan
2

Zwei verschiedene Berechnungen, die gleiche reelle Zahlen erzeugen, erzeugen nicht notwendigerweise gleiche Gleitkommazahlen. Personen, die == verwenden, um die Ergebnisse von Berechnungen zu vergleichen, werden normalerweise davon überrascht. Die Warnung hilft daher dabei, einen möglicherweise subtilen und schwer zu reproduzierenden Fehler zu kennzeichnen.

VoiceOfUnreason
quelle
2

Haben Sie es mit ausgelagertem Code zu tun, der Floats für Dinge mit dem Namen sectionID und currentSectionID verwendet? Nur neugierig.

@ Bill K: "Die binäre Darstellung eines Floats ist irgendwie nervig." Wie? Wie würdest du es besser machen? Es gibt bestimmte Zahlen, die in keiner Basis richtig dargestellt werden können, weil sie niemals enden. Pi ist ein gutes Beispiel. Sie können es nur annähern. Wenn Sie eine bessere Lösung haben, wenden Sie sich an Intel.

xcramps
quelle
1

Wie in anderen Antworten erwähnt, können Doppelte kleine Abweichungen aufweisen. Und Sie könnten Ihre eigene Methode schreiben, um sie mit einer "akzeptablen" Abweichung zu vergleichen. Jedoch ...

Es gibt eine Apache-Klasse zum Vergleichen von Doubles: org.apache.commons.math3.util.Precision

Es enthält einige interessante Konstanten: SAFE_MINundEPSILON , die die maximal möglichen Abweichungen einfacher arithmetischer Operationen sind.

Es bietet auch die notwendigen Methoden zum Vergleichen, Gleichstellen oder Runden von Doppelwerten. (mit Ulps oder absoluter Abweichung)

bvdb
quelle
1

In einer einzeiligen Antwort kann ich sagen, Sie sollten verwenden:

Float.floatToIntBits(sectionID) == Float.floatToIntBits(currentSectionID)

Damit Sie mehr über die korrekte Verwendung verwandter Operatoren erfahren, werden hier einige Fälle erläutert: Im Allgemeinen gibt es drei Möglichkeiten, Zeichenfolgen in Java zu testen. Sie können ==, .equals () oder Objects.equals () verwenden.

Wie unterscheiden sie sich? == testet die Referenzqualität in Strings, um herauszufinden, ob die beiden Objekte gleich sind. Andererseits testet .equals (), ob die beiden Zeichenfolgen logisch gleichwertig sind. Schließlich testet Objects.equals () auf Nullen in den beiden Zeichenfolgen und bestimmt dann, ob .equals () aufgerufen werden soll.

Idealer Bediener

Nun, dies war Gegenstand vieler Debatten, da jeder der drei Betreiber seine eigenen Stärken und Schwächen hat. Beispiel: == ist häufig eine bevorzugte Option beim Vergleichen von Objektreferenzen. In einigen Fällen scheint es jedoch auch so zu sein, dass Zeichenfolgenwerte verglichen werden.

Was Sie jedoch erhalten, ist ein fallender Wert, da Java die Illusion erzeugt, dass Sie Werte vergleichen, aber im eigentlichen Sinne nicht. Betrachten Sie die beiden folgenden Fälle:

Fall 1:

String a="Test";
String b="Test";
if(a==b) ===> true

Fall 2:

String nullString1 = null;
String nullString2 = null;
//evaluates to true
nullString1 == nullString2;
//throws an exception
nullString1.equals(nullString2);

Daher ist es viel besser, jeden Operator zu verwenden, wenn Sie das spezifische Attribut testen, für das er entwickelt wurde. In fast allen Fällen ist Objects.equals () ein universellerer Operator. Daher entscheiden sich erfahrene Webentwickler dafür.

Hier erhalten Sie weitere Informationen: http://fluentthemes.com/use-compare-strings-java/

Fließende Themen
quelle
-2

Der richtige Weg wäre

java.lang.Float.compare(float1, float2)
Eric
quelle
7
Float.compare (float1, float2) gibt ein int zurück, sodass es in der if-Bedingung nicht anstelle von float1 == float2 verwendet werden kann. Darüber hinaus wird das zugrunde liegende Problem, auf das sich diese Warnung bezieht, nicht wirklich gelöst. Wenn Floats Ergebnisse numerischer Berechnungen sind, kann float1! = Float2 nur aufgrund von Rundungsfehlern auftreten.
quant_dev
1
Richtig, Sie können nicht kopieren und einfügen. Sie müssen zuerst das Dokument überprüfen.
Eric
2
Was Sie anstelle von float1 == float2 tun können, ist Float.compare (float1, float2) == 0.
Deterb
29
Das kauft dir nichts - du bekommst immer nochFloat.compare(1.1 + 2.2, 3.3) != 0
Pavel Minaev
-2

Eine Möglichkeit, Rundungsfehler zu reduzieren, besteht darin, Double anstelle von Float zu verwenden. Dadurch wird das Problem nicht behoben, aber die Fehlermenge in Ihrem Programm wird verringert, und Float ist fast nie die beste Wahl. MEINER BESCHEIDENEN MEINUNG NACH.

Peter Lawrey
quelle