• Das kreative Thema des Monats Oktober wird vor allem diejenigen unter Euch besonders ansprechen, denen Do-it-yourself quasi im Blut liegt. Zeigt uns Eure Improvisationskünste oder fotografiert, was andere Leute sich so im Alltag zusammengestrickt haben. --> Zum Mitmachen bitte hier klicken

Modulo und Doubles... (JAVA)

Bilbao

Wohlschmecker aus Vierlanden
Registriert
25.01.06
Beiträge
238
hi leute

hab mal ne frage..

Es geht um folgendes ich hab einen double wert und versuche diesen so weit zu erweitern, dass er eine ganze Zahl wird.

Also folgendes

aus : 12.3123

sollte 123123 werden (mit einem vermerk es wurde um 4 * 10 erweitert)

Code:
	public static void main(String[] args) {
		double b= 12.33123412;
		int q=0;
		while((b%1)!=0){
			System.out.println(b);
			b=b*10;
			q++;
			System.out.println(b);
			System.out.println(q);
			
			
		}
		
		System.out.println(q+" "+b);
	}

So gedanklich betrachtet macht es ja genau das
aber aus dem log geht folgendes hervor
12.33123412
123.31234119999999
1
123.31234119999999
1233.123412
2
1233.123412
12331.23412
3
12331.23412
123312.3412
4
123312.3412
1233123.412
5
1233123.412
1.2331234120000001E7
6
1.2331234120000001E7
1.2331234120000002E8
7
1.2331234120000002E8
1.2331234120000002E9
8
1.2331234120000002E9
1.2331234120000002E10
9
1.2331234120000002E10
1.2331234120000002E11
10
1.2331234120000002E11
1.2331234120000002E12
11
1.2331234120000002E12
1.2331234120000002E13
12
1.2331234120000002E13
1.2331234120000002E14
13
1.2331234120000002E14
1.2331234120000002E15
14
1.2331234120000002E15
1.2331234120000002E16
15
15 1.2331234120000002E16
durch das modulo werden am ende periode 9 angehängt dem entsprechend läuft es immer bis 15 (egal was ich eingebe)

weiss einer wie ich dieses Problem umgehen kann bzw. welche andere Methode eher passt zu meinem Problem

Schon mal danke im voraus für antworten
 
Das Problem ist, dass du Fließkommawerte mit != vergleichst. Und das geht im allgemeinen Fall, wegen fehlender Präzision, schief. Lösung wäre ein Vergleich der Werte mittels „Epsilon“, welches eine gewisse Toleranz erlaubt. In deinem Fall zum Beispiel so:

Code:
private static final double EPSILON = 0.000001;
…

while (b % 1 > EPSILON) {
   …
}


Lektüre:

http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
http://mindprod.com/jgloss/floatingpoint.html
http://www.ibm.com/developerworks/java/library/j-jtp0114/
 
Sry.. ich hab gemerkt das problem ist was ganz adneres...

es ist nicht der modulo der das problem verursacht ..

die Operation bei dem double *10 ghet nicht richtig...
was eingetlich ziemlich seltsam ist... er wird nämlich ungenau bei *10... das verursacht das problem.. es wird ja nie eine ganze zahl weil immer 9er nachrücken (beim multiplizieren mit 10)

kann mir das einer erklären?

(ich hab schon verstnaden das es eben die eigenart von double sind weil man nachkomma zahlen nur perfekt darstellen kann wenn sie einer negativen 2er potenz entsprechen 2^-1 2^-2 etc...) aber ein einfacher *10 ....

edit:

Okay das problem ist immer noch folgendes selbst wenn ich anfange zu sagen das ich ein Epsilon habe mit dem ich runde (bzw. vergleiche) hab ich immer noch das problem, dass ich ja nicht weiss wie viele nachkoma stellen mein double hat und zweitens änder es ja nicht das problem mit dem *10 denn slebst wenn ich dann epsilon habe werde ich am ende immer 9er haben die den wert erheblich verändern
 
Zuletzt bearbeitet:
Hallo,

schau dir am besten mal den Artikel zu IEEE 754 an ( http://en.wikipedia.org/wiki/IEEE_754-1985 ). Es ist wichtig zu verstehen wie Gleitkommazahlen in Java funktionieren. Is ist glaube ich enfacher, den wert in einen String zu wandeln und dann manuel das Komma zu verschieben.
 
Zur Visualisierung:
Code:
public class Test {

	public static void main(String[] args) {
		double b = 12.33123412;
		int q = 0;
		DecimalFormat myFormatter = new DecimalFormat(
				"00000000000000000.0000000000000000");

		while ((b % 1) != 0) {
			System.out.printf("%3d %sf%n", q, myFormatter.format(b));
			b = b * 10;
			q++;
		}
	}
}