* improved complex / operator by Dimitrios Apostolou

git-svn-id: trunk@5279 -
This commit is contained in:
florian 2006-11-07 21:09:57 +00:00
parent 08f72e02f4
commit 7cc78b6ae1

View File

@ -315,14 +315,35 @@ Unit UComplex;
inline; inline;
{$endif TEST_INLINE} {$endif TEST_INLINE}
{ division : z := znum / zden } { division : z := znum / zden }
var { The following algorithm is used to properly handle
denom : real; denominator overflow:
begin
with zden do denom := (re * re) + (im * im); | a + b(d/c) c - a(d/c)
{ generates a fpu exception if denom=0 as for reals } | ---------- + ---------- I if |d| < |c|
z.re := ((znum.re * zden.re) + (znum.im * zden.im)) / denom; a + b I | c + d(d/c) a + d(d/c)
z.im := ((znum.im * zden.re) - (znum.re * zden.im)) / denom; ------- = |
end; c + d I | b + a(c/d) -a+ b(c/d)
| ---------- + ---------- I if |d| >= |c|
| d + c(c/d) d + c(c/d)
}
var
tmp, denom : real;
begin
if ( abs(zden.re) > abs(zden.im) ) then
begin
tmp := zden.im / zden.re;
denom := zden.re + zden.im * tmp;
z.re := (znum.re + znum.im * tmp) / denom;
z.im := (znum.im - znum.re * tmp) / denom;
end
else
begin
tmp := zden.re / zden.im;
denom := zden.im + zden.re * tmp;
z.re := (znum.im + znum.re * tmp) / denom;
z.im := (-znum.re + znum.im * tmp) / denom;
end;
end;
operator / (znum : complex; r : real) z : complex; operator / (znum : complex; r : real) z : complex;
{ division : z := znum / r } { division : z := znum / r }