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 aus std.math rechnet bei großen Argumenten falsch (#1537) — sin(1e16) ergibt dort 0,909 statt 0,780; bei 1e12 stimmen noch etwa vier Stellen. Zusätzlich ist die installierte Standardbibliothek veralteter als das Repository (#1578) und liefert für SinF64(−6,282895) den Wert −11,89 — außerhalb des Wertebereichs.

MxSin/MxCos umgehen beides und sind zugleich unabhängig davon, welche Fassung der Standardbibliothek installiert ist.

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