Source-Changes-D archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: CVS commit: src/tests/lib/libc/locale



> Date: Wed, 29 Nov 2017 11:41:58 +0700
> From: Robert Elz <kre%munnari.OZ.AU@localhost>
> 
> 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;
}


Home | Main Index | Thread Index | Old Index