Big Integer

rubenranjo

Mitglied
Hallo, das hier ist das erste Mal dass ich in ein Programmierforum poste, daher entschuldige ich mich gleich mal für den Fall, sollte ich was falsch gemacht haben 🙂.


So nun zu meiner Frage: Und zwar bin ich gerade ein Programm am schreiben was mir zu einer eingegebenen Zahl eine Funktion sucht(Beispiel ich habe die Zahl : 6761636 und ich will wissen ob es eine Funktion der Form ax^n dafür gibt).

Da ich aber mit beliebig großen Zahlen arbeiten möchte, kann ich natürlich die Datentypen int,double etc nicht verwenden.

Meine Idee war es dafür die Klasse BigInteger zu benutzen, welche allerdings nur eine Referenzvariable generiert.

Meine Frage ist jetzt gibt es eine Möglichkeit einen BigInteger Wert irgendwie in einer Schleife zu benutzen?
Das gesuchte Problem findet ihr im Codeauschnitt 63-104..

Vielen Dank für eure Hilfe



Java:
import java.util.Scanner;
import java.math.BigInteger;
public class Calc
{
    // Variablenzuweisung
    private double [] kk= new double [100];
    private double a,b,c,d,e;
    private double n ;
    private int suchzahl;
    private double i;
    private double suchzahlEnde;
    private double x,z,y,w;
    private double konstante_1,ergebnis;
    private String s;

  
   public void main(){
    System.out.print("Rechner     (1)  ");
    System.out.print("Suchzahl    (2)  ");
    System.out.print("Potenzsuche (3)  ");
  
    Scanner scan = new Scanner (System.in);
    int eingabe=scan.nextInt();
    if(eingabe == 1){
    System.out.print("Rechner  ");
    System.out.print("Erste Zahl  ");
    Scanner scan_3 = new Scanner (System.in);
    System.out.print("Operator  ");
    s=scan.next();
    System.out.print("Zweite Zahl  ");
    y=scan.nextDouble();
    
    
    
      if (s.equals("+")){
        z=x+y;
        }
    if (s.equals("-")){
        z=x-y;
        }if (s.equals("*")|| s.equals("x")){
        z=x*y;
        }
        if (s.equals("/")|| s.equals(":")){
        z=x/y;
        }
        System.out.print("Ergebnis= " + z);
   
    }
    if (eingabe== 2){
        System.out.println("Suchzahl eingeben: ");
        //Scanner scan_2 = new Scanner (System.in);
        //suchzahl=scan.nextInt();
        //BigInteger big = new  BigInteger();
        //suchzahl=big.add(suchzahl,0);
       Scanner scan_2 = new Scanner(System.in);
       BigInteger big = new BigInteger(scan_2.next());
      

      
       
  
   }
   if (eingabe== 3){
  System.out.println("Suchzahl eingeben: ");
        //Scanner scan_2 = new Scanner (System.in);
        //suchzahl=scan.nextInt();
        //BigInteger big = new  BigInteger();
        //suchzahl=big.add(suchzahl,0);
       Scanner scan_2 = new Scanner(System.in);
       BigInteger big = new BigInteger(scan_2.next());
      
           
        int basisStart = 1;
        int basisEnde = 100;
 
        int expStart = 1;
        int expEnde = 10;
 
        int konstanteStart = 1;
        int konstanteEnde = 100;
       
        double suchzahlEnde= suchzahl+100;
 
     
 
        for ( i = suchzahl; suchzahl <= suchzahl+100; suchzahl++) {
            System.out.println("Suchzahl: " + big);
 
            for (int konstante = konstanteStart; konstante <= konstanteEnde; konstante++) {
                for (int basis = basisStart; basis <= basisEnde; basis++) {
                    for (int exp = expStart; exp <= expEnde; exp++) {
 
                        int potenz = (int) Math.pow(basis, exp);
                        int ergebnis = potenz * konstante;
                        if (ergebnis == suchzahl) {
                            System.out.println(potenz + "___ " + konstante
                                    + "___ " + "Basis: " + basis + "___ "
                                    + "Exponent: " + exp + "___ " + "Positiv");
                        }
                    }
                }
            }
        }
    }
  
    }
   
