www.digitalmars.com         C & C++   DMDScript  

D.gnu - unittests failures: constant folding of cos function gives

reply Johannes Pfau <nospam example.com> writes:
One of the tests in std.complex is failing because cos(LITERAL) and
cos(VARIABLE) return different results. AFAICS this happens only if the
parameter doesn't fit in 80bits and needs to be rounded. If
LITERAL/VARIABLE are values which fit exactly in 80bits we get the same
result. It's exactly the same situation in GCC.
I guess we just get higher precision when evaluating those functions
using constant folding as the LITERAL value is probably not rounded
before evaluating the cos.

So should we try to make the constant folding produce exactly the same
value as the runtime version or do we want to keep the higher precision
and adjust the unit test to use different values?


Here's a test case:
---------
import std.math, std.stdio;

void main()
{
    real a = 1.3e5L;
    real res1 = std.math.cos(1.3e5L);
    real res2 = std.math.cos(a);

    foreach(entry; *cast(byte[10]*)&res1)
        writef("%s ", entry);
    writeln();

    foreach(entry; *cast(byte[10]*)&res2)
        writef("%s ", entry);
    writeln();
}
---------
Output gdc:
-26 -73 -128 92 -10 33 -17 -97 -2 63 
123 -82 -128 92 -10 33 -17 -97 -2 63 

Output dmd:
123 -82 -128 92 -10 33 -17 -97 -2 63 
123 -82 -128 92 -10 33 -17 -97 -2 63 

However, gcc with the test case ported to C outputs the same result as
gdc:
---------
#include <stdio.h>
#include <math.h>

void main()
{

    long double a = 1.3e5L;
    long double res1 = cosl(1.3e5L);
    long double res2 = cosl(a);

    for(size_t i = 0; i < 8; i++)
        printf("%d ", ((char*)&res1)[i]);
    printf("\n");

    for(size_t i = 0; i < 8; i++)
        printf("%d ", ((char*)&res2)[i]);
    printf("\n");
}
Jul 09 2013
parent Iain Buclaw <ibuclaw ubuntu.com> writes:
On 9 July 2013 17:08, Johannes Pfau <nospam example.com> wrote:
 One of the tests in std.complex is failing because cos(LITERAL) and
 cos(VARIABLE) return different results. AFAICS this happens only if the
 parameter doesn't fit in 80bits and needs to be rounded. If
 LITERAL/VARIABLE are values which fit exactly in 80bits we get the same
 result. It's exactly the same situation in GCC.
 I guess we just get higher precision when evaluating those functions
 using constant folding as the LITERAL value is probably not rounded
 before evaluating the cos.

 So should we try to make the constant folding produce exactly the same
 value as the runtime version or do we want to keep the higher precision
 and adjust the unit test to use different values?
If gcc is the same, I'd just accept that's just how the backend works. Also, with dmd, does it not use inline assembler for these routines - so the calculated value is always the same? -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0';
Jul 10 2013