> 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;
}

Reply via email to