D.gnu - unittests failures: constant folding of cos function gives
- Johannes Pfau (50/50) Jul 09 2013 One of the tests in std.complex is failing because cos(LITERAL) and
- Iain Buclaw (7/18) Jul 10 2013 If gcc is the same, I'd just accept that's just how the backend works.
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
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