Danke für die Tipps.
In die Richtung dachte ich auch schon. Aber wenn ich statt
Single
Double
oder
Extended
verwende, bleibt das Ergebnis trotzdem gleich. Die Unschärfe muss also woanders herkommen. Ich habs der Korrektheit wegen aber auf
Extended
umgestellt.
Das Ergebnis, wenn einer der Werte
NaN
ist, wäre in dem Fall dann auch
NaN
. Den Part kann man also wegkürzen und mit der Bedingung
if sigma < 0 then
zusammenfassen. Ich hab das so aus der C-Implementierung übernommen, aber in Delphi macht das keinen Sinn.
Dein Bedenken mit der Prüfung auf exakte Gleichheit bei Floating-Variablen stimmt generell auch. Ist in dem Fall aber nicht so wichtig, da die Funktion in diesem Fall wirklich exakt 0 oder 1 übergeben bekommen würde. Der Korrektheit wegen habe ich's aber auch umgestellt. Aber statt
CompareValue
habe ich
SameValue
genommen.
Überarbeitete Funktion:
Delphi-Quellcode:
function qnorm(p: Extended; mu: Extended = 0; sigma: Extended = 1): Extended;
begin
if IsNan(p) or IsNan(mu) or IsNan(sigma) or (sigma < 0) then
Result := NAN
else if sigma = 0 then
Result := mu
else if SameValue(p, 0) then
Result := -Infinity
else if SameValue(p, 1) then
Result := Infinity
else
try
Result := Sqrt(Abs(0.5 * Pi * Ln(1 - Sqr(1 - 2 * p))));
if p < 0.5 then
Result := -Result;
Result := mu + sigma * Result;
except
Result := NAN;
end;
end;
PS: Oben muss es natürlich heissen
qnorm(0.05)
statt
qnorm(0.5)
. Denn
qnorm(0.5)
= 0. Habs mal editiert.