Please see below ...
Joe. ( Feeling a bit better :-)
-----Original Message----- From: Emil Jerabek [SMTP:ejer5183@artax.karlin.mff.cuni.cz] Sent: Wednesday, February 06, 2002 4:39 AM To: gpc@gnu.de Subject: Re: Complex_Arctan
Frank Heckenbach wrote:
Emil Jerabek wrote:
[...]
Your change doesn't solve this, it just reduces the threshold to EpsReal^2 > 4 / MaxReal. (BTW, the original implementation in
math.pas also needs
a similar condition.)
Frank, do you _really_ think there are machines with such a small
MaxReal?
It doesn't really matter what I think, does it? ;-) Actually, I haven't looked at any non-IEEE FP implementation in detail.
I'm applying Joe's patch (since it's certainly a little improvement). If you have more ideas for improvement, let me know.
Frank
So, here's another version :-) It should never overflow, AFAICS.
const Ln2 = 0.6931471805599453094172321214581765680755; var FunnyNumber: Real;
function Complex_ArcTan (z: Complex): Complex; var x, y, a, b, c, d: Real; begin x := Abs (Re (z)); y := Abs (Im (z)); b := 1 - y; d := (1 + y) / 2; if b < 0 then d := -d; b := Abs (b); if x >= b then begin c := b / x; d := d * c - x / 2; if x <= FunnyNumber then b := Ln2 - Ln (4 * x * Sqrt (1 + Sqr (c)) / (1 + y)) / 2 else b := Log1P (2 * (y / x) / (b * c / 2 + x / 2)) / 4; c := 1; end else begin c := x / b; a := x * c / 2; d := d - a; if b <= FunnyNumber then b := Ln2 - Ln (4 * b * Sqrt (1 + Sqr (c)) / (1 + y)) / 2 else b := Log1P (2 * (y / b) / (b / 2 + a)) / 4 end; d := ArcTan2 (c, d) / 2; if Re (z) < 0 then d := -d; if Im (z) < 0 then b := -b; Complex_ArcTan := Cmplx (d, b) end;
to begin do begin FunnyNumber := 2.1 / Sqrt (MaxReal); end;
I encountered a compiler bug during testing :-( Strictly speaking, the Standard doesn't allow function calls in constant expressions, but I expect the compiler would reject it if it were not supposed to work.
[Joe da Silva]
Well, actually the ISO-10206 standard (since the topic was complex maths, that is the applicable standard) *does* allow function calls in constant expressions. See sections 6.3.1, 6.3.2, 6.8.2. :-)
There are some restrictions of course, mainly to ensure that the constant expression is indeed constant. AFAIK, only pre-defined functions are allowed (although I haven't looked too closely at that).
Example from section 6.3.2 :
const ............... pi = 4 * arctan(1); ...............
[pas]% cat exprconst.pas program Foo (Output);
const Bar = 1 / Sqrt (16);
------ snip ------
Joe wrote:
Please see below ...
Joe. ( Feeling a bit better :-)
Good news :-)
Well, actually the ISO-10206 standard (since the topic was complex maths, that is the applicable standard) *does* allow function calls in constant expressions. See sections 6.3.1, 6.3.2, 6.8.2. :-)
There are some restrictions of course, mainly to ensure that the constant expression is indeed constant. AFAIK, only pre-defined functions are allowed (although I haven't looked too closely at that).
Example from section 6.3.2 :
const ............... pi = 4 * arctan(1); ...............
You are probably right. I got somewhat confused by the language of the standard ;-)
From section 6.8.2:
"...An expression shall be designated nonvarying if it does not contain the following ... c) an applied occurrence of an identifier as a function-identifier that has a defining-point contained by the program-block or that denotes one of the required functions eof or eoln. ..."
Section 6.2.2.1:
"Each identifier or label contained by the program-block shall have a defining-point, with the exception of the identifier of a program-heading (see 6.12)."
From section 6.2.2.10:
"Required identifiers that denote the required values, types, schemata, procedures, and functions shall be used as if their defining-points have a region enclosing the program (see 6.1.3, 6.4.2.2, 6.4.3.4, 6.4.3.6, 6.4.3.3.3, 6.7.5, 6.7.6, and 6.10). ..."
So, do those required identifiers have a defining-point or do they not?
Emil Jerabek