Emil Jerabek wrote:
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;
Well, this one is a little longer than the previous ones, so should I use it?
When I pointed out these special cases in previous mails, I didn't mean to says we should cater for all kinds of practically impossible situations, I rather meant to ask you if you see any real problems (since my numeric experience is rather limited). E.g., when using the previous version on a machine that really has such strange properties, would it merely produce inaccurate results in some borderline cases (which is probably acceptable on such a strange machine), or produce clearly visible errors (so a user on such a platform would recognize it and report it as a bug, and we'd know about the problem and where it happens), or could it silently produce substantially wrongs results (which would be a real problem)?
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.
At least that's a known bug (at least known to us; I'll have to check the to-do list if it's listed there). I'll look into it ... (emil11.pas)
I also wondered if the compiler catches this as a violation of the standard when compiled with `--extended-pascal' or `-pedantic'. It compiled happily with the former (when I replaced `Val' with `ReadStr', of course), but the result with `-pedantic' was somewhat surprising. It seems that even the wheel was invented in San Diego :-)
Of course, the errors about `SqRt', `Ord' and `WriteLn' are wrong (happens for all standard functions because of a systematic bug). Fixing it. (emil10.pas)
(Apart from that, shouldn't it produce warnings rather than errors?)
It did until a recent discussion here when people noted that there should be errors with `--extended-pascal' (or other dialect options which don't contain the given feature), so I changed it. One might want to make it warnings with `-pedantic' and errors with `--extended-pascal', but doing this will be some extra work. If you like to do it, go ahead. ;-) I won't do it for such an unimportant thing (IMHO -- since a program that compiles without problems with `-pedantic' must be in the intersection of ISO 7185, UCSD and Borland Pascal and maybe more, which gives a rather restricted language ;-).
Frank