Warum man nicht float mit float vergleichen kann

G

Gast2

Gast
Moin,

da immer gerne float direkt mit float verglichen wird, mal ein kleines im Kopf nachrechenbares Beispiel

Java:
public static void main(String[] args) {
	float oben = 60.0f;
	float unten = 0.2f;
	
	oben = oben / 100.0f;0
	oben = oben - 0.4f;
	if (oben == unten) {
		System.out.println("oben und unten sind gleich");
	} else {
		System.out.println("komisch - passt nicht");
	}

	if ((oben > unten - 0.0001f) && (oben < unten + 0.0001f)) {
		System.out.println("endlich");
	}
}

es wird in der tat "komisch - passt nicht" ausgegeben. Erst nachdem getestet wurde ob oben in der Nähe von unten ist wird "endlich" ausgegeben. Das Problem besteht darin das eine CPU nicht mit analogen Dingen umgehen kann, es wird alles digitalisiert. Und bei der Digitalisierung von 0.2 entsteht ein periodischer Bruch der sich nur 0.2 annähert aber 0.2 nie erreicht (es wird 0.19~). Die 0.4 ist ebenfalls ein periodischer Bruch (ist 0.39~).

Der Rest ist eigentlich einfach. Einmal 60 durch 100 dividieren, wird 0.6. Davon 0.4 abziehen macht 0.2. Allerdings zieht die CPU nicht 0.4 sondern 0.39 ab, macht noch ganze 0.21. Die 0.2 wird intern auf 0.19 gerunden und 0.21 ist nicht 0.19.

Eine ausführlichere Erklärung findet man im Wiki IEEE 754 ? Wikipedia

hand, mogel
 
Zuletzt bearbeitet von einem Moderator:

Kr0e

Gesperrter Benutzer
Dieser Threshold-Vergleich wird aber gern und häufig verwendet. Z.b. Unity verwendet 1E-5 als Vergleichswert. Wert die innerhalb dieses Wertes nicht übereinstimmen sind vermutlich auch nicht gleich...
 

Marco13

Top Contributor
Ich verwende ihn auch gelegentlich, in ähnlicher Form. Man sollte sich aber im klaren sein, dass er manchmal nicht funktioniert. Wenn man mit Zahlen wie 1e-30 oder 1e30 rechnet, kann so ein 1e-5 ziemlich unsinnig sein. Wenn man in einer Welt rechnet, bei der sich alles so um die 1.0 rum abspielt passt der aber für viele Fälle.
 
S

Spacerat

Gast
Ich mach das immer vom letzten Digit abhängig, mit Float.floatToRawIntBits bzw. Double.doubleToRawLongBits. Wenn die Differenzen dieser Werte < -1 oder > +1 sind, interpretiere ich sie als ungleich.
[EDIT]...oder besser "Double.compare(double a, double b)"[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben