Laden...

Rechnen mit strings

Erstellt von Big Al vor 18 Jahren Letzter Beitrag vor 17 Jahren 20.612 Views
B
Big Al Themenstarter:in
342 Beiträge seit 2006
vor 18 Jahren
Rechnen mit strings

Moin, moin,
ich hatte nix zu tun und so hab ich mal ne class geschrieben,
mit der manmit Zahlen, die als strings vorliegen, rechnen kann.
Natürlich geht das auch mit int.Parse(...), aber die Zahlen können länger sein.
Hier der Code:


using System;
using System.Collections;
using System.Collections.Generic;

namespace AlexanderF.Math.BigCalc
{
	public class BigArithmetics
	{		

		public static string SumUp(string addend1, string addend2)
		{
			int transnum = 0;//Übergangszahl(0 oder 1)
			string tempnum = string.Empty;//Ergebnis
				
			
			//wenn der erste Summand negativ ist
			if((addend1.StartsWith("-")) && (!addend2.StartsWith("-")))
			{
				tempnum = Substract(addend1.Remove(0, 1), addend2);
				if(tempnum.StartsWith("-"))
				{
					tempnum = tempnum.Remove(0, 1);
				}
				else
				{
					tempnum = "-" + tempnum;
				}
				return tempnum;
			}
			
			//wenn der zweite Summand negativ ist
			else if((!addend1.StartsWith("-")) && (addend2.StartsWith("-")))
			{
				return Substract(addend1, addend2.Remove(0, 1));
			}
			
			//wenn beide Summanden negativ sind
			else if((addend1.StartsWith("-")) && (addend2.StartsWith("-")))
			{
				return "-" + SumUp(addend1.Remove(0, 1), addend2.Remove(0, 1));
			}
			
			//Anpassen der Längen			
			if(addend1.Length < addend2.Length)
			{
				addend1 = addend1.PadLeft(addend2.Length, '0');
			}
			else if(addend2.Length < addend1.Length)
			{
				addend2 = addend2.PadLeft(addend1.Length, '0');
			}
			
			//Durchgang für jede Ziffer
			for(int counter = addend1.Length - 1; counter >= 0; counter--)
			{
				int num = transnum;	
				num += int.Parse(addend1[counter].ToString()) + int.Parse(addend2[counter].ToString());

				if(num >= 10)
				{
					if(counter != 0)
					{
					transnum = 1;
					tempnum = num.ToString()[1] + tempnum;
					}
					else
					{
					tempnum = num.ToString() + tempnum;
					return tempnum;	
					}
				}
				else if(num < 10)
				{
					transnum = 0;
					tempnum = num.ToString() + tempnum;
				}
			}

			return tempnum;
		}
		
		
		public static string Substract(string minuend, string subtrahend)
		{
			int transnum = 0; //0 oder 1 --> Übergangswert
							  //z.B.  120 <-- 0 kleiner als 5, also transnum 1
							  //	 - 15     
							  //----------
							  //      105
							  
			string tempnum = string.Empty;//Ergebnis
			bool negative = IsLower(minuend, subtrahend);//true, wenn Ergebnis negativ
			if(negative)
			{
				return "-" + Substract(subtrahend, minuend);
			}
			
			//wenn der Minuend negativ ist
			if(minuend.StartsWith("-") && !subtrahend.StartsWith("-"))
			{
				return "-" + SumUp(minuend.Remove(0, 1), subtrahend);
			}
			
			//wenn der Subtrahend negativ ist
			else if(!minuend.StartsWith("-") && subtrahend.StartsWith("-"))
			{
				return SumUp(minuend, subtrahend.Remove(0, 1));
			}
			
			//wenn beide Zahlen negativ sind
			else if(minuend.StartsWith("-") && subtrahend.StartsWith("-"))
			{
				return SumUp(minuend, subtrahend.Remove(0, 1));
			}
			
			//auf gleiche Länge bringen...
			if(minuend.Length < subtrahend.Length)
			{
				minuend = minuend.PadLeft(subtrahend.Length, '0');
			}
			else if(subtrahend.Length < minuend.Length)
			{
				subtrahend = subtrahend.PadLeft(minuend.Length, '0');
			}
			
			//Schleife für alle Ziffern der Zahlen
			for(int counter = minuend.Length - 1; counter >= 0; counter--)
			{
				int num = 0;
				if(int.Parse(subtrahend[counter].ToString()  + transnum.ToString()) != 0)
				{
					//Minuend[counter] ist kleiner als Subtrahend[counter], also transnum = 1
					if(( (int.Parse(minuend[counter].ToString())) - (int.Parse(subtrahend[counter].ToString()) + transnum)) < 0)
					{
						num = (int.Parse("1" + minuend[counter].ToString())) - (int.Parse(subtrahend[counter].ToString())  + transnum);
						transnum = 1;
						tempnum = num.ToString() + tempnum;
					}
					
					//Minuend[counter] größer als Subtrahend[counter], also transnum = 0
					else if(( (int.Parse(minuend[counter].ToString())) - int.Parse(subtrahend[counter].ToString()) + transnum) >= 0)
					{
						num = (int.Parse(minuend[counter].ToString())) - (int.Parse(subtrahend[counter].ToString())  + transnum);
						transnum = 0;
						tempnum = num + tempnum;
					}
				

				}
				else
				{
					transnum = 0;
					tempnum = minuend[counter].ToString() + tempnum;
				}
			}
			
			//evtl. Entfernen der Nullen am Anfang der Zahl
			
			while(tempnum.StartsWith("0"))
			{
				if(tempnum != "0")
				tempnum = tempnum.Remove(0, 1);
				else
				break;
			}

			return tempnum;

		}
		
