Bachelor studies
Ich nehme zum Wintersemester das Studium der Mathematik (B.Sc.) mit dem Ergänzungsbereich Informatik an der FU Berlin auf und möchte interessierte Leser gerne ein wenig daran teilhaben lassen.
Deshalb werde ich wöchentlich eine kleine Zusammenfassung des Studienverlaufs hier schreiben, so dass – neben dem Lerneffekt für mich – auch andere einen Einblick in das Studium der Mathematik erhalten können. Die ersten Lehrveranstaltungen beginnen Mitte Oktober, der Brückenkurs bereits Ende September.
Im ersten Semester besuche ich u. a. die Lehrveranstaltungen Analysis I/III, Lineare Algebra I/II und Computerorientierte Mathematik I/II. Diese werden entsprechend den Großteil der Beiträge beeinflussen.
Ich werde versuchen, weitere Artikel zur Softwareentwicklung mit C# zumindest einmal im Monat zu veröffentlichen.
Deshalb werde ich wöchentlich eine kleine Zusammenfassung des Studienverlaufs hier schreiben, so dass – neben dem Lerneffekt für mich – auch andere einen Einblick in das Studium der Mathematik erhalten können. Die ersten Lehrveranstaltungen beginnen Mitte Oktober, der Brückenkurs bereits Ende September.
Im ersten Semester besuche ich u. a. die Lehrveranstaltungen Analysis I/III, Lineare Algebra I/II und Computerorientierte Mathematik I/II. Diese werden entsprechend den Großteil der Beiträge beeinflussen.
Ich werde versuchen, weitere Artikel zur Softwareentwicklung mit C# zumindest einmal im Monat zu veröffentlichen.
Arbitrary-precision Arithmetic in C#
Für manche Anwendungen kann es notwendig werden, mit ganzen Zahlen zu arbeiten, die mitunter deutlich größer (bzw. kleiner) sind, als die CLS-Typen
Zwar ist es eine gute Übung, arithmetische Operationen auf ganzen Zahlen, die als Zeichenkette vorliegen, selbst zu implementieren – das .NET-Framework bringt jedoch bereits seit v4.0 die Struktur
Die Verwendung gestaltet sich denkbar einfach, insofern belasse ich es für den Moment bei ein paar Beispielen:
Notwendig sind derartige Vorgehensweisen beispielsweise in der Kryptologie oder bei Simulationen in der numerischen Mathematik. Hauptsächlich kam ich jedoch deswegen auf diesen kurzen Beitrag, da einige Entwickler die Einführung dieser Struktur (
Int16
(short), Int32
(int) und Int64
(long) definieren.Zwar ist es eine gute Übung, arithmetische Operationen auf ganzen Zahlen, die als Zeichenkette vorliegen, selbst zu implementieren – das .NET-Framework bringt jedoch bereits seit v4.0 die Struktur
BigInteger
aus System.Numerics
mit. Sofern du dir also nicht sehr sicher bist, eine für deinen spezifischen Anwendungsfall bessere Implementierung vorliegen zu haben, solltest du eher auf das Framework setzen.Die Verwendung gestaltet sich denkbar einfach, insofern belasse ich es für den Moment bei ein paar Beispielen:
BigInteger verwenden
Selbstverständlich stehen noch einige andere nützliche Operationen und Indikatoren zur Verfügung.0102030405060708091011
BigInteger a = BigInteger.Parse("34872923458349238592320478");BigInteger b = BigInteger.Parse("14782398471853465710237672");
// Operatorüberladung für BigInteger.Add(a, b)BigInteger sum = (a + b); // 49655321930202704302558150
// Operatorüberladung für BigInteger.Subtract(a, b)BigInteger difference = (a – b); // 20090524986495772882082806
// Operatorüberladung für BigInteger.Multiply(a, b)BigInteger product = (a * b); // 515505450439764661138576432136536115538523372647216
Notwendig sind derartige Vorgehensweisen beispielsweise in der Kryptologie oder bei Simulationen in der numerischen Mathematik. Hauptsächlich kam ich jedoch deswegen auf diesen kurzen Beitrag, da einige Entwickler die Einführung dieser Struktur (
BigInteger
ist nicht als Klasse implementiert) verpasst zu haben scheinen. 
String.Format by Object Properties
Jeder C#-Entwickler wird sicherlich bereits die eine oder andere Überladung der
String.Format
-Methode verwendet haben – ansonsten wird es auf jeden Fall höchste Zeit, sich damit zu beschäftigen. Beispiel:
String.Format verwenden
Noch etwas bequemer – insbesondere auch im Zusammenhang mit anonymen Typen – wäre es jedoch, die Eigenschaften eines Objekts als Ersetzungsdaten verwenden zu können. Wir werden uns dazu eine (nicht ernsthaft optimierte) Erweiterungsmethode für den Typ 0102030405
string message = String.Format("{0} ist {1} Jahre alt und besitzt {2:C}.", "Bernd", 35, 1234.56); // "Bernd ist 35 Jahre alt und besitzt 1234,56 €."
String
schreiben, welche auf Reflexion setzt:
FormatByObject implementieren
Nun können wir statt numerischer Indizes komfortablere Zeichenketten verwenden:
01020304050607080910111213
public static string FormatByObject(this string str, object obj) { StringBuilder stringBuilder = new StringBuilder(str); { foreach(PropertyInfo propertyInfo in obj.GetType().GetProperties()) { stringBuilder.Replace( "{" + propertyInfo.Name + "}", propertyInfo.GetValue(obj).ToString() ); } }
return stringBuilder.ToString();}
FormatByObject verwenden
Dieses sehr einfache Vorgehen unterstützt jedoch bei Weitem nicht alle Möglichkeiten der ursprünglichen Implementierung, so ist beispielsweise kein 0102030405
message = "{Name} ist {Age} Jahre alt und besitzt {Balance} €.".FormatByObject(new { Name = "Bernd", Age = 35, Balance = 1234.56}); // "Bernd ist 35 Jahre alt und besitzt 1234,56 €."
{Balance:C}
zur Währungsformatierung möglich. Dies könnte dadurch behoben werden, indem wir unsere erweiterte Formatierung auf das Basisformat zurückführen – sprich, die Zeichenketten durch einen Index ersetzen. Ich werde dies in einem separaten Beitrag noch einmal aufgreifen. Determine if a Number is a Power of Two
Für manche Algorithmen bestehen Optimierungsansätze, wenn eine zu untersuchende Zahl eine Zweierpotenz ist. Daher möchte ich mit diesem Beitrag aufzeigen, wie sich diese Problemstellung möglichst effizient lösen lässt.
Naive Ansätze arbeiten mit Schleifen und prüfen schrittweise alle in Frage kommenden Zweierpotenzen – es ist leicht einzusehen, dass dieses Vorgehen insbesondere für größere Zahlen eher mäßig effizient ist. Alternativ könnte man auf die Idee kommen, das Problem mit Logarithmen zu lösen – hier kann es jedoch zu Rundungsproblemen kommen. Wir sollten uns daher die Struktur entsprechender Zahlen einmal genauer ansehen:
In C# könnte die Implementierung beispielsweise wie folgt aussehen:
Naive Ansätze arbeiten mit Schleifen und prüfen schrittweise alle in Frage kommenden Zweierpotenzen – es ist leicht einzusehen, dass dieses Vorgehen insbesondere für größere Zahlen eher mäßig effizient ist. Alternativ könnte man auf die Idee kommen, das Problem mit Logarithmen zu lösen – hier kann es jedoch zu Rundungsproblemen kommen. Wir sollten uns daher die Struktur entsprechender Zahlen einmal genauer ansehen:
Zweierpotenzen
Offensichtlich ist bei einer Zweierpotenz 010203040506
Dualzahl Dezimalzahl-------------------------------------------- 20 1 1 21 10 2 22 100 4 23 1000 8
2n
demnach das (n + 1)
-te Bit auf 1
gesetzt und alle ggf. nachfolgenden Stellen besitzen den Wert 0
– was kaum eine Überraschung darstellen sollte. Wir müssen nun jedoch nicht jedes Bit einzeln prüfen, ob die Zahl auf dieses "Muster" passt, sondern können uns das Bitmuster der Zahl 2n – 1
zu Nutze machen:
Voränger von Zweierpotenzen
Wie selbstverständlich zu erwarten war, muss der Vorgänger ein inverses Bitmuster besitzen. Dies hilft uns insofern weiter, als dass wir diese beiden Zahlen mit einem bitweisen UND verknüpfen und auf Gleichheit mit 010203040506
Dualzahl 2n – 1 (dual)-------------------------------------------- 20 1 0 21 10 01 22 100 011 23 1000 0111
0
prüfen können, was bei Zweierpotenzen zutreffen muss.In C# könnte die Implementierung beispielsweise wie folgt aussehen:
Zahl auf Zweierpotenz prüfen (Basis)
Dieses Vorgehen liefert jedoch auch für die Zahl 010203
public static bool IsPowerOfTwo(uint number) { return ((number & (number – 1)) == 0);}
0
den Wert true
zurück. Wir prüfen diesen Fall daher separat:
Aufrufer-Informationen für Methoden in C#
Manchmal kann es sinnvoll sein, sich Informationen über den Aufrufer einer Methode übermitteln zu lassen. Wir werden dies im Folgenden mit zwei praxisnahen Beispielen genauer untersuchen.
Zuerst möchten wir ein (einfaches) Logging-System implementieren:
Ich möchte noch einen weiteren praktischen Anwendungsfall mit
Zuerst möchten wir ein (einfaches) Logging-System implementieren:
Logging implementieren
Diese Klasse können wir nun beispielsweise wie folgt verwenden:
010203040506070809
public static class Logging { public static void Enter(string caller) { Trace.WriteLine(caller + " betreten"); }
public static void Leave(string caller) { Trace.WriteLine(caller + " verlassen"); }}
Logging verwenden
Nun stellt uns jedoch das .NET-Framework ein spezielles Attribut 010203040506070809
static void Main(string[] args) { Logging.Enter("Main");
/** * Aktionen ausführen **/
Logging.Leave("Main");}
CallerMemberName
zur Verfügung, um diesen Prozess ein wenig zu optimieren – dazu müssen wir unsere Klasse minimal ergänzen:
Logging-Implementierung erweitern
Der Parameter 010203040506070809
public static class Logging { public static void Enter([CallerMemberName] string caller = "") { Trace.WriteLine(caller + " betreten"); }
public static void Leave([CallerMemberName] string caller = "") { Trace.WriteLine(caller + " verlassen"); }}
caller
wird nun beim Aufruf automatisch festgelegt, so dass die explizite Angabe in Main
bei gleichem Ergebnis entfallen kann.Ich möchte noch einen weiteren praktischen Anwendungsfall mit
INotifyPropertyChanged
demonstrieren:
INotifyPropertyChanged mit impliziten Aufruferinformationen
Dies vereinfacht die Verwendung dieser Schnittstelle, die insbesondere zur Datenbindung im Rahmen der WPF Verwendung findet – vor allem bei Refaktorierungsmaßnahmen. Das Verhalten ist wie erwartet:
01020304050607080910111213141516171819202122232425262728293031323334353637
public class Person : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged;
private string name; public string Name { get { return this.name; } set { if(this.name != value) { this.name = value;
this.OnPropertyChanged(); } } }
private int age; public int Age { get { return this.age; } set { if(this.age != value) { this.age = value;
this.OnPropertyChanged(); } } }
private void OnPropertyChanged([CallerMemberName] string propertyName = "") { this?.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }}
Objekt verwenden
Weitere Informationen (und hilfreiche Attribute) lassen sich im MSDN nachlesen. 0102030405060708091011121314151617
Person ich = new Person() { Name = "Holger", Age = 25};
ich.PropertyChanged += (sender, e) => { Debug.WriteLine("Der Wert der Eigenschaft '{0}' hat sich geändert!", (object) e.PropertyName );};
ich.Age = 26;
/** * Das Ereignis "PropertyChanged" wird ausgelöst * und "PropertyName" implizit auf "Age" gesetzt.**/
Project links
-
BitStadt – Stadtportal
Berlin · Hamburg · Amsterdam -
CCC – Fahrplan
Schedules for the CCCongress
Categories / Archive | Übersicht
- PHP functions in C# (136)
- Dictionary (257)
Tags
.NET · ADO.NET · Work · ASP.NET MVC · Blog · C# · Generics · Society · Computer Science · Java · LINQ · Logic · Mathematics · Network · PHP · Project · Security · Software development · Studies · Technics · Theory · Web design · WPF