"Boris Gaertner" Boris.Gaertner@gmx.net wrote:
I use Squeak in Windows, with an Intel Celeron. On that platform the expressions 1.0e200 sin and 1.0e200 tan answer two different representations of NaN. which is certainly a wrong answer.
The Intel documentation (IA-32 Intel Architecture Software Developer's Manual) says for instructions FSIN and FPTAN: <citation> The source operand must be given in radians and must be within the range -2^63 to +2^63. </citation>
which is why a C compiler *MUST NOT* convert calls to sin() and tan() directly to uses of the FSIN and FPTAN instructions, unless the programmer has explicitly requested a non-standard fp mode (rather like the "-fnonstd" option of the Sun C compiler or the "-ffast-math" option of GCC.
Source values outside the range -2^63 to +2^63 can be reduced to the range of the instruction by subtracting an appropriate integer multiple of 2*pi or by using the FPREM instruction with a divisor of 2*pi. See the section titled 'Pi' in Chapter 8 of the IA-32 Intel Architecture Software Developer's Manual, Volume 1, for a discussion of the proper value to use for pi in performing such reductions.
Which is what someone implementing sin() and tan() in the maths library might do, yes. Although it is not the best advice. The Sun math library uses "infinite precision pi" for argument reduction. This can make testing a bit tricky as sin(3.14.......) is non-zero in the Sun library even for the representable number closest to pi. Demonstration: f% cat >sin.c #include "math.h" int main(void) { printf("%g\n", sin(M_PI)); return 0; } <EOF> f% cc sin.c -lm f% a.out 1.22465e-16 Where this _really_ matters of course is precisely for those very large argument values; using "infinite precision pi" and using the Intel recommended value will give you quite different answers.
In other words: The implementor of a maths library has the permission to do whatever he thinks is suitable. No, that's not what it says. They cannot give that permission. Permission to deliver bad answers in the name of speed can only come from the language standard or the programmer who invokes the compiler.
Boris, how about this as a replacement for your #testNaN2 method? It does not use the sin() and tan() functions in the C math library, and I think that it captures the intent of your original test. I should work correctly on little-endian and big-endian machines.
Is this OK? If so I'll suggest including it with your original posting (Stef is waiting to harvest it).
There are two attachments to this message: Boris Gaertner's FloatTests-additionalTests, plus my FloatTestPatch-3-dtl which provides an update for #testNaN2. Boris has approved my #testNaN2 update (private email), so I think that these two change set together can be approved.
Note: The #testNaN2 test may require an update for 64 bit Squeak, so I added a comment to that effect. But we can worry about that when 64 bit Squeak is available.
On Friday, October 1, 2004, at 05:41 PM, lewis@mail.msen.com wrote:
There are two attachments to this message: Boris Gaertner's FloatTests-additionalTests, plus my FloatTestPatch-3-dtl which provides an update for #testNaN2. Boris has approved my #testNaN2 update (private email), so I think that these two change set together can be approved.
Your updated testNaN2 looks like it should work correctly on all existing systems. It would be nice to have a platform-independent way to generate different NaN values without having to muck with the underlying bit patterns, but unfortunately it doesn't exist.
-- Tim Olson
squeak-dev@lists.squeakfoundation.org