Source-Changes-HG archive

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

[src/netbsd-8]: src/tests/lib/libc/locale Pull up following revision(s) (requ...



details:   https://anonhg.NetBSD.org/src/rev/74aec8d81423
branches:  netbsd-8
changeset: 851479:74aec8d81423
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Thu Mar 15 11:24:46 2018 +0000

description:
Pull up following revision(s) (requested by martin in ticket #631):
        tests/lib/libc/locale/t_sprintf.c: revision 1.4
        tests/lib/libc/locale/t_sprintf.c: revision 1.5
        tests/lib/libc/locale/t_sprintf.c: revision 1.6
        tests/lib/libc/locale/t_sprintf.c: revision 1.7
Add some diagnostics to the strto test, so I can see why this
fails on i386 (on qemu) - will probably keep them when done.
When comparing doubles (any floating point values) which have been
computed using different methods, don't expect to achieve identical
results (here, one constant is perhaps converted to binary from a string by
a cross compiler, the other is converted at run time).   Allow them to
have a small difference (for now, small is < 1e-7 - the constant is ~ 1e5,
so this is 12 orders of magnitude less) before failing (and include the
actual difference in the error message if it does fail.)
Revert 1.4 (perhaps temporarily) and add even more diagnostics to those
added in 1.3 to see if it is possible to determine why the strict equality
test fails on i386, yet succeeds elsewhere.
Since the C standard allows for intermediate floating results to contain
more precision bits than the data type expects, but (kind of obviously)
does not allow such values to be stored in memory, expecting the value
returned from strtod() (an intermediate result) to be identical (that is,
equal) to a stored value is incorrect.
So instead go back to checking that the two numbers are very very close.
See comments added to the test for more explanation.

diffstat:

 tests/lib/libc/locale/t_sprintf.c |  46 ++++++++++++++++++++++++++++++++++++--
 1 files changed, 43 insertions(+), 3 deletions(-)

diffs (74 lines):

diff -r 267234ee53c3 -r 74aec8d81423 tests/lib/libc/locale/t_sprintf.c
--- a/tests/lib/libc/locale/t_sprintf.c Thu Mar 15 09:56:35 2018 +0000
+++ b/tests/lib/libc/locale/t_sprintf.c Thu Mar 15 11:24:46 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: t_sprintf.c,v 1.1.2.2 2018/03/15 09:55:23 martin Exp $ */
+/* $NetBSD: t_sprintf.c,v 1.1.2.3 2018/03/15 11:24:46 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -32,9 +32,10 @@
 #include <sys/cdefs.h>
 __COPYRIGHT("@(#) Copyright (c) 2017\
  The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: t_sprintf.c,v 1.1.2.2 2018/03/15 09:55:23 martin Exp $");
+__RCSID("$NetBSD: t_sprintf.c,v 1.1.2.3 2018/03/15 11:24:46 bouyer Exp $");
 
 #include <locale.h>
+#include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -125,12 +126,51 @@
 static void
 h_strto(const struct test *t)
 {
+       double d, diff;
+
        ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C");
        printf("Trying locale %s...\n", t->locale);
        ATF_REQUIRE(setlocale(LC_NUMERIC, t->locale) != NULL);
 
        ATF_REQUIRE_EQ((int)strtol(t->int_input, NULL, 10), t->int_value);
-       ATF_REQUIRE_EQ(strtod(t->double_input, NULL), t->double_value);
+
+       /*
+        * Note that the C standard permits function values to be
+        * returned with more precision than is expected by (floating)
+        * data types, and on i386 (and potentially other implementations)
+        * that is exactly what happens, meaning that the result from
+        * strtod() is not identical to the expected value - it turns out
+        * that it is the same if the value is constrained to the number
+        * of mantissa bits in a double (so the %a values printed below
+        * show the exact same bit patterns) and on i386 -ffloat-store
+        * will cause gcc to constrain the result that way, but nothing
+        * demands that be true, so instead, we simply test that the
+        * value returned is very very close to that expected.
+        *
+        * 1e-12 is chosen as the allowable delta, as we know (from
+        * the data in the "struct test" earlier in this file) that
+        * its magnitude is ~ 10^5, with values of that magnitude,
+        * 10^-12 difference is a 10^-17 relative difference, and
+        * with a 56 bit mantissa (standard IEEE "double") a difference
+        * that small vanishes (requires at least 57 mantissa bits to
+        * be representable).   If the data values were to change, then
+        * so might this delta (if they were not all the same, we would
+        * move the delta into the struct rather than having it a constant
+        * here.).
+        *
+        * Finally, note that our purpose here is not to test floating
+        * point arithmetic, we're testing locale dependent string to
+        * binary conversions.
+        */
+
+       d = (double)strtod(t->double_input, NULL);
+       diff = fabs(d - t->double_value);
+       if (diff >= 1e-12)
+               ATF_REQUIRE_EQ_MSG(d, t->double_value, "In %s: " 
+                   "d=strtod(t->double_input[%s], NULL)[%.12g = %a] != "
+                   "t->double_value[%.12g = %a]: diff=%g", t->locale,
+                   t->double_input, d, d, t->double_value, t->double_value,
+                   diff);
 }
 
 static void



Home | Main Index | Thread Index | Old Index