Inhaltsverzeichnis

std.mathx — genaue Elementarfunktionen

exp, log, sin, cos, tan und atan mit ordentlicher Argumentreduktion — dazu die Genauigkeitsvarianten expm1/log1p, die hyperbolischen Funktionen und den Zugriff auf die Exponentenebene.

→ Mathematik-Units · std.feq · std.math · std.complex

import std.mathx;

Schicht 1, hängt an std.feq, std.math und std.alloc. 29 Funktionen. Alle Beispiele mit lyxc 1.0.21A übersetzt und ausgeführt.


Warum es diese Unit gibt

ExpF64 und LogF64 aus std.math tragen rund 1e−7 relativen Fehler — die halbe Genauigkeit, die f64 hergibt. Alles, was darauf aufbaut, erbt das: PowF64 (ist exp∘log), Gamma, sämtliche Verteilungen, Entropien.

Der Unterschied lässt sich nicht mit PrintF64 zeigen — sechs Nachkommastellen verdecken ihn. Über die Bitmuster ist er eindeutig:

unit main;
import std.io;
import std.string;
import std.math;
import std.feq;
import std.mathx;

fn ZB(t: pchar, v: f64): void { Print(t); PrintLn(IntToStr(FeqBits(v))); }

fn main(): int64 {
    ZB("Bits MxLog(1000)  : ", MxLog(1000.0));
    ZB("Bits LogF64(1000) : ", LogF64(1000.0));
    ZB("Bits MxExp(10)    : ", MxExp(10.0));
    ZB("Bits ExpF64(10)   : ", ExpF64(10.0));
    return 0;
}

Bits MxLog(1000)  : 4619463459452485536
Bits LogF64(1000) : 4619463459373954948
Bits MxExp(10)    : 4671783802770883936
Bits ExpF64(10)   : 4671783802770877367

Funktion Abstand zum exakten Wert
MxLog(1000) 0 ULP — bitgenau
LogF64(1000) 78 530 588 ULP
MxExp(10) 0 ULP — bitgenau
ExpF64(10) 6 569 ULP

Die Mx-Fassungen treffen das Bitmuster der Referenzrechnung exakt. Bei LogF64 liegen dazwischen über 78 Millionen darstellbare Zahlen.

 
Wo das zählt und wo nicht. Für eine Anzeige mit zwei Nachkommastellen ist 1e−7 belanglos. Sobald ein Ergebnis aber weiterverrechnet wird — Produkte vieler Logarithmen, Iterationen, Differenzen fast gleicher Werte —, wächst der Fehler mit. Eine Verteilungsfunktion, die intern zwanzig Mal exp aufruft, hat am Ende keine sieben Stellen mehr.

Argumentreduktion

