Multiplikation nach der Schulmethode

F.S.WhiTeY

Bekanntes Mitglied
Hallo Leute,
ich versuche gerade zwei arrays nach der schulmethode zu Multiplizieren. Hab dazu auch schon was geschrieben aber irgendwo muss ich nen Fehler in meinem Code haben und ich find ihn nicht.

Ich weiß einfach nicht mehr weiter, vilt. findet ja jemand von euch den Fehler ?

Es sollen zwei Strings übergeben werden die Zahlen repräsentieren. Diese Zahlen sollen dann miteinander multipliziert werden und als String wieder zurück gegeben werden.

Das geht mit meiner Methode bis zu einer gewissen Stelle gut. Soll bedeuten, wenn ich mit BigInteger einen Vergleichswert ausgeben lasse sind die Strings bis zu einer gewissen Stelle gleich. danach wirds einfach nur falsch und ich komme nicht drauf woran es liegt.

Ich habe den Algorithmus auch schon für Integer Werte implemntiert, auch da war was falsch. Es sollte also nicht an dem hin und herrechnen mit Chars liegen sondern an der Multiplikationsmethode im allgemeinen.


LG WhiTeY

Java:
public String mulStringWithReminder(String s, String s2) {
		String erg = "";
		char[]a= new char[s.length()];
		char[]b= new char[s2.length()];
		int[]z=new int[a.length+b.length];
		int tmp = 0;
		int carry = 0;
		int j2 =0;
                //Zahlen umgedreht in Character Arrays Schreiben um damit rechnen zu können.
		 for (int i = 0; i < a.length; i++) {
			a[i]=s.charAt(a.length-1-i);
		}
		 for (int i = 0; i < b.length; i++) {
			b[i]= s2.charAt(b.length-1-i);
		}
		//Zwei Schleifen um alles miteinander zu Multiplizieren
		for (int j = 0; j < a.length; j++) {
			carry=0;
			for ( j2 = 0; j2 < b.length; j2++) {
		//ein wenig unschön aber für mich zur übersicht besser
               // Die zahlen 0-9 im ASCII Code haben den wert 48-56
              // Wenn man also 48 abzieht bekommt man den "Integerwert" und kann damit normal rechnen 
				int arg1 = a[j]-48;
				int arg2 = b[j2]-48;
             //Also rechnen wir ... stelle*stell+übertrag+das was an der ergebniss-stelle aus vorrangegangenen 
             //multiplikationen steht. Das erspart das zwischenspeicher der ergebnisse und das "Verschieben der Bits"
				tmp = arg1*arg2+carry+z[j+j2];
                                //übertrag berechnen
				carry = tmp / 10;
                                //ergebnis ohne übertrag an die vorgesehene stelle schreiben
				tmp=tmp%10;
				z[j+j2]=(tmp);
				
			}
			//Nun den übertrag noch verwerten
			int k= j+j2;
			while(carry!=0){
			k++;
			int t = carry % 10 +z[k];
			z[k]=(t);
			carry=carry/10;
			
			}
			
		}
		//Die zahl wieder als String repräsentieren 
		for (int i = z.length-1; i >=0; i--) {
			erg+=(char)(z[i]+48);
		}

        
		return erg;
	}
 
Hab' jetzt nicht genau geschaut, aber... das entweder mal im Debugger laufen lassen, oder zumindest sowas wie
Code:
System.out.println("Multipliziere Stelle "+i+" mit Wert "+a[i]);
System.out.println("und           Stelle "+j+" mit Wert "+b[j]);
...
System.out.println("Ergibt an Stelle "+k+" den Wert "+c[k]+" mit Übertrag "+carry);
und das dann mit 2 zweistelligen Zahlen testen, könnte schon helfen...
 
das habe ich schon getan, komischerweise für kleinre zahlen funktioniert der algorithmus auch.
Ich hab ihn auch schon per hand nachgespielt, das hat auch geklappt....

wie gesagt ich hab gemacht und getan aber ich komme nicht drauf warum ab einer gewissen stelle fehler auftreten. nen überlauf kann es ja nicht geben. die zahlen sind auf jeden fall < 110 von daher verstehe ich es einfach nicht wie es dazu kommt
 
Java:
public class Test2 {

   public static void main(String[] args) {

      for (int i = 0; i < 100; i++) {
         for (int j = 0; j < 100; j++) {
            int res1 = Integer.parseInt(mulStringWithReminder(String.valueOf(i), String.valueOf(j)));
            int res2 = i * j;
            if (res1 != res2) {
               System.out.println("ungleich: i=" + i + " j=" + j + " res1="
                     + res1 + " res2=" + res2);
            }
         }
      }
   }

