Programmieren in Java < Mathe-Software < Mathe < Vorhilfe
|
Hallo allerseits,
ich intereßiere mich für ein mathematisches "Problem" :
Wenn man eine rationale Zahl q geeignet mit einer natürlichen Zahl p erweitert, so daß p*Nenner(q) zu einer Zehnerpotenz wird, dann ist q in Dezimalschreibweise endlich. D.h. q besitzt nur endlich viele Nachkommastellen.
Mathematisch ist mir das klar, einen Beweis benötige ich nicht.
Ich habe diese Frage in keinem Forum auf anderen Internetseiten gestellt.
Ich möchte dieses Problem mit Java realisieren. Hier sind meine Grundgedanken:
Zuerst laße ich eine integer Zahl m einlesen (m soll der Nenner des zu testenden Bruches sein). Anschließend setze ich:
double x = 0;
for (int i = 1; i <= 100; i++){
x = Math.pow(10,i)/m;
* //if x ist ein integer, break, syso (i)
}
Ich möchte an der mit * gekennzeichneten Stelle folgendes tun:
Wenn x irgendwann in der for-Schleife ganzzahlig wird, soll das i ausgegeben werden, für das x eben ganzzahlig ist. Dann hätte ich diejenige Zehnerpotenz gefunden, auf die sich der Bruch bzw der Nenner m erweitern ließe.
Also: Wie kann ich an der Stelle * einen "int-Test" durchführen?
Ich habe mir schon überlegt, vor der main Methode eine Funktion bzw einen boolean zu schreiben und dann:
//if (isInt(x) = true){system.out.println (+i)}
Wie würde ich überhaupt an den Zählindex i rankommen?
Ich bin ja gerade an dem i_null intereßiert, für das x integer ist.
Okay, ich hoffe jemand weiß, was ich meine und hat eine Idee
|
|
|
|
Hi,
ich kenn mich nicht mit java aus. Aber ich würde:
- eine While Schleife verwenden (gut du kannst auch die For-Schleife missbrauchen und gehst per break raus)
- i nicht in der Schleife deklarieren, wie sagen die Informatiker "Function-scope" oder so etwas (also auf jeden Fall vor der Schleife, dann hast du dein i_Null
- falls kein isint vorhanden ist, dann gibt es meistens round und "if round(x)-x<eps" mit eps = [mm] 10^{-28} [/mm] oder so => es ist Ganzzahl
|
|
|
|
|
Status: |
(Antwort) fertig | Datum: | 22:20 Mi 20.04.2011 | Autor: | rainerS |
Hallo!
> Hallo allerseits,
>
> ich intereßiere mich für ein mathematisches "Problem" :
>
> Wenn man eine rationale Zahl q geeignet mit einer
> natürlichen Zahl p erweitert, so daß p*Nenner(q) zu einer
> Zehnerpotenz wird, dann ist q in Dezimalschreibweise
> endlich. D.h. q besitzt nur endlich viele
> Nachkommastellen.
>
> Mathematisch ist mir das klar, einen Beweis benötige ich
> nicht.
> Ich habe diese Frage in keinem Forum auf anderen
> Internetseiten gestellt.
> Ich möchte dieses Problem mit Java realisieren. Hier sind
> meine Grundgedanken:
>
> Zuerst laße ich eine integer Zahl m einlesen (m soll der
> Nenner des zu testenden Bruches sein). Anschließend setze
> ich:
>
> double x = 0;
> for (int i = 1; i <= 100; i++){
> x = Math.pow(10,i)/m;
> * //if x ist ein integer,
> break, syso (i)
> }
>
> Ich möchte an der mit * gekennzeichneten Stelle folgendes
> tun:
>
> Wenn x irgendwann in der for-Schleife ganzzahlig wird, soll
> das i ausgegeben werden, für das x eben ganzzahlig ist.
> Dann hätte ich diejenige Zehnerpotenz gefunden, auf die
> sich der Bruch bzw der Nenner m erweitern ließe.
>
>
> Also: Wie kann ich an der Stelle * einen "int-Test"
> durchführen?
Ich denke, du machst hier mehrere Fehler.
1. Zahlen von Typ int sind in der Größe beschränkt auf das Intervall [mm] $[-2^{31},2^{31}-1]$. [/mm] Das heisst, mit größeren Werten für m als etwa 2 Milliarden kannst du nicht rechnen.
2. Du berechnest [mm] $10^i$ [/mm] als double-Wert, für i von 1 bis 100. [mm] $10^{100}$ [/mm] liegt zwar noch im Zahlenbereich eines double-Werts, kann aber mit seinen etwa 332 Binärstellen in den 52 Bits der Mantisse nicht mehr genau dargestellt werden; 280 Binärstellen werden durch Runden abgeschnitten. Wenn du durch m dividierst, wird wieder gerundet.
Besser ist es, wenn du mit java.math.BigInteger rechnest, da sind die Zahlen in der Größe nicht begrenzt und du vermeidest Rundungsfehler.
Außerdem kannst du das Problem erheblich vereinfachen, wenn du dir überlegst, dass m genau dann zu einer Zehnerpotenz erweitert werden kann, wenn die Primfaktorzerlegung nur aus Potenzen von 2 und 5 besteht - weil [mm] $10^n=2^n*5^n$ [/mm] ist und damit jeder Teiler von [mm] $10^n$ [/mm] auch nur die Form [mm] $2^i*5^j$ [/mm] haben kann.
Das heisst, dass du eigentlich nur solange durch 2 und 5 teilen musst bis entweder 1 herauskommt oder ein Rest übrigbleibt, etwa so:
1: | boolean teste(BigInteger m) {
| 2: |
| 3: | final BigInteger two = new BigInteger("2");
| 4: | final BigInteger five = new BigInteger("5");
| 5: | BigInteger result[2];
| 6: |
| 7: | if (m.compareTo(BigInteger.ZERO) < 1) {
| 8: | // keine positive Zahl m
| 9: | return false;
| 10: | }
| 11: |
| 12: |
| 13: | while (! m.equals(BigInteger.ONE)) {
| 14: | result = m.divideAndRemainder(two);
| 15: | if (result[1].equals(BigInteger.ONE)) {
| 16: | // Rest ist 1 => Zahl war ungerade
| 17: | break;
| 18: | }
| 19: | m = result[0]; // m durch m/2 ersetzen
| 20: | }
| 21: |
| 22: | // Hier ist m ungerade
| 23: | while (! m.equals(BigInteger.ONE)) {
| 24: | result = m.divideAndRemainder(five);
| 25: | if (! result[1].equals(BigInteger.ZERO)) {
| 26: | // Rest ist nicht 0 => Zahl war nicht durch 5 teilbar
| 27: | return false;
| 28: | }
| 29: | m = result[0]; m durch m/5 ersetzen
| 30: | }
| 31: | return true;
| 32: | } |
Viele Grüße
Rainer
|
|
|
|