MxSin und MxCos zerlegen π/2 in sechs 21-Bit-Stücke. Das klingt umständlich, ist aber der Grund, warum sie bei großen Argumenten noch etwas Sinnvolles liefern: bei sin(1e16) entscheidet die Genauigkeit der π/2-Darstellung darüber, welcher Punkt der Periode überhaupt getroffen wird.

 
SinF64 meldet große Argumente inzwischen, statt still falsch zu rechnen (#1829, nachgemessen mit lyxc 1.2.2B): SinF64(1e16) liefert nan. Früher kam dort 0.909297 heraus — der Wert von sin(2), weil die Argumentreduktion bei dieser Größenordnung nicht mehr trägt. Ein NaN fällt auf, eine plausible falsche Zahl nicht.

MxSin rechnet dort weiter: MxSin(1e16) liefert 0.971758. Bis etwa 1e9 stimmen beide überein (0.545843).

Im normalen Bereich stimmt std.math: SinF64(3.0) → 0.141120, CosF64(0.0) → 1.000000. Der frühere Wert -11.89 aus der installierten Fassung (#1578) tritt nicht mehr auf — installierter Baum und Repository liefern dasselbe.

MxSin/MxCos bleiben der Weg für große Argumente.

MxSinCos(x, sinAddr, cosAddr) rechnet beide auf einmal und spart die zweite Reduktion — bei Drehfaktoren und Koordinatentransformationen die günstigere Form.


''atan2'' — der zweite Reparaturfall

 
Atan2F64 achtet seit #1577 auf das Vorzeichen der Null — die Fallreihenfolge folgt C99 F.10.1.4, atan2(-0.0, -1.0) ergibt -π. Was bleibt, ist die Genauigkeit von etwa zehn Stellen; dafür gibt es MxAtan2.

Das Vorzeichen der Null ist kein Spitzfindigkeit: bei komplexen Verzweigungsschnitten und bei Winkeln nahe π entscheidet es darüber, ob das Ergebnis +π oder −π lautet.


Genauigkeitsvarianten

var x: f64 := 0.000000001;
MxExpm1(x)        // exp(x) - 1, ohne Auslöschung
MxLog1p(x)        // log(1 + x), ohne Auslöschung

Bei kleinem x ist exp(x) fast genau 1. Die Differenz exp(x) − 1 löscht dann die führenden Stellen aus — von 16 Stellen bleiben bei x = 1e−9 noch etwa sieben. MxExpm1 rechnet die Differenz direkt und behält alle Stellen.

Das ist der Normalfall in der Zinsrechnung (kleine Zinssätze über kurze Zeiträume) und in der Wahrscheinlichkeitsrechnung (Wahrscheinlichkeiten nahe 0 oder 1).


Funktionsübersicht

Gruppe Funktionen
Exponential und Logarithmus MxExp · MxLog · MxLog2 · MxLog10 · MxExp2 · MxExp10 · MxPow
Genauigkeitsvarianten MxExpm1 · MxLog1p
Winkelfunktionen MxSin · MxCos · MxTan · MxSinCos · MxAtan · MxAtan2
Hyperbolisch MxSinh · MxCosh · MxTanh · MxAsinh · MxAcosh · MxAtanh
Wurzeln und Reste MxCbrt · MxFmod · MxRemainder
Exponentenebene MxLdexp · MxFrexp · MxScalbn · MxCopySign · MxModf
 
MxFmod und MxRemainder sind nicht dasselbe. Für 7,5 und 2 liefert MxFmod den Wert 1,5 — den Rest mit dem Vorzeichen des Dividenden, wie % bei Ganzzahlen. MxRemainder liefert −0,5: den Rest zum nächstgelegenen Vielfachen, also stets betragsmäßig höchstens die Hälfte des Divisors. Für Winkelnormalisierung ist MxRemainder die richtige Wahl, für „wie viel bleibt übrig„ MxFmod.

Die Exponentenfunktionen arbeiten auf der Bitdarstellung: MxLdexp(x, n) multipliziert mit 2ⁿ ohne zu rechnen, MxFrexp zerlegt in Mantisse und Exponent, MxModf in Vor- und Nachkommateil.


Offener Punkt

 
Nicht alles im Bestand nutzt die genauen Fassungen. QuatExp, ProbLogGamma und die Verteilungen in std.prob rufen weiterhin ExpF64/LogF64 auf und erben deren 1e−7. Ebenso rechnen fft, tensor, autodiff, prob und quat die Winkelfunktionen über SinF64/CosF64 — sie sind damit davon abhängig, welche Fassung der Standardbibliothek eingebunden ist. Eine Umstellung auf MxSinCos ist vorgeschlagen, aber nicht entschieden.

Letzte Aktualisierung: 2026-09-05 (#1829, nachgemessen mit lyxc 1.2.2B) — Kasten gezogen: SinF64 liefert bei sehr großen Argumenten nan statt eines falschen Werts.

Vorherige letzte Aktualisierung: 2026-08-16 · alle Beispiele mit lyxc 1.0.21A übersetzt und ausgeführt; die Genauigkeit über Bitmuster gegen eine unabhängige Referenzrechnung gemessen, nicht über die Textausgabe.

Codebeispiele geprüft: gegen lyxc 1.2.5C übersetzt (Prüflauf 2026-09-08 über die gesamte Doku: 574 Vollprogramme, 0 echte Fehler; zusätzlich 5159 Aufrufe gegen die pub fn-Signaturen in aurum/std gehalten, 0 Abweichungen).