       public void Wurzel(double zahl_wurzel)
    {
       double a=zahl_wurzel;
       double b=1;
     
       //Satz des Heron wird 1000 mal durchgeführt ??? Methode finden um solange durchzuführen bis a = b ist
        for(i=1; i<1000; i++){
        b=(a+b)/2;
        a=zahl_wurzel/b;
      
      
        }
  
      
        System.out.println(a);
    }
      
     
      
     
   
}
 
Sowas?

Java:
BigInteger a = new BigInteger("987654321");
for(BigInteger b = new BigInteger("123456789"); b.compareTo(a) < 0; b = b.add(BigInteger.ONE)) {
    System.out.println(b);
}
 
BigInteger bietet Methoden an, die du anstelle der normalen Operator (+,-,*,/) verwenden kannst.
Damit kannst du dann alle Werte mittels BigInteger berechnen.
 
Ok das heißt ich muss in all meinen 4 verschachtelten Schleifen alle Werte durch BigInteger ersetzen ....jäh wird das ein Spaß ....vielen Dank für die Hilfe
 
Ok mein Problem hat sich nicht gelöst, ich komme seit Tagen einfach nicht weiter: Vielleicht sieht ja jemand von euch wo ich einen Denkfehler habe hier mein Lösungsansatz:


Java:
if (eingabe== 3){
       Scanner scan_1 = new Scanner(System.in);
       Scanner scan_a = new Scanner(System.in);
       Scanner scan_b = new Scanner(System.in);
       Scanner scan_c = new Scanner(System.in);
       Scanner scan_d = new Scanner(System.in);
       Scanner scan_e = new Scanner(System.in);
       Scanner scan_f = new Scanner(System.in);
    
       BigInteger suchzahl = new BigInteger(scan_1.next());
       BigInteger wert = new BigInteger( "100");
       BigInteger suchzahlEnde = suchzahl.add(wert);   
       BigInteger basisEnde = new BigInteger(scan_f.next());
 
      String expStart = scan_c.next();
      BigInteger expEnde = new BigInteger (scan_d.next());
 
        BigInteger  konstanteEnde = new BigInteger(scan_b.next());
       
    
 
     
 
        for ( BigInteger i = new BigInteger(scan_1.next()); i.compareTo(suchzahlEnde) <0; i.add(BigInteger.ONE)) {
            System.out.println("Suchzahl: " + suchzahl);
 
            for (BigInteger i_2 = new BigInteger("1"); i_2.compareTo(konstanteEnde) <0; i_2.add(BigInteger.ONE)) {
                for (BigInteger i_3 =new BigInteger("1"); i_3.compareTo(basisEnde) <0; i_3.add(BigInteger.ONE)) {
                    for (BigInteger i_4 =new BigInteger("1"); i_4.compareTo(expEnde) <0; i_4.add(BigInteger.ONE)) {
 
                      
                       int  i3= i_3.intValue();
                        int  i4= i_4.intValue();
                        
                        BigInteger potenz = i_3.pow(i4);
                        BigInteger ergebnis = potenz.multiply(i_2);
                        if (true) {
                            System.out.println(potenz + "___ " + i_2
                                    + "___ " + "Basis: " + i_3 + "___ "
                                    + "Exponent: " + i_4 + "___ " + "Positiv");
                        }
                    }
                }
            }
        }
    }
  
    }


Also zu einer eingegeben Zahl+-100 soll eine Funktion der Form ax^n gefunden werden!!! aber Ergebnis sind nur Einsen
 
- Ich nehme mal an, das
Code:
if(true)
in Zeile 38 ist nur ein Überbleibsel Deiner Versuche?

- Du brauchst nicht 7 Scanner auf System.in. Es reicht einer, der ganz am Anfang des Programms instanziert wird und dann überall verwendet werden kann.

- Es ist nicht verwunderlich, dass Du bei einer vierfach verschachtelten for-Schleife Tage damit zubringst, den Ablauf nachzuvollziehen. So eine Struktur ist ein No-Go. Deswegen keine direkte Lösung. Nur ein Ansatz zur Entzerrung Deines Codes. Überlege, was jede einzelne Schleife macht und lager sie in eine Methode aus.

