1 /* Generate table of tests in tst-strtod-round.c from
3 Copyright (C) 2012-2023 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
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.
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.
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 <https://www.gnu.org/licenses/>. */
20 /* Compile this program as:
22 gcc -std=gnu11 -O2 -Wall -Wextra gen-tst-strtod-round.c -lmpfr \
23 -o gen-tst-strtod-round
25 (use of current MPFR version recommended) and run it as:
27 gen-tst-strtod-round tst-strtod-round-data tst-strtod-round-data.h
29 The output file will be generated as tst-strtod-round-data.h
41 /* Work around incorrect ternary value from mpfr_strtofr
42 <https://sympa.inria.fr/sympa/arc/mpfr/2012-08/msg00005.html>. */
46 string_to_fp (mpfr_t f
, const char *s
, mpfr_rnd_t rnd
)
48 mpfr_clear_overflow ();
51 mpfr_init2 (f2
, 100000);
52 int r0
= mpfr_strtofr (f2
, s
, NULL
, 0, rnd
);
53 int r
= mpfr_set (f
, f2
, rnd
);
54 r
|= mpfr_subnormalize (f
, r
, rnd
);
58 int r
= mpfr_strtofr (f
, s
, NULL
, 0, rnd
);
59 r
|= mpfr_subnormalize (f
, r
, rnd
);
65 print_fp (FILE *fout
, mpfr_t f
, const char *suffix
)
68 mpfr_fprintf (fout
, "\t%sINF%s", mpfr_signbit (f
) ? "-" : "", suffix
);
70 mpfr_fprintf (fout
, "\t%Ra%s", f
, suffix
);
74 round_str (FILE *fout
, const char *s
, int prec
, int emin
, int emax
,
79 mpfr_set_default_prec (prec
);
83 int r
= string_to_fp (f
, s
, MPFR_RNDD
);
84 bool overflow
= mpfr_overflow_p () != 0;
87 assert (prec
== 106 && emin
== -1073 && emax
== 1024);
88 /* The maximum value in IBM long double has discontiguous
90 mpfr_init2 (max_value
, 107);
91 mpfr_set_str (max_value
, "0x1.fffffffffffff7ffffffffffffcp+1023", 0,
93 if (mpfr_cmpabs (f
, max_value
) > 0)
99 mpfr_fprintf (fout
, "\t%s,\n", r
? "false" : "true");
100 print_fp (fout
, f
, overflow
? ", true,\n" : ", false,\n");
101 string_to_fp (f
, s
, MPFR_RNDN
);
102 overflow
= (mpfr_overflow_p () != 0
103 || (ibm_ld
&& mpfr_cmpabs (f
, max_value
) > 0));
104 print_fp (fout
, f
, overflow
? ", true,\n" : ", false,\n");
105 string_to_fp (f
, s
, MPFR_RNDZ
);
106 overflow
= (mpfr_overflow_p () != 0
107 || (ibm_ld
&& mpfr_cmpabs (f
, max_value
) > 0));
108 print_fp (fout
, f
, overflow
? ", true,\n" : ", false,\n");
109 string_to_fp (f
, s
, MPFR_RNDU
);
110 overflow
= (mpfr_overflow_p () != 0
111 || (ibm_ld
&& mpfr_cmpabs (f
, max_value
) > 0));
112 print_fp (fout
, f
, overflow
? ", true" : ", false");
115 mpfr_clear (max_value
);
119 round_for_all (FILE *fout
, const char *s
)
121 static const struct fmt
{
127 { 24, -148, 128, false },
128 { 53, -1073, 1024, false },
129 /* This is the Intel extended float format. */
130 { 64, -16444, 16384, false },
131 /* This is the Motorola extended float format. */
132 { 64, -16445, 16384, false },
133 { 106, -1073, 1024, true },
134 { 113, -16493, 16384, false },
136 mpfr_fprintf (fout
, " TEST (\"");
141 if ((p
- s
) % 60 == 59 && p
[1])
142 mpfr_fprintf (fout
, "\"\n\t\"");
144 mpfr_fprintf (fout
, "\",\n");
146 int n_formats
= sizeof (formats
) / sizeof (formats
[0]);
147 for (i
= 0; i
< n_formats
; i
++)
149 round_str (fout
, s
, formats
[i
].prec
, formats
[i
].emin
,
150 formats
[i
].emax
, formats
[i
].ibm_ld
);
151 if (i
< n_formats
- 1)
152 mpfr_fprintf (fout
, ",\n");
154 mpfr_fprintf (fout
, "),\n");
158 main (int argc
, char **argv
)
164 char *fin_name
, *fout_name
;
168 fprintf (stderr
, "Usage: %s <input> <output>\n", basename (argv
[0]));
175 fin
= fopen (fin_name
, "r");
178 perror ("Could not open input for reading");
182 fout
= fopen (fout_name
, "w");
185 perror ("Could not open output for writing");
189 fprintf (fout
, "/* This file was generated by %s from %s. */\n",
191 fputs ("static const struct test tests[] = {\n", fout
);
192 while ((nbytes
= getline (&p
, &len
, fin
)) != -1)
194 if (p
[nbytes
- 1] == '\n')
196 round_for_all (fout
, p
);
200 fputs ("};\n", fout
);