This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: libm-test.inc: Computing ulps near FP_ZERO.
- From: "Carlos O'Donell" <carlos at redhat dot com>
- To: Brooks Moses <brooks_moses at mentor dot com>
- Cc: GNU C Library <libc-alpha at sourceware dot org>, "Joseph S. Myers" <joseph at codesourcery dot com>, Andreas Jaeger <aj at suse dot com>, Thomas Schwinge <thomas at codesourcery dot com>, David Miller <davem at davemloft dot net>
- Date: Tue, 09 Apr 2013 09:58:28 -0400
- Subject: Re: libm-test.inc: Computing ulps near FP_ZERO.
- References: <51606D8A dot 9080003 at redhat dot com> <5160A4D7 dot 9080802 at codesourcery dot com> <516183BD dot 6060700 at redhat dot com> <5161AADF dot 2040403 at codesourcery dot com> <5161FA1A dot 5060100 at redhat dot com> <51620F35 dot 5080101 at codesourcery dot com> <51634CA1 dot 4050006 at redhat dot com> <51636912 dot 10702 at codesourcery dot com> <5163710F dot 9080500 at mentor dot com>
On 04/08/2013 09:38 PM, Brooks Moses wrote:
> Brooks Moses wrote, at 4/8/2013 6:04 PM:
>> Carlos O'Donell wrote, at 4/8/2013 4:02 PM:
>>> Regenerating ULPs for /home/carlos/build/glibc/math/test-idouble
>>> testing double (inline functions)
>>> Failure: Test: cos (pi/2) == PI_ERROR/2
>>> Result:
>>> is: 6.12323399573676603587e-17 0x1.1a62633145c070000000p-54
>>> should be: 1.11022302462515654042e-16 0x1.00000000000000000000p-53
>>> difference: 4.97899625051479936837e-17 0x1.cb3b399d747f20000000p-55
>>> ulp(x) : 2.46519032881566189191e-32 0x1.00000000000000000000p-105
>>> ulp : 2019720827359740.5000
>>> max.ulp : 0.0000
>>
>> I think you've missed the bit where I pointed out that the expected
>> result here is "0 +/- ulp(pi/2)/2", not "ulp(pi/2)/2"!
>>
>> In other words, you've confused the expected error bound with the
>> expected result.
>
> Which is to say that there's a more fundamental problem here, because
> there's no clear way to implement what you actually need to do in the
> test harness as it stands. This test suite is assuming (in, e.g.,
> check_float_internal) that some fixed multiple of ulp(expected) is a
> reasonable measure of the expected error bounds.
>
> That, in this case, is fundamentally _false_.
Do you say this because cos(pi/2) has an answer that is a bound rather
than a fixed answer? It would be true in the general case, but as I
said earlier it's not true in the specific case. You know the exact
answer because you know the machine format and error. What I need to
do is exactly what Rich recommends, which is to use an alternate
implementation to precisely calculate cos(M_PI_2l) and use that answer
as the real answer.
> You cannot meaningfully test cos(pi/2) with a function that takes the
> error and divides it by ulp(result) and then looks at the resulting
> number. The result of that division is meaningless, because ulp(result)
> is irrelevant to the expected error.
Careful. It's not meaningless. It's *one* way to measure error. The
alternative would be to use relative error. We know the exact answer
to cos(M_PI_2l).
> Given those circumstances, setting ulp(0) equal to ulp(1) is a very
> workable hack around that limitation of the test harness, and will cause
> it to get the correct answer in the end -- namely, that a result of
> 6e-17 should be a pass, because ulp(1) is what we _actually_ want to be
> using as a threshold.
Why is it actually what we want as a threshold?
> And, for the cases where the expected result is zero and you really do
> want exactly zero, you can just pass a zero max_ulp value to check_float
> and it will do what you need there too.
:-)
Cheers,
Carlos.