Z.B. Die innerste Schleife sieht so aus, als würde sie eine Potenz suchen. (Kann sein, dass ich das falsch sehe, aber hier kommt's mir auf die Erklärung an.) Schreibe also eine Methode findePotenz, die geeignete Parameter und Rückgabetyp hat. Mit den anderen Schleifen verfährst du genauso. Ziel ist, deinen Gesamtalgorithmus in Teilschritte zu zerlegen, denen man einen sprechenden Namen gibt. So kann man die Teilschritte einzeln testen und weiß anhand des Namens auch, wofür er überhaupt da ist.
 
Die for Schleifen dienten ja dazu alle möglichen Funktionen durchzuprüfen:

Beispiel ich habe die Zahl 1024 dann prüft er:


1*1^1
1*1^2
1*1^3
.....1*1^n

dann erhöht erhöht er die Basis um 1

1*2^1
1*2^2
1*2^3
.....1*n^n

dann wird die Konstante davor um 1 erhöht

2*1^1
n*n^n

Dann wird dasselbe nochmal für 1025 durchgeführt ....also bis ein bestimmter Wert erreicht wird also sucht er für jede Zahl von 1024-1124.

Und das kann ich doch nur mit einer verschachtelten Schleife lösen sonst wird der Aufwand zu groß...
Hat auch bei der Verwendung von Double anstatt BigInteger prima funktioniert
Ich gehe aber davon aus dass du mir nur helfen wolltest dass ich genau verstehe was ich da mache deshalb werde ich mal versuchen es in Teilschritte zu spalten um Fehler nachzuvollziehen.

Vielen Dank noch für deine Hilfe !!
ps. Ja das true war nur ein Test um zu schauen was er überhaupt ausgibt... Eigentlich gehört da Suchzahl==Ergebnis hin also um das Beiscpiel von oben zu verwenden 1024==ax^n
 
Und das kann ich doch nur mit einer verschachtelten Schleife lösen sonst wird der Aufwand zu groß...
Nein, wohl strukturierter und einfach zu lesender Code führt zu weniger Aufwand. Es gibt nie und unter keinen Umständen zwingende Gründe für tiefe Verschachtelungen im Quellcode. Man kann immer alles schön in Methoden aufteilen. (Am Ende ist der Ablauf natürlich mehrfach verschachtelt, weil sich die Methoden ja gegenseitig aufrufen, aber eben nicht im Quellcode.)
 
Mal ein Ansatz zum Refactoring: Wenn ich Deine Erklärung richtig verstehe, dann benötigt Deine Prüfung vier Parameter: Faktor, Basis, Exponent und die zu Prüfende Zahl sie liefert true zurück, wenn die Funktion zur Zahl passt, sonst false. Da kann man schon eine Methode draus machen.

Java:
static boolean validCombi(BigInteger number, BigInteger factor, BigInteger base, int expo) {

  BigInteger functionResult = factor.multiply(base.pow(expo));

  return number.equals(functionResult);
}
Nun die Schleifen aufgeteilt auf Methoden:
Java:
static void searchFunctions(BigInteger number, BigInteger maxFactor, BigInteger maxBase, int maxExpo) {
  for(BigInteger currentFactor = BigInteger.ONE; currentFactor.compareTo(maxFactor) < 0 ; currentFactor.add(BigInteger.ONE)) {
     incrementBase(number, currentFactor, maxBase, maxExpo);
  }
}

static void incrementBase(BigInteger number, BigInteger currentFactor, BigInteger maxBase, int maxExpo) {
  
  for(BigInteger currentBase = BigInteger.ONE; currentBase.compareTo(maxFactor) < 0; currentBase.add(BigInteger.ONE) {
    incrementExpo(number, currentFactor, currentBase, maxExpo);
  }
}

static void incrementExpo(BigInteger number, BigInteger currentFactor, BigInteger currentBase, int maxExpo) {

  for(int currentExpo = 1; i < maxExpo; i++) {
     if (validCombi(number, currentFactor, currentBase, currentExpo) {
      System.out.println(String.format(
        "Funktion gefunden: %s*%s^%s=%s", currentFactor, currentBase, currentExpo, number));
     }
  }
}
So grob könnte das aussehen. Jetzt kannst du die Methoden von hinten nach vorne durchtesten.
 

Neue Themen


Zurück
Oben