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 */ 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 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 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