   public static String mulStringWithReminder(String s, String s2) {
      String erg = "";
      char[] a = new char[s.length()];
      char[] b = new char[s2.length()];
      int[] z = new int[a.length + b.length];
      int tmp = 0;
      int carry = 0;
      int j2 = 0;
      // Zahlen umgedreht in Character Arrays Schreiben um damit rechnen zu
      // können.
      for (int i = 0; i < a.length; i++) {
         a[i] = s.charAt(a.length - 1 - i);
      }
      for (int i = 0; i < b.length; i++) {
         b[i] = s2.charAt(b.length - 1 - i);
      }
      // Zwei Schleifen um alles miteinander zu Multiplizieren
      for (int j = 0; j < a.length; j++) {
         carry = 0;
         for (j2 = 0; j2 < b.length; j2++) {
            // ein wenig unschön aber für mich zur übersicht besser
            // Die zahlen 0-9 im ASCII Code haben den wert 48-56
            // Wenn man also 48 abzieht bekommt man den "Integerwert" und kann
            // damit normal rechnen
            int arg1 = a[j] - 48;
            int arg2 = b[j2] - 48;
            // Also rechnen wir ... stelle*stell+übertrag+das was an der
            // ergebniss-stelle aus vorrangegangenen
            // multiplikationen steht. Das erspart das zwischenspeicher der
            // ergebnisse und das "Verschieben der Bits"
            tmp = arg1 * arg2 + carry + z[j + j2];
            // übertrag berechnen
            carry = tmp / 10;
            // ergebnis ohne übertrag an die vorgesehene stelle schreiben
            tmp = tmp % 10;
            z[j + j2] = (tmp);

         }
         // Nun den übertrag noch verwerten
         int k = j + j2;
         while (carry != 0) {
            k++;
            int t = carry % 10 + z[k];
            z[k] = (t);
            carry = carry / 10;

         }

      }
      // Die zahl wieder als String repräsentieren
      for (int i = z.length - 1; i >= 0; i--) {
         erg += (char) (z[i] + 48);
      }

      return erg;
   }

}

resultiert bei i=2 j=4 in einer
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at Test2.mulStringWithReminder(Test2.java:60)
at Test2.main(Test2.java:7)

Folglich stimmt da wirklich was nicht ;-)

EDIT: was ich sagen will ist, dass du entweder den falschen Code gepostet hast oder nicht richtig getestet oder deine Fehlerbeschreibung irgendwie nicht zum Problem passt.
 
Zuletzt bearbeitet:
der code sollte der richtige sein....

Java:
public String mulStringWithReminder(String s, String s2) {
		String erg = "";
		char[]a= new char[s.length()];
		char[]b= new char[s2.length()];
		int[]z=new int[a.length+b.length];
		int tmp = 0;
		int carry = 0;
		int j2 =0;
		 for (int i = 0; i < a.length; i++) {
			a[i]=s.charAt(a.length-1-i);
		}
		 for (int i = 0; i < b.length; i++) {
			b[i]= s2.charAt(b.length-1-i);
		}
		
		for (int j = 0; j < a.length; j++) {
			carry=0;
			for ( j2 = 0; j2 < b.length; j2++) {
				
				int arg1 = a[j]-48;
				int arg2 = b[j2]-48;
				tmp = arg1*arg2+carry+z[j+j2];
				carry = tmp / 10;
				tmp=tmp%10;
				z[j+j2]=(tmp);
				
			}
			
			int k= j+j2;
			while(carry!=0){
			k++;
			int t = carry % 10 +z[k];
			z[k]=(t);
			carry=carry/10;
			
			}
			
		}
		
		for (int i = z.length-1; i >=0; i--) {
			erg+=(char)(z[i]+48);
		}

        
		return erg;
	}


getestet mit einigen variationen z.b. :

93273528230*193273528230

Ergebnis BigInteger:
37354656 714472606932900
Ergebnis meiner methode:
127445565 714472606932900


Aufruf in der main :
BigInteger tt = new BigInteger("193273528230");
tt= tt.multiply(tt);
System.out.println(tt.toString());
System.out.println(ar.mulStringWithReminder("193273528230","193273528230");

Keine Exceptions, nur falsche werte ^^ mit allen werten die ich bis hierher getestet habe.

LG
 
Entweder bin ich zu müde oder du testest falsch. Habe die selbe Exception bei den selben Eingaben (scheint der selbe Code zu sein). Warum fängst du überhaupt bei 93273528230*193273528230 statt bei 0*0 an?
 
Cool dein Test hat es echt gebracht, ich hatte vorher nie eine exception.

Der fehler ist gefunden :

Java:
......

            int k= j+j2-1;//MINUS EINS MUSS DA HIN :D
            while(carry!=0){
            k++;
            int t = carry % 10 +z[k];
            z[k]=(t);
            carry=carry/10;
            
            }
.....


Danke dir, hast mir die nacht gerettet 😉
 

Zurück
Oben