Schleife mit BigInteger

Status
Nicht offen für weitere Antworten.

andreas2505

Bekanntes Mitglied
Hallo,

icst es möglich z.B. eine for-Schleife zu machen in der auch BigInteger als Laufvariable genommen wird.

z.B.:

Java:
public static BigInteger potenz(BigInteger basis, BigInteger exp) {
        BigInteger result = basis;
        for (BigInteger i=1; i<exp; i++) {
            result = result * basis;
        }
        return result;
    }
 
Wenn du den Code doch schon geschrieben hast, warum kompilierst du ihn nicht einfach und kuckst nach? Ich weiss es grad selber nicht, denke aber schon. Allerdings weiss ich nicht ob sowas wie "<" auf BigInteger definiert ist, d.h. das musst du dann evtl über passende Methoden lösen, zB: i.lessThan(BigInteger.ONE) oder sowas.
 
Tja, deine Syntax ist ja hübsch, aber leider tun sich die Java-Bonzen noch etwas schwär mit Operatorüberladungen...

Java:
public static BigInteger potenz(BigInteger basis, BigInteger exp) {
        BigInteger result = basis;
        for (BigInteger i=BigInteger.ONE; i.compareTo(exp)<0; i = i.add(BigInteger.ONE)) {
            result = result.multiply(basis);
        }
        return result;
    }
Es gibt effizientere Wege zur Berechnung der Potenz. Der Exponent als BigInteger ist auch nicht sinnvoll, denn wenn der größer als ein long (2^64) wird, ist dein Speicher sowieso voll - selbst wenn die Basis nur 2 ist.
 
Vielleicht daran, dass 1 ein int und kein BigInteger ist?

Ganz im Ernst, das sind zwei verschiedene Paar Schuhe: int ist ein primitiver Typ, von dem es Listerale gibt (0, 1 , 4711, 0xabcd), und BigInteger ist eine Klasse, die man gebastelt hat, damit Zahlen beliebig groß werden können. Als Klasse stehen BigInteger die "primitiven" Operatoren nicht zur Verfügung, genausowenig, wie +, - usw. bei den anderen Zahlen-Wrapper-Klassen (Integer, Long...) funktionieren.
 
Zuletzt bearbeitet:
hab noch ne frage:

ich habe nun die folgende zeile:

Java:
        BigInteger basis = (BigInteger) (Math.random().multiply((n.subtract(new BigInteger("2")))).add(new BigInteger("2")));

mit dieser will ich basis = Zufallszahl zwischen 2 und n-2 erzeugen

aber da kommt die fehlermeldung :

double cannot be dereferenced.

Was muss ich da ändern?
 
warum so viel auf einmal und dann die Welt nicht mehr verstehen?

double d = Math.random();
d.multiply(..);

??

an einem double kann man keine Methode aufrufen
 
new BigInteger("2")
bekommst du hin,
da ist es nicht zu erraten, wie du wohl aus einem double oder noch anderen Werten ein Objekt machst?
schau dir doch alle Konstruktoren und sonsten Methoden von BigInteger an, besonders die statischen

BigInteger ist allerdings wirklich nur für ganze Zahlen gedacht, während Math.random() einen Wert zwischen 0 und 1 liefert,
dieses Dilemma kann ich auch nicht für dich lösen..
 
Irgendwie scheint es dir nicht bewusst zu sein, was ein BigInteger ist.
Ist dir klar, dass mit solchen Zahlen einfach nichts, was exponentiellen Aufwand oder exponentiellen Speicherplatzverbrauch hat, zu deinen Lebzeiten funktionieren kann?
  • Wenn du die minimal sinnvollen Argumente [c]basis=2[/c] [c]exp=2^64[/c] nimmst, dann brauchst du etwa 2097152 Terabyte um das Ergebnis abzuspeichern
  • mal angenommen du könntest pro Sekunde 1 Milliarde BigInt-Multiplikationen durchführen (das ist sicher nicht der Fall), dann brauchst du für den minimalen sinnvollen Exponenten mit deiner Methode etwa 558.5 Jahre für die Berechnung. Siehe Square and Multiply.
  • zufälligen BigInt würfeln zu wollen, und dafür Math.random() zu verwenden ist totaler blödsinn, weil double eben nur die vergleichsweise lächerlichen 2^64 verschiedene Zustände annehmen kann (bzw. hier nicht mal das, wegen des Intervalls). Da müsste man eher ein ganzes byte-Array mit zufälligen Werten füllen, und daraus BigInt erzeugen. Oder einfach in die API schauen und BinInteger(int, Random) nehmen.
 