		public static string SumUpArray(string[] addends)
		{
			string result = string.Empty;
			foreach(string s in addends)
			{
				result = SumUp(result, s);
			}
			return result;
		}
		
		public static string SubstractArray(string[] numbers)
		{
			string result = string.Empty;
			foreach(string s in numbers)
			{
				result = Substract(result, s);
			}
			return result;
		}
		
		public static string Multiply(string factor1, string factor2)
		{
			bool negative = false;
			string result = "0";
			ArrayList TempNumbers = new ArrayList();
			
			//festlegen ob positiv oder negativ
			if(factor1.StartsWith("-"))
			{
				factor1 = factor1.Remove(0, 1);
				negative = true;
			}
			else if(factor2.StartsWith("-"))
			{
				factor2 = factor2.Remove(0, 1);
				negative = true;
			}
			else if((factor1.StartsWith("-")) && (factor2.StartsWith("-")))
			{
				factor2 = factor2.Remove(0, 1);
				factor1 = factor1.Remove(0, 1);
				
			}
			
			//Schleife für den 2. Faktor
			for(int f2counter = 0; f2counter < factor2.Length; f2counter++)
			{
				int trans = 0;
				string tempnumber = string.Empty;
				
				//Schleife für den 1. Faktor, damit jeder Ziffer des
				//2. Faktors mit jeder des 2. Faktors multipliziert wird
				for(int f1counter = factor1.Length - 1; f1counter >= 0; f1counter--)
				{
					//num: Ergebnis der Multiplikation einer Ziffer des 2. und einer
					//Ziffer des 1. Faktors
					int num = int.Parse(factor2[f2counter].ToString()) * int.Parse(factor1[f1counter].ToString()) + trans;
					//wenn num < 10 muss nichts auf die nächste Multiplikation übertragen werden
					if(num < 10)
					{
						trans = 0;
						tempnumber = num.ToString() + tempnumber;
					}
					
					//nur der Einer wird gespeichert, der Rest wird übertragen
					//
					//   123
					//     ^
					//     Einer
					else if(num >= 10)
					{
						//wenn wir an der ersten Ziffer des ersten Faktors angelangt sind
						//wird das ganze Ergebnis der Multiplikation der beiden Ziffern hinzugefügt
						if(f1counter != 0)
						{
						tempnumber = num.ToString()[num.ToString().Length - 1].ToString() + tempnumber;
						trans = int.Parse(num.ToString()[0].ToString());
						}
						else
						{
							tempnumber = num.ToString() + tempnumber;
						}
					}
					
				}
				//Teilergebnis speichern
				TempNumbers.Add(tempnumber);
			}
			
			//jetzt haben wir ein Array mit allen zu addierenden Zahlen, wobei den
			//hinteren noch Nullen angehängt werden müssen, denn:
			//123 * 23
			//	  4260 <-- hier muss aus Formatierungsgründen beim addieren eine Null hin
			//     369
			//---------
			//    4629
			
			int count = TempNumbers.Count - 1;
			for(int c = 0; c < TempNumbers.Count; c++)
			{	
				if(TempNumbers.Count > 1)
				{
				string addstr = string.Empty;
				for(int i = 0; i < count; i++)
				{
					addstr += "0";
				}
				count--;
				
				result = SumUp(result, (TempNumbers[c] as string) + addstr);
				}
				else
				result = TempNumbers[0] as string;
			}
			
			if(negative)
			return "-" + result;
			else
			return result;
		}
		
		
		public static bool IsLower(string number1, string number2)
		{
			bool negative = false;
			if(number1.StartsWith("-") && !number2.StartsWith("-"))
			{
				return true;
			}
			else if(!number1.StartsWith("-") && number2.StartsWith("-"))
			{
				return false;
			}
			else if(number1.StartsWith("-") && number2.StartsWith("-"))
			{
				negative = true;
			}
			
			//auf gleiche Länge bringen...
			if(number1.Length < number2.Length)
			{
				number1 = number1.PadLeft(number2.Length, '0');
			}
			else if(number2.Length < number1.Length)
			{
				number2 = number2.PadLeft(number1.Length, '0');
			}
			
			for(int c = 0; c < number1.Length; c++)
			{
				if(int.Parse(number1[c].ToString()) < int.Parse(number2[c].ToString()))
				{
					if(negative)
					return false;
					else
					return true;
					
				}
				else if(int.Parse(number1[c].ToString()) > int.Parse(number2[c].ToString()))
				{
					if(negative)
					return true;
					else
					return false;
				}
			
			}
			return false;
		}		
	}
}

PS.: Dividieren hab ich leider nicht hingekriegt 🙁 🙁 🙁
Greetz,
Big Al

Da man Spatzen nicht mit Kanonen jagt, sollte man auch nicht mit Computern auf Spatzenhirne losgehen.

4.506 Beiträge seit 2004
vor 18 Jahren

Hallo Big Al,

mir war es ehrlich gesagt zu mühselig Deinen Code genau durchzulesen, aber auf folgende Bemerkung:

PS.: Dividieren hab ich leider nicht hingekriegt

kann ich Dir den Tipp geben, dass man das genauso rechnen kann wie in der Grundschule einem beigebracht worden ist. (nennt sich glaube ich Kaufmanns-Dividieren, die rechnung mit dem lästigen übertrag und so weiter und so fort 😉

Gruß
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

C
1.215 Beiträge seit 2004
vor 18 Jahren

Original von Big Al
Natürlich geht das auch mit int.Parse(...), aber die Zahlen können länger sein.

Dann nimmt man double.Parse...
😉

Nichts für ungut - Deine Klasse ist sicher eine schöne Übung, aber an die Geschwindigkeit eines Parsers, der mathematische Ausdrücke innerhalb eines Strings evaluiert, werden Deine Funktionen nimmer herankommen. Was heissen soll, dass es wohl keinen sinnvollen Einsatz dafür gibt.

Original von norman_timol
nennt sich glaube ich Kaufmanns-Dividieren, die rechnung mit dem lästigen übertrag und so weiter und so fort

Richtig - mod wäre hier das Stichwort...
20%6 ergibt den Rest 2.

Grüsse

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Cord Worthmann,

Dann nimmt man double.Parse...

was hat denn ein double mit langen Zahlen zu tun? 🙂

herbivore

C
1.215 Beiträge seit 2004
vor 18 Jahren

Original von herbivore
Hallo Cord Worthmann,

Dann nimmt man double.Parse...
was hat denn ein double mit langen Zahlen zu tun? 🙂

herbivore

Yup, stimmt.
'War ich wohl ein bisschen voreilig...

sorry, Big Al!
😉

Grüsse

B
Big Al Themenstarter:in
342 Beiträge seit 2006
vor 18 Jahren

Mit der Kaufmannsdivision hab ichs probiert, aber vielleicht ein bisschen zu schnell aufgegeben 😁
Naja, ich glaub ich versuchs nochmal, damit die Klasse vollständig wird.
Zum Thema Nützlichkeit:
Was macht ihr z.B. mit 213671254361427354127632816431287643821643 * 67547614642153128654128343763, wenn ihr das vollständige Ergebnis braucht?
Wird zwar sicher nicht oft vorkommen, aber manchmal vielleicht doch 😜 😁
Big Al

Da man Spatzen nicht mit Kanonen jagt, sollte man auch nicht mit Computern auf Spatzenhirne losgehen.

S
1.047 Beiträge seit 2005
vor 18 Jahren

@bigal
dafür gibts in java z.b. biginteger... ledier vermiß ich das in c# irgendwie 😕
aber es gibts verschiedene konvertierungen im netz 🙂

B
Big Al Themenstarter:in
342 Beiträge seit 2006
vor 18 Jahren

Hi,
ich glaube, statt BigInt gibts in C# "long".
Aber was, wenn der Wert noch größer wird 😁

Da man Spatzen nicht mit Kanonen jagt, sollte man auch nicht mit Computern auf Spatzenhirne losgehen.

S
1.047 Beiträge seit 2005
vor 18 Jahren

@bigal
nein da verwechselst du was

BigInteger ist eine Klasse die sehr sehr große Zahlen aufnehmen kann die weit über einen einzelnen Datentypen hinaus geht.
Intern benutzt BigInteger int-arrays um die großen Zahlen abzubilden.
Die Zahl ergibt sich dann durch das "zusammensetzen" der einzelnen Felder.

Man brauch sowas eigetnlich z.B. für Verschlüsselungen wo große Primzahlen von nöten sind.
Wie bildet man die eigentlich in C# ab?

B
Big Al Themenstarter:in
342 Beiträge seit 2006
vor 18 Jahren

Also irgendwo hat progger glaub ich mal was dazu geschrieben, ich weiß aber nicht, ob das auf C# bezogen war. Leider ist die Suche hier n bisschen blöd, sonst hätte ich das Thema vielleicht wiedergefunden.
Naja, wars halt nutzlos, Spaß gemacht hats trotzdem 😁
und darauf kommts ja an.
Big Al

Da man Spatzen nicht mit Kanonen jagt, sollte man auch nicht mit Computern auf Spatzenhirne losgehen.

S
1.047 Beiträge seit 2005
vor 18 Jahren

wenn es dir spaß gemacht hat und du was dabei gelernt hast dann war es ja nicht nutzlos 🙂

und der ein oder andere wird sicher auhc nutzen dafür finden, sei es denn nur mal um zu schauen wie du das ganze implementiert hast 🙂

1.271 Beiträge seit 2005
vor 18 Jahren

Hallo zusammen,

@Big Al: Ich kann mich zwar nicht erinnern, aber ich hab trotzdem was auf Lager. Bei Codeproject gibt es eine BigInteger-Implementierung.

Gruß,
progger

A wise man can learn more from a foolish question than a fool can learn from a wise answer!
Bruce Lee

Populanten von Domizilen mit fragiler, transparenter Außenstruktur sollten sich von der Translation von gegen Deformierung resistenter Materie distanzieren!
Wer im Glashaus sitzt, sollte nicht mit Steinen werfen.

B
Big Al Themenstarter:in
342 Beiträge seit 2006
vor 17 Jahren

Moin,
ich habs eeeeeeeeeeeeeeeentlich geschafft, die Sammlung ist vollständig, dividieren geht auch!!! 😁 😁 😁 😁 😁 😁 😁 😁 😁
Ich würd jetzt gerne mal die Performance testen, weiß jemand, womit ich das am besten mache?
Diesmal hab ich das ganze als Datei angehängt, weil die Formatierung von großen Codefragmenten hierein bißchen unglücklich ist (s.o.).
Weitere Feedbacks sind natürlich willkommen...
Greetz,
Big Al

Da man Spatzen nicht mit Kanonen jagt, sollte man auch nicht mit Computern auf Spatzenhirne losgehen.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Big Al,

Ich würd jetzt gerne mal die Performance testen, weiß jemand, womit ich das am besten mache?

Einfach jede zu testende Operation in einer Schleife immer wieder ausführen und die Zeit mit der StopWatch-Klasse messen.

herbivore

B
Big Al Themenstarter:in
342 Beiträge seit 2006
vor 17 Jahren

Gute Idee,
vielen Dank!

Da man Spatzen nicht mit Kanonen jagt, sollte man auch nicht mit Computern auf Spatzenhirne losgehen.

T
512 Beiträge seit 2006
vor 17 Jahren

Fürs Multiplizieren kenne ich noch ne einfache Performanceverbesserung.

Und zwar den Karatsuba-Ofman-Algorithmus. Im Prinzip eine Devide&Conquer Strategie.

Du teilst den größeren der beiden Strings in der Mitte und zerlegst ihn quasi in:
x = x0 + x1*(b^n/2)

Wobei x0 und x1 jeweils halbe Länge von x haben.
Also wenn x die Länge n hat, sind x0 die niederwertigen n/2 Stellen, x1 die höherwertigen n/2 Stellen. b ist die Basis, also im Dezimalsystem 10.

Den 2. Operator (y) musst du in gleicher Weise teilen. Also nicht in der Mitte, sondern (von rechts nach links) in n/2 niederwertige Stellen und Rest.

Der Rest ist dann simple Mathematik:

x * y = ( x0 + x1*(bn/2) ) * ( y0 + y1*(bn/2) )
x * y = x0y0 + x1y1b^n + (x1y0 + x0*y1)*b^n/2

(Bisher 4 Multiplikationen mit Länge n/2 statt 1 Multiplikation mit Länge n. Noch nichts gespart)

NR:
(x0 + x1) * (y0 + y1) = x0y0 + x1y1 + (x0y1 + x1y0)
(x0y1 + x1y0) = (x0 + x1) * (y0 + y1) - x0y0 - x1y1

x0y0 und x1y1 sind bereits bekannt. Also können wir (x0y1 + x1y0) mit nur einer Multiplikation der Länge n/2 und zwei Subtraktionen ausführen.

Also in Code würde das so aussehen:

public static string Multiply( string x, string y )
		{
			// unnötige Länge kürzen
			x = x.TrimStart( '0' );
			y = y.TrimStart( '0' );
			
			if( x.Length < y.Length )
			{
				string buff = x;
				x = y;
				y = buff;
			}
			
			if( string.IsNullOrEmpty( y ) )
				return "0";
			
			if( x.Length > 4 )	// Abbruchbedingung für die Rekursion
			{
				// x und y teilen
				string x0 = x.Substring( x.Length / 2 );
				string x1 = x.Substring( 0, x.Length - x0.Length );
				
				string y0, y1;
				if( x0.Length > y.Length )
				{
					y0 = y;
					y1 = "0";
				}
				else
				{
					y1 = y.Substring( 0, y.Length - x0.Length );
					y0 = y.Substring( y1.Length );
				}
				
				string a = Multiply( x0, y0 );
				string b = Multiply( x1, y1 );
				string c = SumUp( a, b );
				string d = Substract( Multiply( SumUp( x0, x1 ), SumUp( y0, y1 ) ), c );
				
				return SumUp( SumUp( a, b + new string( '0', x0.Length*2 ) ), d  + new string('0', x0.Length) );
			}
			else	// länge ist klein genug für Integermultiplikation ohne Überlauf
			{
				int ix = int.Parse( x );
				int iy = int.Parse( y );
				return (ix * iy).ToString();
			}
		}

Hab das mal ganz primitiv gegen deine Implementation antreten lassen:

		static void Main()
		{
			string a = "1234567890123456789012345678901234567890";
			string b = "9876543210987654321098765432109876543210";
			
			int max = 5000;
			
			int start = Environment.TickCount;
			for( int i = 0; i < max; ++i )
			{
				Multiply( a, b );	// Karatsuba-Ofman
			}
			Console.WriteLine( Environment.TickCount - start );
			
			start = Environment.TickCount;
			for( int i = 0; i < max; ++i )
			{
				Multiply2( a, b );	// deins
			}
			Console.WriteLine( Environment.TickCount - start );
			
			Console.ReadKey();
		}

Output (ca):
21000
35000
(lange zahl)
(noch eine lange zahl die gleich der 1. ist)

Also schon messbar schneller.
Wenn große Abschnitte nur 0 sind, wirds sogar noch deutlich besser.

Das ist so ein Trick, den man im Informatikstudium 3. Semester lernt, und auch wie man sieht nach dem Verständniss auch leicht zu implementieren ist 😁
Man könnte vieleicht noch schauen, ob man an der Abbruchlänge von 4 noch was optimieren könnte. Habs eben nur gewählt wegen der int Multiplikation. Keine Ahnung ob ein früherer Abbruch mit deiner Multiplikation am Ende nicht schneller wäre.

Ich hoffe das alles klingt nicht zu klugscheißerisch 😁

e.f.q.

Aus Falschem folgt Beliebiges

B
Big Al Themenstarter:in
342 Beiträge seit 2006
vor 17 Jahren

Puuuuuhhh, ganz schön starker Tobac 🤔
Das muss ich mir noch mal in Ruhe angucken, aber wenn ichs verstanden hab werd ichs natürlich übernehmen. Vielen Dank.
Greetz,
Big Al

Da man Spatzen nicht mit Kanonen jagt, sollte man auch nicht mit Computern auf Spatzenhirne losgehen.

T
512 Beiträge seit 2006
vor 17 Jahren

Googel einfach mal nach Karatsuba Ofman. Gibt bestimmt millionen Leute die das besser erklären können als ich.

e.f.q.

Aus Falschem folgt Beliebiges

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo zusammen,

bei feststehenden Begriffen ist Wikipedia auch immer einen Blick wert:

http://de.wikipedia.org/wiki/Karatsuba-Algorithmus

herbivore

B
Big Al Themenstarter:in
342 Beiträge seit 2006
vor 17 Jahren

Wikipedia hilft doch immer, he, he, he...
Das war die erste site, auf der ich gesucht hab, leider nur unter "Karatsuba-Ofman-Algorithmus", da gabs keine Ergebnisse, also danke @ Herbivore, ich habs jetzt verstanden 😁

Gibt bestimmt millionen Leute die das besser erklären können als ich

Wenn man nach "Karatsuba-Ofman-Algorithmus" googled, bekommt man nur 3 Einträge, die alle nich so das Wahre sind.
Weiß jemand von euch, ob es für die anderen Rechenarten auch bessere Methoden gibt? Später is dann zwar wahrscheilich kein Codefitzelchen mehr von mir übrig, aber Verbesserungen sind mir wichtig, weil man ja was lernt.
Naja,
so long
Big Al

Da man Spatzen nicht mit Kanonen jagt, sollte man auch nicht mit Computern auf Spatzenhirne losgehen.

1.271 Beiträge seit 2005
vor 17 Jahren

Original von Big Al
Später is dann zwar wahrscheilich kein Codefitzelchen mehr von mir übrig

Der Code ist und bleibt von dir. Den Algorithmus muss man sich ja nicht immer selbst ausdenken, fertige sind meist auch von Profis gut durchdacht und gut getestet. Es ist auch eine Herausforderung einen (fertigen) Algorithmus umzusetzen. Dabei kommt man manchmal auch ins Grübeln und man lernt auf jeden Fall einiges dabei.

A wise man can learn more from a foolish question than a fool can learn from a wise answer!
Bruce Lee

Populanten von Domizilen mit fragiler, transparenter Außenstruktur sollten sich von der Translation von gegen Deformierung resistenter Materie distanzieren!
Wer im Glashaus sitzt, sollte nicht mit Steinen werfen.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Big Al,

wenn ich das richtig sehe, verwendest du momentan als Ziffern 0-9 als chars. Vermutlich ist es weit effizienter ints oder longs als "Ziffern" von 0-int/long-MaxValue zu nehmen. Vielleicht sogar noch besser uint oder ulong. Natürlich müsst diese Repräsentation bei Ein- und Ausgabe wieder in Strings umgewandelt werden.

herbivore

B
Big Al Themenstarter:in
342 Beiträge seit 2006
vor 17 Jahren

@herbivore
Das versteh ich jetzt nich so ganz, aber wäre es nicht vielleicht auch schneller,
uint-Arrays statt strings zu nehmen?
Und was ist eigentlich, wenn ich den Code als unsafe markiere?
Kann ich das machen, solange ich weiß, dass darin keine Überläufe o.ä. entstehen können? Unsafe bringt ja angeblich ziemlich viel Performance, wie ist das hier?
Big Al

Da man Spatzen nicht mit Kanonen jagt, sollte man auch nicht mit Computern auf Spatzenhirne losgehen.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Big Al,

Das versteh ich jetzt nich so ganz, aber wäre es nicht vielleicht auch schneller,
uint-Arrays statt strings zu nehmen?

so meinte ich das 🙂

Und was ist eigentlich, wenn ich den Code als unsafe markiere?

Ich denke unsafe ist nicht das, was du willst:

Das unsafe-Schlüsselwort deutet auf einen nicht sicheren Kontext hin, der für alle Zeigeroperationen erforderlich ist.

sondern unchecked:

Das unchecked-Schlüsselwort wird verwendet, um die Überlaufprüfung für arithmetische Operationen und Konvertierungen mit ganzzahligen Typen zu unterdrücken.

herbivore

T
512 Beiträge seit 2006
vor 17 Jahren

Ich glaube er meint einfach nur, dass du nicht jede Ziffer einzeln betrachtest, sondern in Blöcken. Die Blöcke wandelst du dann in ints um und addierst sie, statt jede einzelne Ziffer in einen int umzuwandeln. Bei Dezimalsystem sollten Blöcke von 9 Ziffern problemlos ohne Überlauf addiert werden können.

Also zuerst die Umwandlung in int Arrays indem du in Blöcke teilst.
Dann die Rechnung.
Und dann zur Ausgabe wieder zurückwandeln.

e.f.q.

Aus Falschem folgt Beliebiges

B
Big Al Themenstarter:in
342 Beiträge seit 2006
vor 17 Jahren

Wie mache ich das dann mit den Vorzeichen?
Doch nur chars können auch das Minus darstellen.
Big Al

Da man Spatzen nicht mit Kanonen jagt, sollte man auch nicht mit Computern auf Spatzenhirne losgehen.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Big Al,

wo ist dein Problem? Da gibt es doch diverse Lösungen. Eine wäre, sich das Vorzeichen in einer boolschen Variable zu merken.

herbivore

B
Big Al Themenstarter:in
342 Beiträge seit 2006
vor 17 Jahren

Meinst du so:
SumUp(uint[] addend1, bool addend1Negativ, uint[] addend2, bool addend2Negativ)
{...}
wäre natürlich ne Möglichkeit....mal wieder danke

Da man Spatzen nicht mit Kanonen jagt, sollte man auch nicht mit Computern auf Spatzenhirne losgehen.