You are not logged in.

  • Login

Dear visitor, welcome to Coder Forum. If this is your first visit here, please read the Help. It explains in detail how this page works. To use all features of this page, you should consider registering. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

1

Friday, May 30th 2008, 2:31pm

BlueJ 1,3-0,3=0,9999994???

Hey Leute,
wir sollen momentan in der Schule einen Taschnrechner in BlueJ, was mit Java 1.42 läuft (die Lehrer sind zu faul 1.6 zu installieren ) programmieren.
Dabei habe ich einen interessanten Fehler. Und zwar bekommt der Taschenrechner bei der Rechnung 1,3 - 0,3 0,9999994(Anzahl 9 nicht genau bekannt, sitze gerade zu Hause, waren aber so zwischen 5 und 8 Neunen, denke ich) raus. Nun frage ich mich woran das liegt. Man gibt erst die eine Zahl per Buttons ein(also man hat eine Oberfläche wie bei einem normalem Taschenrechner, drückt dann auf die Minustaste, worauf die erste Zahl als Float in einer Variablen gespeichert wird, dann gibt man die zweite Zahl ein und drückt auf die Gleichtaste. Daraufhin wird dann die zweite Zahl auch in einer Variablen als Float gespeichert. Anschließend werden die Zahlen subtrahiert und das Ergebnis von Float in String umgewandelt, damit es auf dem Display angezeigt werden kann. Das Ergebnis ist dann, wie schon gesagt 0,9999994 und nicht 1.
Ich weiß, dass der Fehler nicht auftritt, wenn man anstatt von Float Double benutzt, aber mich würde schon interessieren, wo der Fehler liegt.
Die Lehrer wollen, bzw können, mir nicht sagen, wo das Problem liegt.

This post has been edited 1 times, last edit by "Darkfire" (May 30th 2008, 11:47pm)


2

Friday, May 30th 2008, 11:38pm

Quoted

und das Ergebnis von Float in Integer umgewandelt
Warum das denn? Integer kann nie 0,9999994 sein.

Der Quellcode wäre sehr hilfreich!

3

Friday, May 30th 2008, 11:47pm

Argh sorry, hab mich verschrieben, nicht Integer sondern String natürlich. (verbesser ich gleich noch)
Quellcode habe ich leider nicht hier. : /

4

Friday, May 30th 2008, 11:48pm

Ich kann dein Problem reporduzieren:

Java Quellcode

1
2
3
4
5
6
7
8
9
Float a = new Float("1.3");
		Float b = new Float("0.3");
 
		System.out.println(a);
		System.out.println(b);
 
		Float c = new Float(a.floatValue() - b.floatValue());
 
		System.out.println(c);

Quellcode brauchst du also nicht zu posten.

Es tritt auch bei Java 6 auf.

5

Friday, May 30th 2008, 11:54pm

http://www.i-coding.de/www/de/java/zahle…uble-float.html

Da steht die Lösung. Float und Double sind nicht 100% genau (obwohl es mich bei + und - auch sehr überrascht). Der Vorteil liegt in der Geschwindigkeit. Wenn man es genauer haben will: BigDecimal

6

Saturday, May 31st 2008, 1:47pm

Also ich hätte zwar vieles Gedacht, aber nicht das. oO
Wie genau kommt denn diese Ungenauigkeit zu stande? Ich meine, wie rechnet der Pc das ganze?

7

Saturday, May 31st 2008, 4:08pm

Verwendest du float wird die Floating Point Unit in der CPU genutzt und das geht dann natürlich flott.
Verwendest du BigDecimal werden wohl Integer verwendet und die Länge wird immer dynamisch erweitert.

Ich glaube das float-Verhalten haben alle/die meisten Programmiersprachen... Oft ist das exakte Ergebnis eben nicht wichtig.

8

Saturday, May 31st 2008, 10:42pm

Gut aber man sollte ja eigentlich denken, dass der 1,3 - 0,3 hinbekommt. :P

9

Thursday, June 5th 2008, 4:34pm

Was mich jetzt aber wundert, auf der einen Seite steht, dass Double genauso ungenau ist, mache ich das ganze aber mit Double, erhalte ich das Ergebnis 1 und keine Kommazahl.

Java Quellcode

1
2
3
4
5
6
7
8
9
Double a = new Double("1.3");
                Double b = new Double("0.3");
 
		System.out.println(a);
		System.out.println(b);
 
		 Double c = (a - b);
 
		System.out.println(c);

Hier der Quelltext. Theoretisch müsste da doch ebenfalls 0,999999.... rauskommen? Aufjedenfall eine Kommazahl. Aber es kommt 1,0 heraus?

10

Thursday, June 5th 2008, 9:52pm

Double ist ja auch 4294967296 mal genauer als Float.

11

Tuesday, June 10th 2008, 9:38pm

Kann mir jemand vlt genau erklären, wie diese Ungenauigkeit zu Stande kommt? Würde mich schon interessieren. (meine Infolehrer haben übrigens mittlerweile gestanden, dass sie keine Ahnung haben woran das liegt. :P)

12

Tuesday, June 10th 2008, 10:03pm

Naja, das mit der Genauigkeit war etwas schön geredet. Ich wollte nur darauf anspielen, dass Float 32 Bit ist und Double 64 Bit.

Ich glaube ich kann dir vorrechnen, wie das passiert, ich poste es, sobald ich es fertig hab.

This post has been edited 1 times, last edit by "Hafner" (Jun 10th 2008, 10:10pm)


13

Tuesday, June 10th 2008, 10:50pm

Arg, ich bin mathematisch echt aus der Übung. Naja, es ist auch schon spät.
Hier gibt es einen kleinen Überblick:
http://www-lehre.informatik.uni-osnabrueck.de/~ainf/2000/skript/node18.html

Hier ein kleiner Rechner:
http://www.h-schmidt.net/FloatApplet/IEEE754de.html
Man kann schon deutlich sehen, dass 1,3 oder 0,3 eben nicht GENAU gespeichert wird.

Weiterhin geht Genauigkeit verloren, wenn der Algorithmus (siehe 1. Link) die 2er Potenzen der Gleitkommazahlen anpasst.

Wenn man Gleitkommazahlen ausgibt, wird wohl immer gerundet, deswegen bekommt man bei
float f =1.3f;
System.out.println(f);
auch 1.3 geliefert und nicht 1.2999999523162842 (siehe 2. Link).

Bei den leppischen 32 Bit von Float ist nach der Berechnung der Rundungsfehler eben sichtbar.

Bedenke (!), dass Float und Double ihre Werte in Binärsystem speichern! Das was im Dezimalsystem so schön (also mit wenigen Nachkommastellen) aussieht wie 1.3 oder 0.3 kann im Binärsystem eine ziemlich krumme Zahl (also mit möglicherweise unendlich vielen Nachkommastellen) sein. Da wird natürlich irgendwann abgeschnitten.

Wenn es dich weitergehend interessiert, dann google mal nach IEEE 754-1985

PS:
Verdammt, ich weiß genau, dass ich an der Uni erfolgreich solche Dinger durchgerechnet habe.....

This post has been edited 2 times, last edit by "Hafner" (Jun 10th 2008, 11:12pm)


14

Wednesday, June 11th 2008, 7:11am

Uffff, also ich muss ganz ehrlich sagen, dass die Rechnungen für mich als Schüler zu hoch sind, verstehe da kaum etwas. : /

15

Thursday, June 19th 2008, 5:42am

Nimm einfach java.math.BigDecimal statt Double
Damit ist sichergestellt dass er richtig rechnet :)

Similar threads

Social bookmarks