Zuletzt bearbeitet:
wer sagt denn, dass der Exponent nicht 3 oder 5 ist, sondern 2^64?
dass für kleine Exponenten ein anderer Typ reicht, wurde schon erwähnt, der Rest zu TeraByte + Jahren ist doch sinnlos, besonders ohne Smily
 
also abgesehen davon, dass es vlt. nicht der beste weg ist, habe ich es immer noch nicht rausgefunden wie ich es mache, dass es funktioniert.
Finde nur die Methode valueOf bei BigOInteger, aber damit klappts auch nicht.
Kann mir nicht schnell wer einfach die richtige Variante schreiben?
 
was soll denn genau passieren?
gibt doch mal paar Beispielrechnungen

Math.random() liefert immer eine Zahl zwischen 0 und 1, als BigInteger ist das standardmäßig 0,
brauchst du vielleicht BigDecimal?..
 
also ich will damit eine zufällige zahl zwischen 2 und n-2 erzeugen (eine ganze zahl)
Ich nehme halt BigInteger, weil sie auch sehr groß sein soll/kann.

Ich weiß ja dass Math.random eine Zahl zwischen 0 und 1 erzeugt, aber wenn man sie mit (n-2) multipliziert und +2 macht hat man ja den entsprechenden Bereich.
Und durch das Casten müsste es dann ein BigInteger sein,aber das klappt ja nicht richtig.
 
dann nimm BigDecimal, wandle n und den double-Wert in BigDecimal um, das geht nun wirklich über Konstruktoren/ valueOf usw,
mutipliziere, und am Ende zum BigInteger runden
 
also ich will damit eine zufällige zahl zwischen 2 und n-2 erzeugen (eine ganze zahl)
Ich nehme halt BigInteger, weil sie auch sehr groß sein soll/kann.

Ich weiß ja dass Math.random eine Zahl zwischen 0 und 1 erzeugt, aber wenn man sie mit (n-2) multipliziert und +2 macht hat man ja den entsprechenden Bereich.

[0...n-2] alles +2 = [2...n]
Du müsstest das ganze mit (n-4) multiplizieren wenn du am ende auf n-2 kommen willst.

Casten ist ne schlechte Idee, BigInteger sind eben keine primitiven int.
 
das passt schon mit den grenzen!

Aber zu dem davor:
Wenn ich das als double nehme und dann in BigDecimal umwandle, dann hab ich ja wieder das Problem dass die größe des doubles begrenzt ist.
oder irre ich mich da?
 
so genau muss es werden?
nun, dann musst du eine riesige Zufallszahl erzeugen, je nachdem wie groß n ist
für n = 43490803480583420840980498 brauchst du ungerechnet sagen wir mal 40 Bits

einfacheres Beispiel:
n = 5, dann 3 Bits
also eine Zufallszahl 0-7

problematisch sind nun die Fälle 6 und 7, die am besten ignorieren,
solange Zufallszahlen wiederholen, bis das Ergebnis zwischen 0 und 5 liegt oder 1 bis 5 oder +2 = 3-7, das ist variabel

-----------

das ganze geht auch anschaulicher im Zehner-System,
wenn n = 43490803480583420840980498 20 Stellen hat,
dann bilde 20 Zufallszahlen 0-9, füge die zusammen (etwa als String) und du hast eine entsprechend große Zufallszahl,
wieder zu große Zahlen ignorieren,
wenn man n entsprechend analyisiert könnte man gleich bei der ersten Ziffer alles > 4 ignorieren
 
Zuletzt bearbeitet von einem Moderator:
@SlaterB:
wer sagt denn, dass der Exponent nicht 3 oder 5 ist, sondern 2^64?
Weil es nicht danach aussieht, als wollte der OP irgendein allgemeines Interface implementieren, das BigInteger-wertige Exponenten vorschreibt? In irgendeinem allgemeineren Kontext würde noch sinn machen, isoliert macht's aber keinen Sinn, das sollte das Beispiel veranschaulichen... Smileys hab ich hier auch noch welche vorrätig: 😉

@OP:
Java:
BigInteger n=new BigInteger("123456789987654321");
BigInteger r=new BigInteger(n.bitLength(),new Random())
.mod(n.subtract(new BigInteger("4"))).add(new BigInteger("2"));
sowas ungefähr...? Was bitLength genau liefert weiß ich nicht, paar bits draufaddieren schadet evtl nicht.
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben