1 /*
2 * Output various information about GMP and MPFR.
3 */
4
5 /*
6 Copyright 2010-2023 Free Software Foundation, Inc.
7 Contributed by the AriC and Caramba projects, INRIA.
8
9 This file is part of the GNU MPFR Library.
10
11 The GNU MPFR Library is free software; you can redistribute it and/or modify
12 it under the terms of the GNU Lesser General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or (at your
14 option) any later version.
15
16 The GNU MPFR Library is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
19 License for more details.
20
21 You should have received a copy of the GNU Lesser General Public License
22 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
23 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
24 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
25 */
26
27 #include <stdio.h>
28 #include <limits.h>
29 #include <gmp.h>
30 #include <mpfr.h>
31
32 /* The following failure can occur if GMP has been rebuilt with
33 * a different ABI, e.g.
34 * 1. GMP built with ABI=mode32.
35 * 2. MPFR built against this GMP version.
36 * 3. GMP rebuilt with ABI=32.
37 */
failure_test(void)38 static void failure_test (void)
39 {
40 mpfr_t x;
41
42 mpfr_init2 (x, 128);
43 mpfr_set_str (x, "17", 0, MPFR_RNDN);
44 if (mpfr_cmp_ui (x, 17) != 0)
45 printf ("\nFailure in mpfr_set_str! Probably an unmatched ABI!\n");
46 mpfr_clear (x);
47 }
48
patches(void)49 static void patches (void)
50 {
51 const char *p = mpfr_get_patches ();
52 printf ("MPFR patches: %s\n", p[0] ? p : "[none]");
53 }
54
55 #define STRINGIZE(S) #S
56 #define MAKE_STR(S) STRINGIZE(S)
57
58 #define SIGNED_STR(V) ((V) < 0 ? "signed" : "unsigned")
59 #define SIGNED(I) SIGNED_STR((I) - (I) - 1)
60
main(void)61 int main (void)
62 {
63 unsigned long c;
64 mp_limb_t t[4];
65 int i;
66
67 /* Casts are for C++ compilers. */
68 for (i = 0; i < (int) (sizeof (t) / sizeof (mp_limb_t)); i++)
69 t[i] = (mp_limb_t) -1;
70
71 /**************** Information about the C implementation ****************/
72
73 /* This is useful, as this can affect the behavior of MPFR. */
74
75 #define COMP "Compiler: "
76 #ifdef __INTEL_COMPILER
77 # ifdef __VERSION__
78 # define ICCV " [" __VERSION__ "]"
79 # else
80 # define ICCV ""
81 # endif
82 printf (COMP "ICC %d.%d.%d" ICCV "\n", __INTEL_COMPILER / 100,
83 __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE);
84 #elif defined(__TINYC__)
85 /* The format of __TINYC__ is not described, but libtcc.c defines it with
86 * sprintf(buffer, "%d", a*10000 + b*100 + c);
87 * tcc_define_symbol(s, "__TINYC__", buffer);
88 */
89 printf (COMP "TCC %d.%d.%d\n", (int) (__TINYC__ / 10000),
90 (int) ((__TINYC__ / 100) % 100), (int) (__TINYC__ % 100));
91 #elif (defined(__GNUC__) || defined(__clang__)) && defined(__VERSION__)
92 # ifdef __clang__
93 # define COMP2 COMP
94 # else
95 # define COMP2 COMP "GCC "
96 # endif
97 printf (COMP2 "%s\n", __VERSION__);
98 #endif
99
100 #if defined(__STDC__) || defined(__STDC_VERSION__)
101 printf ("C/C++: __STDC__ = "
102 #if defined(__STDC__)
103 MAKE_STR(__STDC__)
104 #else
105 "undef"
106 #endif
107 ", __STDC_VERSION__ = "
108 #if defined(__STDC_VERSION__)
109 MAKE_STR(__STDC_VERSION__)
110 #else
111 "undef"
112 #endif
113 #if defined(__cplusplus)
114 ", C++"
115 #endif
116 "\n");
117 #endif
118
119 #if defined(__GNUC__)
120 printf ("GNU compatibility: __GNUC__ = " MAKE_STR(__GNUC__)
121 ", __GNUC_MINOR__ = "
122 #if defined(__GNUC_MINOR__)
123 MAKE_STR(__GNUC_MINOR__)
124 #else
125 "undef"
126 #endif
127 "\n");
128 #endif
129
130 #if defined(__ICC) || defined(__INTEL_COMPILER)
131 printf ("Intel compiler: __ICC = "
132 #if defined(__ICC)
133 MAKE_STR(__ICC)
134 #else
135 "undef"
136 #endif
137 ", __INTEL_COMPILER = "
138 #if defined(__INTEL_COMPILER)
139 MAKE_STR(__INTEL_COMPILER)
140 #else
141 "undef"
142 #endif
143 "\n");
144 #endif
145
146 #if defined(_WIN32) || defined(_MSC_VER)
147 printf ("MS Windows: _WIN32 = "
148 #if defined(_WIN32)
149 MAKE_STR(_WIN32)
150 #else
151 "undef"
152 #endif
153 ", _MSC_VER = "
154 #if defined(_MSC_VER)
155 MAKE_STR(_MSC_VER)
156 #else
157 "undef"
158 #endif
159 "\n");
160 #endif
161
162 #if defined(__GLIBC__)
163 printf ("GNU C library: __GLIBC__ = " MAKE_STR(__GLIBC__)
164 ", __GLIBC_MINOR__ = "
165 #if defined(__GLIBC_MINOR__)
166 MAKE_STR(__GLIBC_MINOR__)
167 #else
168 "undef"
169 #endif
170 "\n");
171 #endif
172
173 printf ("\n");
174
175 /************************************************************************/
176
177 #if defined(__MPIR_VERSION)
178 printf ("MPIR .... Library: %-12s Header: %d.%d.%d\n",
179 mpir_version, __MPIR_VERSION, __MPIR_VERSION_MINOR,
180 __MPIR_VERSION_PATCHLEVEL);
181 #else
182 printf ("GMP ..... Library: %-12s Header: %d.%d.%d\n",
183 gmp_version, __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR,
184 __GNU_MP_VERSION_PATCHLEVEL);
185 #endif
186
187 printf ("MPFR .... Library: %-12s Header: %s (based on %d.%d.%d)\n",
188 mpfr_get_version (), MPFR_VERSION_STRING, MPFR_VERSION_MAJOR,
189 MPFR_VERSION_MINOR, MPFR_VERSION_PATCHLEVEL);
190
191 printf ("MPFR features: TLS = %s", mpfr_buildopt_tls_p () ? "yes" : "no");
192 #if MPFR_VERSION_MAJOR >= 4
193 printf (", float128 = %s", mpfr_buildopt_float128_p () ? "yes" : "no");
194 #endif
195 printf (", decimal = %s", mpfr_buildopt_decimal_p () ? "yes" : "no");
196 #if MPFR_VERSION_MAJOR > 3 || MPFR_VERSION_MINOR >= 1
197 printf (", GMP internals = %s\nMPFR tuning: %s",
198 mpfr_buildopt_gmpinternals_p () ? "yes" : "no",
199 mpfr_buildopt_tune_case ());
200 #endif /* 3.1 */
201 printf ("\n");
202
203 patches ();
204
205 printf ("\n");
206 #ifdef __GMP_CC
207 printf ("__GMP_CC = \"%s\"\n", __GMP_CC);
208 #endif
209 #ifdef __GMP_CFLAGS
210 printf ("__GMP_CFLAGS = \"%s\"\n", __GMP_CFLAGS);
211 #endif
212 printf ("GMP_LIMB_BITS = %d\n", (int) GMP_LIMB_BITS);
213 printf ("GMP_NAIL_BITS = %d\n", (int) GMP_NAIL_BITS);
214 printf ("GMP_NUMB_BITS = %d\n", (int) GMP_NUMB_BITS);
215 printf ("mp_bits_per_limb = %d\n", (int) mp_bits_per_limb);
216 printf ("sizeof(mp_limb_t) = %d\n", (int) sizeof(mp_limb_t));
217 if (mp_bits_per_limb != GMP_LIMB_BITS)
218 printf ("Warning! mp_bits_per_limb != GMP_LIMB_BITS\n");
219 if (GMP_LIMB_BITS != sizeof(mp_limb_t) * CHAR_BIT)
220 printf ("Warning! GMP_LIMB_BITS != sizeof(mp_limb_t) * CHAR_BIT\n");
221
222 c = mpn_popcount (t, 1);
223 printf ("The GMP library expects %lu bits in a mp_limb_t.\n", c);
224 if (c != GMP_LIMB_BITS)
225 printf ("Warning! This is different from GMP_LIMB_BITS!\n"
226 "Different ABI caused by a GMP library upgrade?\n");
227
228 printf ("\n");
229 printf ("sizeof(mpfr_prec_t) = %d (%s type)\n", (int) sizeof(mpfr_prec_t),
230 SIGNED_STR((mpfr_prec_t) -1));
231 printf ("sizeof(mpfr_exp_t) = %d (%s type)\n", (int) sizeof(mpfr_exp_t),
232 SIGNED_STR((mpfr_exp_t) -1));
233 #ifdef _MPFR_PREC_FORMAT
234 printf ("_MPFR_PREC_FORMAT = %d\n", (int) _MPFR_PREC_FORMAT);
235 #endif
236 /* Note: "long" is sufficient for all current _MPFR_PREC_FORMAT values
237 (1, 2, 3). Thus we do not need to depend on ISO C99 or later. */
238 printf ("MPFR_PREC_MIN = %ld (%s)\n", (long) MPFR_PREC_MIN,
239 SIGNED (MPFR_PREC_MIN));
240 printf ("MPFR_PREC_MAX = %ld (%s)\n", (long) MPFR_PREC_MAX,
241 SIGNED (MPFR_PREC_MAX));
242 #ifdef _MPFR_EXP_FORMAT
243 printf ("_MPFR_EXP_FORMAT = %d\n", (int) _MPFR_EXP_FORMAT);
244 #endif
245 printf ("sizeof(mpfr_t) = %d\n", (int) sizeof(mpfr_t));
246 printf ("sizeof(mpfr_ptr) = %d\n", (int) sizeof(mpfr_ptr));
247 failure_test ();
248
249 mpfr_free_cache ();
250 return 0;
251 }
252