f4ad2701527e677063e9d4922ebdade595800522
[platform/upstream/glibc.git] / stdlib / gen-tst-strtod-round.c
1 /* Generate table of tests in tst-strtod-round.c from
2    tst-strtod-round-data.
3    Copyright (C) 2012 Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, see
18    <http://www.gnu.org/licenses/>.  */
19
20 #define _GNU_SOURCE
21 #include <stdbool.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <mpfr.h>
25
26 /* Work around incorrect ternary value from mpfr_strtofr
27    <https://sympa.inria.fr/sympa/arc/mpfr/2012-08/msg00005.html>.  */
28 #define WORKAROUND
29
30 static int
31 string_to_fp (mpfr_t f, const char *s, mpfr_rnd_t rnd)
32 {
33 #ifdef WORKAROUND
34   mpfr_t f2;
35   mpfr_init2 (f2, 100000);
36   int r0 = mpfr_strtofr (f2, s, NULL, 0, rnd);
37   int r = mpfr_set (f, f2, rnd);
38   mpfr_subnormalize (f, r, rnd);
39   mpfr_clear (f2);
40   return r0 | r;
41 #else
42   int r = mpfr_strtofr (f, s, NULL, 0, rnd);
43   mpfr_subnormalize (f, r, rnd);
44   return r;
45 #endif
46 }
47
48 static void
49 print_fp (mpfr_t f, const char *suffix, const char *suffix2)
50 {
51   if (mpfr_inf_p (f))
52     mpfr_printf ("\t%sINFINITY%s", mpfr_signbit (f) ? "-" : "", suffix2);
53   else
54     mpfr_printf ("\t%Ra%s%s", f, suffix, suffix2);
55 }
56
57 static void
58 round_str (const char *s, const char *suffix,
59            int prec, int emin, int emax, bool need_exact)
60 {
61   mpfr_t f;
62   mpfr_set_default_prec (prec);
63   mpfr_set_emin (emin);
64   mpfr_set_emax (emax);
65   mpfr_init (f);
66   int r = string_to_fp (f, s, MPFR_RNDD);
67   if (need_exact)
68     mpfr_printf ("\t%s,\n", r ? "false" : "true");
69   print_fp (f, suffix, ",\n");
70   string_to_fp (f, s, MPFR_RNDN);
71   print_fp (f, suffix, ",\n");
72   string_to_fp (f, s, MPFR_RNDZ);
73   print_fp (f, suffix, ",\n");
74   string_to_fp (f, s, MPFR_RNDU);
75   print_fp (f, suffix, "");
76   mpfr_clear (f);
77 }
78
79 static void
80 round_for_all (const char *s)
81 {
82   static const struct fmt {
83     const char *suffix;
84     int prec;
85     int emin;
86     int emax;
87     bool need_exact;
88   } formats[7] = {
89     { "f", 24, -148, 128, false },
90     { "", 53, -1073, 1024, false },
91     { "L", 53, -1073, 1024, false },
92     /* This is the Intel extended float format.  */
93     { "L", 64, -16444, 16384, false },
94     /* This is the Motorola extended float format.  */
95     { "L", 64, -16445, 16384, false },
96     { "L", 106, -1073, 1024, true },
97     { "L", 113, -16493, 16384, false },
98   };
99   mpfr_printf ("  TEST (\"");
100   const char *p;
101   for (p = s; *p; p++)
102     {
103       putchar (*p);
104       if ((p - s) % 60 == 59 && p[1])
105         mpfr_printf ("\"\n\t\"");
106     }
107   mpfr_printf ("\",\n");
108   int i;
109   for (i = 0; i < 7; i++)
110     {
111       round_str (s, formats[i].suffix, formats[i].prec,
112                  formats[i].emin, formats[i].emax, formats[i].need_exact);
113       if (i < 6)
114         mpfr_printf (",\n");
115     }
116   mpfr_printf ("),\n");
117 }
118
119 int
120 main (void)
121 {
122   char *p = NULL;
123   size_t len;
124   ssize_t nbytes;
125   while ((nbytes = getline (&p, &len, stdin)) != -1)
126     {
127       if (p[nbytes - 1] == '\n')
128         p[nbytes - 1] = 0;
129       round_for_all (p);
130       free (p);
131       p = NULL;
132     }
133   return 0;
134 }