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.
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.
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.
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.
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.
| 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.