Wie kann ich in Java eine periodische Zahl in einen Bruch umwandeln?

Willibergi  27.03.2021, 16:25

Wie sieht denn dein Programm bisher aus?

lalemos 
Fragesteller
 27.03.2021, 16:29

Also ich schaue wie viele Nachkommastellen ich habe (l = Nachkommastellen) und mache dann das : z = (long) (wert * Math.pow(10, l));

    n = (long) Math.pow(10, l);

4 Antworten

Dein Verfahren findet den exakten Bruch zur Dezimaldarstellung einer Zahl. In Java wird ein double-Wert vermutlich auf 15 oder 16 Stellen genau umgewandelt und dann alle Nullen am Ende wieder abgeschnitten.

Die 0.2 wird intern durch den Wert 0.200000000000000011102230246251565404236316680908203125
repräsentiert. Dein Ergebnis 1/5 kommt nur daher, dass Java die hinteren Stellen abschneidet und das Ergebnis im 10er-System nur wenige Dezimalstellen hat. Bei Brüchen, die im Dezimalsystem nicht abbrechen, kann das gar nicht funktionieren.

Wenn Du zum double-Wert 1.0/3 den „falschen“ Bruch 1/3 finden willst, musst Du die Aufgabenstellung präzisieren:

  • Finde zu einem double d den Bruch z/n mit dem kleinsten Nenner n, für den d==double(z)/n ist.

Das lässt sich effizient mit dem Stern-Brocot-Baum lösen. Salopp: Hangle Dich so lange den Baum hinunter, bis Du auf einen Wert z/n mit d==double(z)/n stößt.

Was hältst du denn von folgendem Verfahren:

Suche einen Bruch für pi = 3,1415926535897932384626433832795

Unten Oben   "Mittel"            Fehler
  3/1   4/1  7/2 = 3.5           +11,4%
  3/1   7/2  10/3 = 3.333..      +6,1%
  3/1  10/3  13/4 = 3,25         +3,5%
  3/1  13/4  16/5 = 3,2          +1,9%
  3/1  16/5  19/6 = 3,1666...    +0,8%
  3/1  19/6  22/7 = 3,1428...    +0,04% !
  (22/7 ist die Handwerkernäherung)
  3/1  22/7  25/8 = 3,125        -0,53%
  (jetzt wird's wieder schlechter)
 25/8  22/7  47/15 = 3,1333...   -0,26%
 47/15 22/7  69/22 = 3,13636...  -0,17%
 69/22 22/7  91/29 = 3,1379...   -0,12%
 91/29 22/7  113/36 = 3,1388...  -0,086%
113/36 22/7  135/43 = 3,1395...  -0,0655%
135/43 22/7  157/50 = 3,14       -0,05%
157/50 22/7  179/57 = 3,14035..  -0,0395% 
  (so gut war ich schon einmal)  

usw.

Das habe ich letztens irgendwo aufgeschnappt, aber irgendwie überzeugt mich das selbst nicht so. Vielleicht habe ich es auch falsch in Erinnerung. Besser (=schneller), aber nicht ganz so einfach zu implementieren, wäre eine Kettenbruchentwicklung.


0.333333 = 333333 / 1000000 und nicht 3333333333333333/10000000000000000

0.Periode(3) ist 3/9 = 1/3

Entsprechend ist 0.Periode(234) = 234/999 = 76/333

Wenn die Periode später anfängt:

0.23Periode(456) = 23/100 + 456/99900


lalemos 
Fragesteller
 27.03.2021, 16:18

Bei 0.33333 hab ich eigentlich periodisch gemeint. Ich werde mal versuchen das auszuprogrammieren. Danke.

0
Schachpapa  27.03.2021, 16:27
@lalemos

Wie unterscheidest du 0.333 = 333/1000 von 0.Periode(3)?

Oder 0.272727 = 272727/1_000_000 von 0.Periode(27) = 27/99 = 3/11 ?

0
lalemos 
Fragesteller
 27.03.2021, 16:35
@Schachpapa

Also ich mache eigentlich nur das, wie ich oben auf die Nachfrage geantwortet habe.

0
Von Experte MrAmazing2 bestätigt
Wie kann ich das besser lösen?

Gar nicht -- wenn in ein Double 0,333 reinpasst (es passt mehr rein, aber ich weiß nicht auswendig, wie viel, also sage ich hier jetzt einfach fürs Beispiel mal, dass nur 0,333 reinpasst), dann ist das ja 0,333000000000... und nicht 0,33333333..., das bedeutet, dass es einfach falsch wäre, wenn du 1/3 rauslesen würdest.


lalemos 
Fragesteller
 27.03.2021, 16:56

Ja, das stimmt schon, aber das liegt daran, dass man keine unendlichen Werte speichern kann, aber 1/3 wird ja auch als 0,333... gespeichert und nicht unendlich.

0
sonderdings  27.03.2021, 17:16
@lalemos

Naja, man kann ein Drittel nicht als Dezimalzahl speichern, aber speichern kann man es, als Bruch. Man kann nur irrationale Zahlen nicht "komplett" speichern (zumal man sie ja auch nicht komplett kennt), und sogar da kann man ja z.B. dann "Wurzel 5" oder 22/3 * PI speichern.

Aber aus "0,333...3 (Schluss)" auf 1/3 zu kommen wäre einfach falsch, denn dann fehlen alle 3er hinter der letzten 3, um wirklich 1/3 zu haben.

0