Kurse:Datentypen-C-Sharp: Unterschied zwischen den Versionen
// via Wikitext Extension for VSCode |
Keine Bearbeitungszusammenfassung |
||
| (3 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
* [[Kurse:Datentypen-C-Sharp String-Operationen und wichtige Methoden]] | |||
=String= | |||
== Grundlagen == | == Grundlagen == | ||
; Deklaration | ; Deklaration | ||
| Zeile 160: | Zeile 161: | ||
== Zusammenfassung == | == Zusammenfassung == | ||
Kurzliste: Length, Indexer, Substring, Contains, StartsWith, EndsWith, IndexOf, Split, Join, Trim*, Replace, Insert, Remove, PadLeft/Right, ToUpper*/ToLower*, Format/$-Interpolation, Equals/Compare, Normalize, StringBuilder. | Kurzliste: Length, Indexer, Substring, Contains, StartsWith, EndsWith, IndexOf, Split, Join, Trim*, Replace, Insert, Remove, PadLeft/Right, ToUpper*/ToLower*, Format/$-Interpolation, Equals/Compare, Normalize, StringBuilder. | ||
= Ganzzahlen: Operationen und wichtige Methoden = | |||
=== Basis-Typen === | |||
* sbyte / byte (8 Bit), short / ushort (16), int / uint (32), long / ulong (64) | |||
* nint / nuint (plattformabhängig), BigInteger (beliebig groß, System.Numerics) | |||
=== Deklaration & Literale === | |||
<syntaxhighlight lang="csharp"> | |||
int a = 42; | |||
long b = 1_000_000_000L; | |||
uint c = 0u; | |||
nint p = 123n; | |||
int bin = 0b1010_1100; | |||
int hex = 0xFF_A0; | |||
</syntaxhighlight> | |||
=== Konvertierung / Casting === | |||
<syntaxhighlight lang="csharp"> | |||
long l = a; // implizit (erweiternd) | |||
int k = (int)l; // explizit (evtl. Datenverlust) | |||
int parsed = int.Parse("123", CultureInfo.InvariantCulture); | |||
if (int.TryParse("123", out var val)) { /* ok */ } | |||
</syntaxhighlight> | |||
=== Rechenoperationen === | |||
<syntaxhighlight lang="csharp"> | |||
int sum = x + y; | |||
int diff = x - y; | |||
int prod = x * y; | |||
int quot = x / y; // ganzzahlig, Rest abgeschnitten | |||
int mod = x % y; | |||
int neg = -x; | |||
</syntaxhighlight> | |||
=== Division: Ganzzahl vs Gleitkomma === | |||
<syntaxhighlight lang="csharp"> | |||
int r1 = 5 / 2; // 2 | |||
double r2 = 5 / 2.0; // 2.5 | |||
</syntaxhighlight> | |||
=== Inkrement / Dekrement === | |||
<syntaxhighlight lang="csharp"> | |||
i++; | |||
++i; | |||
i--; | |||
</syntaxhighlight> | |||
=== Overflow-Kontrolle === | |||
<syntaxhighlight lang="csharp"> | |||
checked { | |||
int o = int.MaxValue; | |||
// int p = o + 1; // OverflowException | |||
} | |||
unchecked { | |||
int wrap = int.MaxValue + 1; // Wrap-around | |||
} | |||
bool ok = int.TryParse("9999999999", out _); // false wenn außerhalb Range | |||
</syntaxhighlight> | |||
=== Vergleich & Relationen === | |||
<syntaxhighlight lang="csharp"> | |||
bool eq = a == b; | |||
bool ne = a != b; | |||
bool lt = a < b; | |||
bool between = x >= min && x <= max; | |||
</syntaxhighlight> | |||
=== Bitoperationen === | |||
<syntaxhighlight lang="csharp"> | |||
int and = flags & mask; | |||
int or = flags | mask; | |||
int xor = flags ^ mask; | |||
int not = ~flags; | |||
int shiftedL = value << 3; | |||
int shiftedR = value >> 2; | |||
bool has = (flags & mask) != 0; | |||
</syntaxhighlight> | |||
=== BitHelpers (.NET) === | |||
<syntaxhighlight lang="csharp"> | |||
int pop = System.Numerics.BitOperations.PopCount((uint)value); | |||
int leading = BitOperations.LeadingZeroCount((uint)value); | |||
int rot = BitOperations.RotateLeft(value, 5); | |||
</syntaxhighlight> | |||
=== Math / Numerik === | |||
<syntaxhighlight lang="csharp"> | |||
int abs = Math.Abs(v); | |||
int clamped = Math.Clamp(v, 0, 100); | |||
int max = Math.Max(a, b); | |||
int min = Math.Min(a, b); | |||
int sign = Math.Sign(v); | |||
long pow2 = 1L << n; | |||
</syntaxhighlight> | |||
=== Zufallszahlen === | |||
<syntaxhighlight lang="csharp"> | |||
int r = Random.Shared.Next(0, 100); // 0..99 | |||
int rr = RandomNumberGenerator.GetInt32(0, 100); // kryptographisch | |||
</syntaxhighlight> | |||
=== Parsing / Formatierung === | |||
<syntaxhighlight lang="csharp"> | |||
int n = int.Parse("42"); | |||
if (int.TryParse("42", NumberStyles.Integer, CultureInfo.InvariantCulture, out var num)) {} | |||
string s1 = num.ToString(); // kulturabhängig | |||
string s2 = num.ToString("D6"); // führende Nullen | |||
string hexStr = num.ToString("X"); // Hex | |||
</syntaxhighlight> | |||
=== Performance / Span Parsing === | |||
<syntaxhighlight lang="csharp"> | |||
ReadOnlySpan<char> span = "12345".AsSpan(); | |||
if (int.TryParse(span, out int fast)) { } | |||
</syntaxhighlight> | |||
=== Checked Arithmetik Helpers (C# 11+) === | |||
<syntaxhighlight lang="csharp"> | |||
int safe = int.CreateChecked((long)other); | |||
int trunc = int.CreateTruncating(big); | |||
int sat = int.CreateSaturating(big); | |||
</syntaxhighlight> | |||
=== Pattern Matching / Ranges === | |||
<syntaxhighlight lang="csharp"> | |||
bool ok = value is >= 0 and <= 10; | |||
</syntaxhighlight> | |||
=== Flags Enum Beispiel === | |||
<syntaxhighlight lang="csharp"> | |||
[Flags] | |||
enum Perm { None=0, Read=1, Write=2, Exec=4 } | |||
Perm p = Perm.Read | Perm.Write; | |||
bool canWrite = p.HasFlag(Perm.Write); // langsamer | |||
bool canWriteFast = (p & Perm.Write) != 0; | |||
</syntaxhighlight> | |||
=== Häufige Fehlerquellen === | |||
* Ganzzahldivision statt Gleitkomma | |||
* Overflow bei Multiplikation (checked nutzen) | |||
* Parse ohne Fehlerprüfung | |||
* Bitmasken falsch (Klammern, Vorzeichen) | |||
=== Zusammenfassung Ganzzahlen === | |||
Kurzliste: + - * / % ++ -- Vergleiche, Bit: & | ^ ~ << >>, Parse/TryParse, ToString("D"/"X"), Math.* (Abs, Clamp, Min, Max, Sign), Random.Shared.Next, BitOperations (PopCount/Rotate/LeadingZeroCount), checked/unchecked, Flags-Enums. | |||
= Fließkommazahlen: Operationen und wichtige Methoden = | |||
=== Typen & Eigenschaften === | |||
* float (Single, 32 Bit IEEE 754, ca. 7 Dezimalstellen) | |||
* double (64 Bit IEEE 754, ca. 15–17 Dezimalstellen) – Standard | |||
* decimal (128 Bit, Basis-10, 28–29 signifikante Stellen, langsamer, für Geld/Buchhaltung) | |||
<syntaxhighlight lang="csharp"> | |||
float f = 1.5f; | |||
double d = 1.5; | |||
decimal m = 1.5m; | |||
</syntaxhighlight> | |||
=== Basis-Operationen === | |||
<syntaxhighlight lang="csharp"> | |||
double sum = a + b; | |||
double diff = a - b; | |||
double prod = a * b; | |||
double quot = a / b; | |||
double neg = -a; | |||
</syntaxhighlight> | |||
=== Vergleich (Toleranz) === | |||
Direkter == Vergleich problematisch wegen Rundungsfehlern. | |||
<syntaxhighlight lang="csharp"> | |||
bool AreClose(double x, double y, double relEps = 1e-12, double absEps = 1e-15) { | |||
double diff = Math.Abs(x - y); | |||
if (diff <= absEps) return true; | |||
return diff <= relEps * Math.Max(Math.Abs(x), Math.Abs(y)); | |||
} | |||
</syntaxhighlight> | |||
=== Spezielle Werte === | |||
<syntaxhighlight lang="csharp"> | |||
double nan = double.NaN; | |||
double posInf = double.PositiveInfinity; | |||
double negInf = double.NegativeInfinity; | |||
bool isNan = double.IsNaN(nan); | |||
bool isInf = double.IsInfinity(posInf); | |||
bool isFinite = double.IsFinite(1.0); | |||
double eps = double.Epsilon; // kleinste >0 Subnormal bei double | |||
</syntaxhighlight> | |||
=== Decimal Besonderheiten === | |||
<syntaxhighlight lang="csharp"> | |||
decimal preis = 12.34m; | |||
decimal sum = preis * 3; // exakte Dezimalarithmetik (Basis 10) | |||
</syntaxhighlight> | |||
=== Casting / Konvertierung === | |||
<syntaxhighlight lang="csharp"> | |||
double dd = (double)f; // implizit float -> double | |||
float ff = (float)dd; // explizit (Präzisionsverlust) | |||
decimal dm = (decimal)dd; // kann Overflow werfen | |||
double back = (double)dm; | |||
</syntaxhighlight> | |||
=== Rundung === | |||
<syntaxhighlight lang="csharp"> | |||
double r1 = Math.Round(2.345, 2); // Banker's (ToEven) | |||
double r2 = Math.Round(2.345, 2, MidpointRounding.AwayFromZero); | |||
double ceil = Math.Ceiling(x); | |||
double floor = Math.Floor(x); | |||
double trunc = Math.Truncate(x); | |||
</syntaxhighlight> | |||
=== Math Funktionen === | |||
<syntaxhighlight lang="csharp"> | |||
double abs = Math.Abs(x); | |||
double pow = Math.Pow(2.0, 10); | |||
double sq = Math.Sqrt(v); | |||
double c = Math.Cos(a); | |||
double s = Math.Sin(a); | |||
double t = Math.Tan(a); | |||
double exp = Math.Exp(a); | |||
double ln = Math.Log(a); | |||
double log10 = Math.Log10(a); | |||
double clamped = Math.Clamp(x, 0.0, 1.0); | |||
double min = Math.Min(a, b); | |||
double max = Math.Max(a, b); | |||
double copySign = Math.CopySign(magnitude:5.0, sign:-2.0); | |||
</syntaxhighlight> | |||
=== MathF für float === | |||
<syntaxhighlight lang="csharp"> | |||
float sf = MathF.Sqrt(3f); | |||
</syntaxhighlight> | |||
=== Fused Multiply-Add (FMA) === | |||
<syntaxhighlight lang="csharp"> | |||
double fma = Math.FusedMultiplyAdd(a, b, c); // a*b + c mit geringerer Rundung | |||
</syntaxhighlight> | |||
=== Parsing & Formatierung === | |||
<syntaxhighlight lang="csharp"> | |||
double v = double.Parse("1.23", CultureInfo.InvariantCulture); | |||
if (double.TryParse("1.23", NumberStyles.Float, CultureInfo.InvariantCulture, out var parsed)) { } | |||
string sG = v.ToString("G17", CultureInfo.InvariantCulture); // max Genauigkeit double | |||
string sF = v.ToString("F2"); // 2 Nachkommastellen | |||
string sE = v.ToString("E3"); // wissenschaftlich | |||
string sR = v.ToString("R"); // Round-trip | |||
</syntaxhighlight> | |||
=== Span Parsing (Performance) === | |||
<syntaxhighlight lang="csharp"> | |||
ReadOnlySpan<char> span = "3.14159".AsSpan(); | |||
if (double.TryParse(span, NumberStyles.Float, CultureInfo.InvariantCulture, out double pi)) { } | |||
</syntaxhighlight> | |||
=== Interop / Bit-Ebene === | |||
<syntaxhighlight lang="csharp"> | |||
long bits = BitConverter.DoubleToInt64Bits(d); | |||
double again = BitConverter.Int64BitsToDouble(bits); | |||
int floatBits = BitConverter.SingleToInt32Bits(f); | |||
</syntaxhighlight> | |||
=== NaN Verhalten === | |||
<syntaxhighlight lang="csharp"> | |||
bool eqNaN = double.NaN == double.NaN; // false | |||
bool notEq = double.NaN != double.NaN; // true | |||
bool ordered = double.NaN < 1.0; // false | |||
</syntaxhighlight> | |||
=== Aggregationen / Summe (Stabilität) === | |||
<syntaxhighlight lang="csharp"> | |||
double StableSum(double[] data) { | |||
double sum = 0, c = 0; // Kahan | |||
foreach (var x in data) { | |||
double y = x - c; | |||
double t = sum + y; | |||
c = (t - sum) - y; | |||
sum = t; | |||
} | |||
return sum; | |||
} | |||
</syntaxhighlight> | |||
=== Random Gleitkomma === | |||
<syntaxhighlight lang="csharp"> | |||
double r = Random.Shared.NextDouble(); // [0,1) | |||
double rRange = Random.Shared.NextDouble() * (max - min) + min; | |||
</syntaxhighlight> | |||
=== Performance Hinweise === | |||
* double schneller als decimal | |||
* float spart Speicher (Arrays, GPU), aber geringere Präzision | |||
* Avoid boxing bei Formatierung durch Span-basierte APIs (TryFormat) | |||
=== Tolerante Sortierung Beispiel === | |||
<syntaxhighlight lang="csharp"> | |||
Array.Sort(values, (x,y) => Math.Abs(x-y) < 1e-12 ? 0 : x.CompareTo(y)); | |||
</syntaxhighlight> | |||
=== Exceptions vermeiden === | |||
Verwendung von TryParse, keine Annahme auf exakte Darstellung (0.1 + 0.2 != 0.3 exakt). | |||
=== Häufige Fehlerquellen === | |||
* Direkter == Vergleich ohne Toleranz | |||
* decimal mit Math.* (gibt nur double-Überladungen für viele Funktionen) | |||
* Kulturabhängige Dezimaltrennzeichen beim Parse | |||
* Rundung (MidpointRounding falsch gewählt) | |||
* Überlauf in decimal (Casting von sehr großen double) | |||
=== Auswahlhilfe === | |||
* Wissenschaft / Grafik: float (wenn Speicher wichtig) oder double | |||
* Standard: double | |||
* Geld / Finanzen (exakte Dezimalstellen): decimal | |||
=== Zusammenfassung Fließkomma === | |||
Kurzliste: + - * / Vergleich mit Toleranz, Math (Sqrt, Pow, Sin, Cos, Log, Exp, Clamp, Min/Max, CopySign, FusedMultiplyAdd), Round/Ceiling/Floor/Truncate, double.IsNaN/IsInfinity/IsFinite, Parse/TryParse, ToString("G17","F","E","R"), BitConverter.*Bits, Random.Shared.NextDouble, Kahan-Summe, decimal für Geld. | |||
= C# bool-Operationen und wichtige Methoden = | |||
== Typ & Literale == | |||
<syntaxhighlight lang="csharp"> | |||
bool t = true; | |||
bool f = false; | |||
</syntaxhighlight> | |||
Wird primär für Kontrollfluss genutzt; keine implizite Konvertierung zu/zur Zahl. | |||
== Logische Operatoren == | |||
<syntaxhighlight lang="csharp"> | |||
bool not = !t; // Negation | |||
bool both = a && b; // UND (short-circuit) | |||
bool either = a || b; // ODER (short-circuit) | |||
bool xor = a ^ b; // Exklusiv-Oder | |||
</syntaxhighlight> | |||
& und | auf bool werten beide Operanden immer aus: | |||
<syntaxhighlight lang="csharp"> | |||
bool bothAll = a & b; | |||
bool eitherAll = a | b; | |||
</syntaxhighlight> | |||
== Vergleich == | |||
<syntaxhighlight lang="csharp"> | |||
bool eq = a == b; | |||
bool ne = a != b; | |||
</syntaxhighlight> | |||
== Zuweisung vs Vergleich == | |||
<syntaxhighlight lang="csharp"> | |||
// if (a = b) // Compilerfehler (gut gegen Verwechslung mit ==) | |||
</syntaxhighlight> | |||
== Operator-Präzedenz (Auszug) == | |||
! vor && vor ||. Klammern für Klarheit: | |||
<syntaxhighlight lang="csharp"> | |||
if (!(a || b) && c) { } | |||
</syntaxhighlight> | |||
== De Morgan == | |||
<syntaxhighlight lang="csharp"> | |||
!(a && b) == !a || !b; | |||
!(a || b) == !a && !b; | |||
</syntaxhighlight> | |||
== Ternärer Operator == | |||
<syntaxhighlight lang="csharp"> | |||
string msg = ok ? "OK" : "FAIL"; | |||
</syntaxhighlight> | |||
== Nullable bool (bool?) == | |||
Drei Zustände: true, false, null. | |||
<syntaxhighlight lang="csharp"> | |||
bool? x = null; | |||
if (x is true) { } | |||
bool res = x ?? false; | |||
bool onlyTrue = x == true; | |||
</syntaxhighlight> | |||
== Pattern Matching == | |||
<syntaxhighlight lang="csharp"> | |||
if (flag is true) { } | |||
switch (flag) { | |||
case true: break; | |||
case false: break; | |||
} | |||
</syntaxhighlight> | |||
== Parsing & Formatierung == | |||
<syntaxhighlight lang="csharp"> | |||
bool b1 = bool.Parse("true"); | |||
if (bool.TryParse("False", out var b2)) { } | |||
string s = b2.ToString(); // "True"/"False" | |||
</syntaxhighlight> | |||
== Konvertierung zu Zahl == | |||
<syntaxhighlight lang="csharp"> | |||
int bit = flag ? 1 : 0; | |||
</syntaxhighlight> | |||
== Seiteneffekte erzwingen == | |||
<syntaxhighlight lang="csharp"> | |||
if (CheckA() & CheckB()) { } // beide werden sicher ausgeführt | |||
if (CheckA() && CheckB()) { } // CheckB nur bei wahr von CheckA | |||
</syntaxhighlight> | |||
== Guard / Früher Rückgabepunkt == | |||
<syntaxhighlight lang="csharp"> | |||
if (!isValid) return; | |||
</syntaxhighlight> | |||
== Debug / Verträge == | |||
<syntaxhighlight lang="csharp"> | |||
Debug.Assert(condition); | |||
Trace.Assert(condition); | |||
</syntaxhighlight> | |||
== Häufige Fehlerquellen == | |||
* Erwartete Ausführung des rechten Operanden bei && / || (short-circuit) | |||
* Nutzung von & / | statt && / || (unbeabsichtigte Seiteneffekte) | |||
* Null nicht beachtet bei bool? | |||
* String-Parsing mit falscher Groß/Kleinschreibung (TryParse berücksichtigt beides) | |||
== Kurzliste == | |||
true/false, !, &&, ||, ^, &, | (kein short-circuit), ?:, ==, !=, bool.Parse/TryParse, bool?, Pattern (is true/false), De Morgan, Debug.Assert. | |||
Aktuelle Version vom 6. September 2025, 04:32 Uhr
String
Grundlagen
- Deklaration
string name = "Alice";
string leer = string.Empty;
- Verkettung
string full = vorname + " " + nachname;
string interp = $"{vorname} {nachname}";
var builder = new StringBuilder().Append(vorname).Append(' ').Append(nachname).ToString();
Häufig genutzte Eigenschaften
- Length – Anzahl der UTF-16 Codeeinheiten (nicht zwingend Benutzer-grafeme)
Vergleich
string.Equals(a, b); // Ordinal, case-sensitiv
string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
a.Equals(b, StringComparison.Ordinal);
a == b; // Wertvergleich
string.Compare(a, b, StringComparison.Ordinal);
Suchen
str.Contains("abc", StringComparison.Ordinal);
str.StartsWith("pre", StringComparison.OrdinalIgnoreCase);
str.EndsWith("suf", StringComparison.Ordinal);
str.IndexOf("x", StringComparison.Ordinal);
str.LastIndexOf('.');
Extrahieren
str.Substring(startIndex);
str.Substring(startIndex, length);
str[startIndex]; // einzelnes char
Teilstrings moderner (Span-Slicing)
ReadOnlySpan<char> span = str.AsSpan();
var teil = span.Slice(5, 3); // vermeidet Kopie
Aufteilen & Zusammenfügen
var parts = str.Split('.', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
string joined = string.Join(";", parts);
Trimmen
str.Trim(); // Whitespace
str.TrimStart();
str.TrimEnd();
str.Trim('0'); // spezifische Zeichen
Ersetzen
str.Replace("alt", "neu");
str.Replace('a', 'b');
Regex.Replace(str, "[0-9]+", "#");
Formatierung
string.Format("Wert: {0:N2}", value);
$"Wert: {value:N2}";
value.ToString("N2", CultureInfo.InvariantCulture);
Groß/Kleinschreibung
str.ToUpperInvariant();
str.ToLower(CultureInfo.CurrentCulture);
Einfügen & Entfernen
str.Insert(index, "XYZ");
str.Remove(startIndex);
str.Remove(startIndex, count);
Pad (Auffüllen)
"42".PadLeft(5, '0'); // 00042
"42".PadRight(5, '.'); // 42...
Zeichenprüfung
char.IsLetterOrDigit(ch);
char.IsWhiteSpace(ch);
Immutable Hinweis
Strings sind unveränderlich. Viele Operationen erzeugen neue Instanzen. Für viele Verkettungen: StringBuilder.
StringBuilder
var sb = new StringBuilder(capacity:256)
.Append("Zeile ").AppendLine("1")
.AppendFormat("Wert={0}", 123);
string result = sb.ToString();
Sicherheitsrelevante Vergleiche
CryptographicOperations.FixedTimeEquals(
MemoryMarshal.AsBytes("secret"u8),
MemoryMarshal.AsBytes(eingabe.AsSpan()));
Null / Empty / WhiteSpace
string.IsNullOrEmpty(str);
string.IsNullOrWhiteSpace(str);
Interpolated String Handler (Performance)
[InterpolatedStringHandler]
public ref struct LogHandler {
// eigener Handler für Logging
}
Raw String Literals (C# 11)
string json = """
{
"id": 1,
"name": "Alice"
}
""";
Escapes
string pfad = @"C:\Temp\log.txt";
string zeile = "Text\nNeue Zeile\tTab";
Normalisierung (Unicode)
string norm = str.Normalize(NormalizationForm.FormC);
Split vs Span
Für Hochleistung: str.AsSpan().Split(...) (ab .NET 8: MemoryExtensions.Split)
Zusammenfassung
Kurzliste: Length, Indexer, Substring, Contains, StartsWith, EndsWith, IndexOf, Split, Join, Trim*, Replace, Insert, Remove, PadLeft/Right, ToUpper*/ToLower*, Format/$-Interpolation, Equals/Compare, Normalize, StringBuilder.
Ganzzahlen: Operationen und wichtige Methoden
Basis-Typen
- sbyte / byte (8 Bit), short / ushort (16), int / uint (32), long / ulong (64)
- nint / nuint (plattformabhängig), BigInteger (beliebig groß, System.Numerics)
Deklaration & Literale
int a = 42;
long b = 1_000_000_000L;
uint c = 0u;
nint p = 123n;
int bin = 0b1010_1100;
int hex = 0xFF_A0;
Konvertierung / Casting
long l = a; // implizit (erweiternd)
int k = (int)l; // explizit (evtl. Datenverlust)
int parsed = int.Parse("123", CultureInfo.InvariantCulture);
if (int.TryParse("123", out var val)) { /* ok */ }
Rechenoperationen
int sum = x + y;
int diff = x - y;
int prod = x * y;
int quot = x / y; // ganzzahlig, Rest abgeschnitten
int mod = x % y;
int neg = -x;
Division: Ganzzahl vs Gleitkomma
int r1 = 5 / 2; // 2
double r2 = 5 / 2.0; // 2.5
Inkrement / Dekrement
i++;
++i;
i--;
Overflow-Kontrolle
checked {
int o = int.MaxValue;
// int p = o + 1; // OverflowException
}
unchecked {
int wrap = int.MaxValue + 1; // Wrap-around
}
bool ok = int.TryParse("9999999999", out _); // false wenn außerhalb Range
Vergleich & Relationen
bool eq = a == b;
bool ne = a != b;
bool lt = a < b;
bool between = x >= min && x <= max;
Bitoperationen
int and = flags & mask;
int or = flags | mask;
int xor = flags ^ mask;
int not = ~flags;
int shiftedL = value << 3;
int shiftedR = value >> 2;
bool has = (flags & mask) != 0;
BitHelpers (.NET)
int pop = System.Numerics.BitOperations.PopCount((uint)value);
int leading = BitOperations.LeadingZeroCount((uint)value);
int rot = BitOperations.RotateLeft(value, 5);
Math / Numerik
int abs = Math.Abs(v);
int clamped = Math.Clamp(v, 0, 100);
int max = Math.Max(a, b);
int min = Math.Min(a, b);
int sign = Math.Sign(v);
long pow2 = 1L << n;
Zufallszahlen
int r = Random.Shared.Next(0, 100); // 0..99
int rr = RandomNumberGenerator.GetInt32(0, 100); // kryptographisch
Parsing / Formatierung
int n = int.Parse("42");
if (int.TryParse("42", NumberStyles.Integer, CultureInfo.InvariantCulture, out var num)) {}
string s1 = num.ToString(); // kulturabhängig
string s2 = num.ToString("D6"); // führende Nullen
string hexStr = num.ToString("X"); // Hex
Performance / Span Parsing
ReadOnlySpan<char> span = "12345".AsSpan();
if (int.TryParse(span, out int fast)) { }
Checked Arithmetik Helpers (C# 11+)
int safe = int.CreateChecked((long)other);
int trunc = int.CreateTruncating(big);
int sat = int.CreateSaturating(big);
Pattern Matching / Ranges
bool ok = value is >= 0 and <= 10;
Flags Enum Beispiel
[Flags]
enum Perm { None=0, Read=1, Write=2, Exec=4 }
Perm p = Perm.Read | Perm.Write;
bool canWrite = p.HasFlag(Perm.Write); // langsamer
bool canWriteFast = (p & Perm.Write) != 0;
Häufige Fehlerquellen
- Ganzzahldivision statt Gleitkomma
- Overflow bei Multiplikation (checked nutzen)
- Parse ohne Fehlerprüfung
- Bitmasken falsch (Klammern, Vorzeichen)
Zusammenfassung Ganzzahlen
Kurzliste: + - * / % ++ -- Vergleiche, Bit: & | ^ ~ << >>, Parse/TryParse, ToString("D"/"X"), Math.* (Abs, Clamp, Min, Max, Sign), Random.Shared.Next, BitOperations (PopCount/Rotate/LeadingZeroCount), checked/unchecked, Flags-Enums.
Fließkommazahlen: Operationen und wichtige Methoden
Typen & Eigenschaften
- float (Single, 32 Bit IEEE 754, ca. 7 Dezimalstellen)
- double (64 Bit IEEE 754, ca. 15–17 Dezimalstellen) – Standard
- decimal (128 Bit, Basis-10, 28–29 signifikante Stellen, langsamer, für Geld/Buchhaltung)
float f = 1.5f;
double d = 1.5;
decimal m = 1.5m;
Basis-Operationen
double sum = a + b;
double diff = a - b;
double prod = a * b;
double quot = a / b;
double neg = -a;
Vergleich (Toleranz)
Direkter == Vergleich problematisch wegen Rundungsfehlern.
bool AreClose(double x, double y, double relEps = 1e-12, double absEps = 1e-15) {
double diff = Math.Abs(x - y);
if (diff <= absEps) return true;
return diff <= relEps * Math.Max(Math.Abs(x), Math.Abs(y));
}
Spezielle Werte
double nan = double.NaN;
double posInf = double.PositiveInfinity;
double negInf = double.NegativeInfinity;
bool isNan = double.IsNaN(nan);
bool isInf = double.IsInfinity(posInf);
bool isFinite = double.IsFinite(1.0);
double eps = double.Epsilon; // kleinste >0 Subnormal bei double
Decimal Besonderheiten
decimal preis = 12.34m;
decimal sum = preis * 3; // exakte Dezimalarithmetik (Basis 10)
Casting / Konvertierung
double dd = (double)f; // implizit float -> double
float ff = (float)dd; // explizit (Präzisionsverlust)
decimal dm = (decimal)dd; // kann Overflow werfen
double back = (double)dm;
Rundung
double r1 = Math.Round(2.345, 2); // Banker's (ToEven)
double r2 = Math.Round(2.345, 2, MidpointRounding.AwayFromZero);
double ceil = Math.Ceiling(x);
double floor = Math.Floor(x);
double trunc = Math.Truncate(x);
Math Funktionen
double abs = Math.Abs(x);
double pow = Math.Pow(2.0, 10);
double sq = Math.Sqrt(v);
double c = Math.Cos(a);
double s = Math.Sin(a);
double t = Math.Tan(a);
double exp = Math.Exp(a);
double ln = Math.Log(a);
double log10 = Math.Log10(a);
double clamped = Math.Clamp(x, 0.0, 1.0);
double min = Math.Min(a, b);
double max = Math.Max(a, b);
double copySign = Math.CopySign(magnitude:5.0, sign:-2.0);
MathF für float
float sf = MathF.Sqrt(3f);
Fused Multiply-Add (FMA)
double fma = Math.FusedMultiplyAdd(a, b, c); // a*b + c mit geringerer Rundung
Parsing & Formatierung
double v = double.Parse("1.23", CultureInfo.InvariantCulture);
if (double.TryParse("1.23", NumberStyles.Float, CultureInfo.InvariantCulture, out var parsed)) { }
string sG = v.ToString("G17", CultureInfo.InvariantCulture); // max Genauigkeit double
string sF = v.ToString("F2"); // 2 Nachkommastellen
string sE = v.ToString("E3"); // wissenschaftlich
string sR = v.ToString("R"); // Round-trip
Span Parsing (Performance)
ReadOnlySpan<char> span = "3.14159".AsSpan();
if (double.TryParse(span, NumberStyles.Float, CultureInfo.InvariantCulture, out double pi)) { }
Interop / Bit-Ebene
long bits = BitConverter.DoubleToInt64Bits(d);
double again = BitConverter.Int64BitsToDouble(bits);
int floatBits = BitConverter.SingleToInt32Bits(f);
NaN Verhalten
bool eqNaN = double.NaN == double.NaN; // false
bool notEq = double.NaN != double.NaN; // true
bool ordered = double.NaN < 1.0; // false
Aggregationen / Summe (Stabilität)
double StableSum(double[] data) {
double sum = 0, c = 0; // Kahan
foreach (var x in data) {
double y = x - c;
double t = sum + y;
c = (t - sum) - y;
sum = t;
}
return sum;
}
Random Gleitkomma
double r = Random.Shared.NextDouble(); // [0,1)
double rRange = Random.Shared.NextDouble() * (max - min) + min;
Performance Hinweise
- double schneller als decimal
- float spart Speicher (Arrays, GPU), aber geringere Präzision
- Avoid boxing bei Formatierung durch Span-basierte APIs (TryFormat)
Tolerante Sortierung Beispiel
Array.Sort(values, (x,y) => Math.Abs(x-y) < 1e-12 ? 0 : x.CompareTo(y));
Exceptions vermeiden
Verwendung von TryParse, keine Annahme auf exakte Darstellung (0.1 + 0.2 != 0.3 exakt).
Häufige Fehlerquellen
- Direkter == Vergleich ohne Toleranz
- decimal mit Math.* (gibt nur double-Überladungen für viele Funktionen)
- Kulturabhängige Dezimaltrennzeichen beim Parse
- Rundung (MidpointRounding falsch gewählt)
- Überlauf in decimal (Casting von sehr großen double)
Auswahlhilfe
- Wissenschaft / Grafik: float (wenn Speicher wichtig) oder double
- Standard: double
- Geld / Finanzen (exakte Dezimalstellen): decimal
Zusammenfassung Fließkomma
Kurzliste: + - * / Vergleich mit Toleranz, Math (Sqrt, Pow, Sin, Cos, Log, Exp, Clamp, Min/Max, CopySign, FusedMultiplyAdd), Round/Ceiling/Floor/Truncate, double.IsNaN/IsInfinity/IsFinite, Parse/TryParse, ToString("G17","F","E","R"), BitConverter.*Bits, Random.Shared.NextDouble, Kahan-Summe, decimal für Geld.
C# bool-Operationen und wichtige Methoden
Typ & Literale
bool t = true;
bool f = false;
Wird primär für Kontrollfluss genutzt; keine implizite Konvertierung zu/zur Zahl.
Logische Operatoren
bool not = !t; // Negation
bool both = a && b; // UND (short-circuit)
bool either = a || b; // ODER (short-circuit)
bool xor = a ^ b; // Exklusiv-Oder
& und | auf bool werten beide Operanden immer aus:
bool bothAll = a & b;
bool eitherAll = a | b;
Vergleich
bool eq = a == b;
bool ne = a != b;
Zuweisung vs Vergleich
// if (a = b) // Compilerfehler (gut gegen Verwechslung mit ==)
Operator-Präzedenz (Auszug)
! vor && vor ||. Klammern für Klarheit:
if (!(a || b) && c) { }
De Morgan
!(a && b) == !a || !b;
!(a || b) == !a && !b;
Ternärer Operator
string msg = ok ? "OK" : "FAIL";
Nullable bool (bool?)
Drei Zustände: true, false, null.
bool? x = null;
if (x is true) { }
bool res = x ?? false;
bool onlyTrue = x == true;
Pattern Matching
if (flag is true) { }
switch (flag) {
case true: break;
case false: break;
}
Parsing & Formatierung
bool b1 = bool.Parse("true");
if (bool.TryParse("False", out var b2)) { }
string s = b2.ToString(); // "True"/"False"
Konvertierung zu Zahl
int bit = flag ? 1 : 0;
Seiteneffekte erzwingen
if (CheckA() & CheckB()) { } // beide werden sicher ausgeführt
if (CheckA() && CheckB()) { } // CheckB nur bei wahr von CheckA
Guard / Früher Rückgabepunkt
if (!isValid) return;
Debug / Verträge
Debug.Assert(condition);
Trace.Assert(condition);
Häufige Fehlerquellen
- Erwartete Ausführung des rechten Operanden bei && / || (short-circuit)
- Nutzung von & / | statt && / || (unbeabsichtigte Seiteneffekte)
- Null nicht beachtet bei bool?
- String-Parsing mit falscher Groß/Kleinschreibung (TryParse berücksichtigt beides)
Kurzliste
true/false, !, &&, ||, ^, &, | (kein short-circuit), ?:, ==, !=, bool.Parse/TryParse, bool?, Pattern (is true/false), De Morgan, Debug.Assert.