std.complex — komplexe Zahlen
Die komplexe Zahl als Wert: Division nach Smith, Betrag über hypot (überlaufsicher bis 1e200), Verzweigungsschnitte nach C99 Annex G.
→ Mathematik-Units · std.fft · std.tensor · std.mathx
import std.complex;
Schicht 2, hängt an std.dist, std.feq und std.mathx. 56 Funktionen. Alle Beispiele mit lyxc 1.0.21A übersetzt und ausgeführt.
Die Struct-Rückgabe legt keinen Speicher mehr an (#1580 behoben). Vorher kostete jeder Aufruf zweimmapohnemunmap— die Kopie bei der Rückgabe und, größer noch, die Deklarationvar p: Pair;mit 4096 Byte. Nachgemessen mit 1.1.2E über 200 000 Rückgaben:
Laufzeit 0,05 s, Spitzenspeicher 6272 kB mmap-Aufrufe insgesamt: 9 (Programmstart, nicht die Schleife)
Der frühere Rat, in Schleifen adressbasiert zu arbeiten, ist damit hinfällig. Für Signalverarbeitung über viele Werte bleibt std.fft mit getrennten Re/Im-Feldern trotzdem der direktere Weg;CxLoad/CxStoreschlagen die Brücke.
Zwei Darstellungen, eine Brücke
std.fft und std.tensor halten Real- und Imaginärteil in getrennten Feldern — gut für lange Reihen, umständlich für eine einzelne Zahl. std.complex ergänzt die einzelne Zahl als Wert:
var z: Cx := CxLoad(reArr, imArr, i); // aus getrennten Feldern
CxStore(z, reArr, imArr, i); // und zurück
Damit lässt sich eine einzelne Stelle bequem rechnen, ohne die Feldstruktur aufzugeben.
Rechnen
unit main;
import std.io;
import std.string;
import std.complex;
fn ZC(t: pchar, z: Cx): void {
Print(t); PrintF64(CxRe(z)); Print(" im="); PrintF64(CxIm(z));
}
fn ZF(t: pchar, v: f64): void { Print(t); PrintF64(v); }
fn main(): int64 {
var a: Cx := CxNew(3.0, 4.0);
var b: Cx := CxNew(1.0, 2.0);
ZF("Abs(3+4i) re=", CxAbs(a));
ZC("Mul(3+4i, 1+2i) re=", CxMul(a, b));
ZC("Div(3+4i, 1+2i) re=", CxDiv(a, b));
ZF("Arg(i) re=", CxArg(CxI()));
var big: Cx := CxNew(1.0e200, 1.0e200);
ZF("Abs(1e200+1e200i)/1e200 = ", CxAbs(big) / 1.0e200);
return 0;
}
Abs(3+4i) re=5.000000
Mul(3+4i, 1+2i) re=-5.000000
im=10.000000
Div(3+4i, 1+2i) re=2.200000
im=-0.400000
Arg(i) re=1.570796
Abs(1e200+1e200i)/1e200 = 1.414213
Sämtliche Werte stimmen mit der Referenzrechnung überein.
Zwei Entwurfsentscheidungen, die zählen
Der Betrag läuft überhypot, nicht über√(re² + im²). Bei1e200 + 1e200iüberläuft schon das Quadrat — die naive Formel liefertinf, obwohl das Ergebnis1,41e200problemlos darstellbar ist. Oben ist es nachgemessen: geteilt durch1e200kommt1,414213heraus, also ein endlicher Wert.
Die Division rechnet nach Smith, nicht nach der Lehrbuchformel.(ac+bd)/(c²+d²)überläuft aus demselben Grund. Smith klammert vorher den betragsgrößeren Nenneranteil aus und bleibt damit im darstellbaren Bereich.
Verzweigungsschnitte
Bei sqrt, log, asin, acos, atanh und Verwandten ist die komplexe Funktion mehrdeutig; welcher Zweig gilt, legt eine Konvention fest. std.complex folgt C99 Annex G — derselben Festlegung wie die C-Standardbibliothek und Pythons cmath.
Das Vorzeichen der Null entscheidet mit. Auf dem Schnitt selbst — etwa beilogentlang der negativen reellen Achse — hängt es von−0,0gegen+0,0ab, ob das Ergebnis+πioder−πilautet. Genau hier istAtan2F64ausstd.mathfehlerhaft (#1577): es verwirft das Vorzeichen der Null und landet in der falschen Halbebene.std.complexrechnet deshalb überMxAtan2aus std.mathx.
Funktionsübersicht
| Gruppe | Funktionen |
|---|---|
| Erzeugen | CxNew · CxFromReal · CxFromImag · CxFromPolar · CxZero · CxOne · CxI · CxCopy |
| Zerlegen | CxRe · CxIm · CxAbs · CxAbs2 · CxArg |
| Prüfen | CxIsZero · CxIsReal · CxIsNaN · CxIsInf · CxIsFinite |
| Grundrechenarten | CxAdd · CxSub · CxMul · CxDiv · CxNeg · CxConj · CxInv |
| Mit einer reellen Zahl | CxAddReal · CxSubReal · CxMulReal · CxDivReal |
| Brücke zu Feldern | CxLoad · CxStore |
Dazu die analytischen Funktionen — Wurzel, Exponential, Logarithmus, Potenz, Winkel- und Hyperbelfunktionen samt Umkehrungen — durchgehend mit den Schnitten nach C99.
CxAbs2 spart die Wurzel: für Vergleiche genügt das Betragsquadrat, und es ist zugleich der Ausdruck, der in Energie- und Leistungsrechnungen ohnehin gebraucht wird.
Bei einer Abweichung zuerst die Referenz prüfen. Beim komplexenpowwich das Ergebnis um 8e−6 von Pythonsabab. Mit einer Rechnung auf 60 Stellen nachgeprüft lag diese Unit bei 1,1e−13 und Python bei 8,3e−6. Ist eine Abweichung zu groß für IEEE-Rundung, muss nicht der eigene Code falsch sein. </box> —- Letzte Aktualisierung: 2026-08-16 · alle Beispiele mitlyxc 1.0.21A'' übersetzt und ausgeführt; Betrag, Produkt, Quotient und die Überlaufsicherheit gegen eine unabhängige Referenzrechnung geprüft, #1580 selbst nachgemessen.
