Home | History | Annotate | Line # | Download | only in examples
      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