> Date: Wed, 29 Nov 2017 11:41:58 +0700 > From: Robert Elz <k...@munnari.oz.au> > > OK, got my i386 test setup (a Xen DomU) built & running, the updated > test failed (as it always failed on i386 before I added the epsilon > test, which is #if 0'd out now) the results are ... > > strto: [0.002429s] Failed: > /release/testing/src/tests/lib/libc/locale/t_sprintf.c:145: d != > t->double_value: In en_US.UTF-8: d=strtod(t->double_input[-12345.678900], > NULL)[-12345.6789 = -0x1.81cd6e631f8a1p+13] != t->double_value[-12345.6789 = > -0x1.81cd6e631f8a1p+13]: diff=7.9492e-13
That's pretty interesting! Can you reproduce it in a small isolated program like the attached one? This program works just fine with and without -m32 on my amd64 system, but I don't have a proper i386 system handy to test. If you can, can you perhaps single-step through it in gdb to see what's actually in the various registers and floating-point stack? (My guess is that there's something screwy with i387 long doubles, but I don't have a good guess about where that screwiness might be happening without single-stepping through it.)
#include <assert.h> #include <err.h> #include <errno.h> #include <locale.h> #include <math.h> #include <stdio.h> #include <stdlib.h> static volatile struct test { const char *locale; const double double_value; const char *double_input; } tests[] = { { "en_US.UTF-8", -12345.6789, "-12345.678900", }, }; static void __attribute__((noinline)) h_strto(const volatile struct test *t) { double d, diff; if (setlocale(LC_NUMERIC, t->locale) == NULL) errx(1, "setlocale failed"); d = strtod(t->double_input, NULL); diff = fabs(d - t->double_value); if (!(d == t->double_value)) { fprintf(stderr, "str %s\n", t->double_input); fprintf(stderr, "exp %a %.17e\n", t->double_value, t->double_value); fprintf(stderr, "act %a %.17e\n", d, d); } } int main(int argc, char **argv) { volatile size_t i; (void)argc; (void)argv; for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) h_strto(&tests[i]); return 0; }