(root)/
mpfr-4.2.1/
tests/
tget_flt.c
       1  /* Test file for mpfr_get_flt and mpfr_set_flt
       2  
       3  Copyright 2009-2023 Free Software Foundation, Inc.
       4  Contributed by the AriC and Caramba projects, INRIA.
       5  
       6  This file is part of the GNU MPFR Library.
       7  
       8  The GNU MPFR Library is free software; you can redistribute it and/or modify
       9  it under the terms of the GNU Lesser General Public License as published by
      10  the Free Software Foundation; either version 3 of the License, or (at your
      11  option) any later version.
      12  
      13  The GNU MPFR Library is distributed in the hope that it will be useful, but
      14  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      15  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
      16  License for more details.
      17  
      18  You should have received a copy of the GNU Lesser General Public License
      19  along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
      20  https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
      21  51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
      22  
      23  #include <float.h>     /* for FLT_MIN */
      24  
      25  #include "mpfr-test.h"
      26  #include "ieee_floats.h"
      27  
      28  /* return non-zero iff f == g, and if both are zero check the sign */
      29  static int
      30  equal_flt (float f, float g)
      31  {
      32    if (f != 0.0)
      33      return f == g;
      34    else if (g != 0)
      35      return 0;
      36    else /* f = g = 0: check they have the same sign */
      37      {
      38        int sf, sg;
      39        mpfr_t z;
      40  
      41        mpfr_init2 (z, MPFR_PREC_MIN);
      42        mpfr_set_flt (z, f, MPFR_RNDN);
      43        sf = mpfr_signbit (z);
      44        mpfr_set_flt (z, g, MPFR_RNDN);
      45        sg = mpfr_signbit (z);
      46        mpfr_clear (z);
      47        return !sf == !sg;
      48      }
      49  }
      50  
      51  int
      52  main (void)
      53  {
      54    mpfr_t x, y;
      55    float f, g;
      56    int i;
      57  #if !defined(MPFR_ERRDIVZERO)
      58    float infp;
      59  #endif
      60  
      61    tests_start_mpfr ();
      62  
      63  #if !defined(MPFR_ERRDIVZERO)
      64    infp = (float) MPFR_DBL_INFP;
      65    if (infp * 0.5 != infp)
      66      {
      67        fprintf (stderr, "Error, FLT_MAX + FLT_MAX does not yield INFP\n");
      68        fprintf (stderr, "(this is probably a compiler bug, please report)\n");
      69        exit (1);
      70      }
      71  #endif
      72  
      73    mpfr_init2 (x, 24);
      74    mpfr_init2 (y, 24);
      75  
      76  #if !defined(MPFR_ERRDIVZERO)
      77    mpfr_set_nan (x);
      78    f = mpfr_get_flt (x, MPFR_RNDN);
      79    if (! DOUBLE_ISNAN (f))
      80      {
      81        printf ("Error for mpfr_get_flt(NaN)\n");
      82        printf ("got f=%f\n", f);
      83        exit (1);
      84      }
      85    mpfr_set_flt (x, f, MPFR_RNDN);
      86    if (! mpfr_nan_p (x))
      87      {
      88        printf ("Error for mpfr_set_flt(NaN)\n");
      89        exit (1);
      90      }
      91  
      92    mpfr_set_inf (x, 1);
      93    f = mpfr_get_flt (x, MPFR_RNDN);
      94    mpfr_set_flt (x, f, MPFR_RNDN);
      95    if (! mpfr_inf_p (x) || mpfr_sgn (x) < 0)
      96      {
      97        printf ("Error for mpfr_set_flt(mpfr_get_flt(+Inf)):\n");
      98        printf ("f=%f, expected -Inf\n", f);
      99        printf ("got "); mpfr_dump (x);
     100        exit (1);
     101      }
     102  
     103    mpfr_set_inf (x, -1);
     104    f = mpfr_get_flt (x, MPFR_RNDN);
     105    mpfr_set_flt (x, f, MPFR_RNDN);
     106    if (! mpfr_inf_p (x) || mpfr_sgn (x) > 0)
     107      {
     108        printf ("Error for mpfr_set_flt(mpfr_get_flt(-Inf)):\n");
     109        printf ("f=%f, expected -Inf\n", f);
     110        printf ("got "); mpfr_dump (x);
     111        exit (1);
     112      }
     113  #endif
     114  
     115    mpfr_set_ui (x, 0, MPFR_RNDN);
     116    f = mpfr_get_flt (x, MPFR_RNDN);
     117    mpfr_set_flt (x, f, MPFR_RNDN);
     118    if (! mpfr_zero_p (x) || MPFR_IS_NEG (x))
     119      {
     120        printf ("Error for mpfr_set_flt(mpfr_get_flt(+0))\n");
     121        exit (1);
     122      }
     123  
     124  #ifdef HAVE_SIGNEDZ
     125    mpfr_set_ui (x, 0, MPFR_RNDN);
     126    mpfr_neg (x, x, MPFR_RNDN);
     127    f = mpfr_get_flt (x, MPFR_RNDN);
     128    mpfr_set_flt (x, f, MPFR_RNDN);
     129    if (! mpfr_zero_p (x) || MPFR_IS_POS (x))
     130      {
     131        printf ("Error for mpfr_set_flt(mpfr_get_flt(-0))\n");
     132        exit (1);
     133      }
     134  #endif  /* HAVE_SIGNEDZ */
     135  
     136    mpfr_set_ui (x, 17, MPFR_RNDN);
     137    f = mpfr_get_flt (x, MPFR_RNDN);
     138    mpfr_set_flt (x, f, MPFR_RNDN);
     139    if (mpfr_cmp_ui (x, 17) != 0)
     140      {
     141        printf ("Error for mpfr_set_flt(mpfr_get_flt(17))\n");
     142        printf ("expected 17\n");
     143        printf ("got      ");
     144        mpfr_dump (x);
     145        exit (1);
     146      }
     147  
     148    mpfr_set_si (x, -42, MPFR_RNDN);
     149    f = mpfr_get_flt (x, MPFR_RNDN);
     150    mpfr_set_flt (x, f, MPFR_RNDN);
     151    if (mpfr_cmp_si (x, -42) != 0)
     152      {
     153        printf ("Error for mpfr_set_flt(mpfr_get_flt(-42))\n");
     154        printf ("expected -42\n");
     155        printf ("got      ");
     156        mpfr_dump (x);
     157        exit (1);
     158      }
     159  
     160    mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN);
     161    for (i = -126; i < 128; i++)
     162      {
     163        f = mpfr_get_flt (x, MPFR_RNDN);
     164        mpfr_set_flt (y, f, MPFR_RNDN);
     165        if (mpfr_cmp (x, y) != 0)
     166          {
     167            printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n");
     168            printf ("expected "); mpfr_dump (x);
     169            printf ("got      "); mpfr_dump (y);
     170            exit (1);
     171          }
     172        mpfr_mul_2ui (x, x, 1, MPFR_RNDN);
     173      }
     174  
     175    mpfr_set_prec (x, 53);
     176    mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN);
     177    for (i = -126; i < 128; i++)
     178      {
     179        mpfr_nextbelow (x);
     180        f = mpfr_get_flt (x, MPFR_RNDN);
     181        mpfr_nextabove (x);
     182        mpfr_set_flt (y, f, MPFR_RNDN);
     183        if (mpfr_cmp (x, y) != 0)
     184          {
     185            printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n");
     186            printf ("expected "); mpfr_dump (x);
     187            printf ("got      "); mpfr_dump (y);
     188            exit (1);
     189          }
     190        mpfr_mul_2ui (x, x, 1, MPFR_RNDN);
     191      }
     192  
     193    mpfr_set_prec (x, 53);
     194    mpfr_set_si_2exp (x, 1, -126, MPFR_RNDN);
     195    for (i = -126; i < 128; i++)
     196      {
     197        mpfr_nextabove (x);
     198        f = mpfr_get_flt (x, MPFR_RNDN);
     199        mpfr_nextbelow (x);
     200        mpfr_set_flt (y, f, MPFR_RNDN);
     201        if (mpfr_cmp (x, y) != 0)
     202          {
     203            printf ("Error for mpfr_set_flt(mpfr_get_flt(x))\n");
     204            printf ("expected "); mpfr_dump (x);
     205            printf ("got      "); mpfr_dump (y);
     206            exit (1);
     207          }
     208        mpfr_mul_2ui (x, x, 1, MPFR_RNDN);
     209      }
     210  
     211    if (have_subnorm_flt ())
     212      for (i = 0; i < 2; i++)
     213        {
     214          /* We assume here that the format of float is binary32, a.k.a.
     215             IEEE single precision (Annex F of ISO C for IEEE 754 support),
     216             as this is the case on all machines nowadays. Then 2^(-150) is
     217             halfway between 0 and the smallest positive float 2^(-149). */
     218          mpfr_set_si_2exp (x, 1, -150, MPFR_RNDN);
     219          g = 0.0;
     220          if (i == 1)
     221            {
     222              mpfr_neg (x, x, MPFR_RNDN);
     223              g = -g;
     224            }
     225          f = mpfr_get_flt (x, MPFR_RNDN);
     226          if (!equal_flt (f, g))
     227            {
     228              printf ("Error for mpfr_get_flt(2^(-150),RNDN)\n");
     229              printf ("expected %.8e, got %.8e\n", g, f);
     230              exit (1);
     231            }
     232          f = mpfr_get_flt (x, MPFR_RNDZ);
     233          if (!equal_flt (f, g))
     234            {
     235              printf ("Error for mpfr_get_flt(2^(-150),RNDZ)\n");
     236              printf ("expected %.8e, got %.8e\n", g, f);
     237              exit (1);
     238            }
     239          f = mpfr_get_flt (x, (i == 0) ? MPFR_RNDD : MPFR_RNDU);
     240          if (!equal_flt (f, g))
     241            {
     242              printf ("Error for mpfr_get_flt(2^(-150),%s)\n",
     243                      i == 0 ? "RNDD" : "RNDU");
     244              printf ("expected %.8e, got %.8e\n", g, f);
     245              exit (1);
     246            }
     247          g = FLT_MIN * FLT_EPSILON;
     248          if (i == 1)
     249            g = -g;
     250          f = mpfr_get_flt (x, (i == 0) ? MPFR_RNDU : MPFR_RNDD);
     251          if (!equal_flt (f, g))
     252            {
     253              printf ("Error for mpfr_get_flt(2^(-150),%s)\n",
     254                      i == 0 ? "RNDU" : "RNDD");
     255              printf ("expected %.8e, got %.8e\n", g, f);
     256              exit (1);
     257            }
     258          f = mpfr_get_flt (x, MPFR_RNDA);
     259          if (!equal_flt (f, g))
     260            {
     261              printf ("Error for mpfr_get_flt(2^(-150),RNDA)\n");
     262              printf ("expected %.8e, got %.8e\n", g, f);
     263              exit (1);
     264            }
     265  
     266          mpfr_set_si_2exp (x, 1, -151, MPFR_RNDN);
     267          g = 0.0;
     268          if (i == 1)
     269            {
     270              mpfr_neg (x, x, MPFR_RNDN);
     271              g = -g;
     272            }
     273          f = mpfr_get_flt (x, MPFR_RNDN);
     274          if (!equal_flt (f, g))
     275            {
     276              printf ("Error for mpfr_get_flt(2^(-151),RNDN)\n");
     277              printf ("expected %.8e, got %.8e\n", g, f);
     278              exit (1);
     279            }
     280          f = mpfr_get_flt (x, MPFR_RNDZ);
     281          if (!equal_flt (f, g))
     282            {
     283              printf ("Error for mpfr_get_flt(2^(-151),RNDZ)\n");
     284              printf ("expected %.8e, got %.8e\n", g, f);
     285              exit (1);
     286            }
     287          f = mpfr_get_flt (x, (i == 0) ? MPFR_RNDD : MPFR_RNDU);
     288          if (!equal_flt (f, g))
     289            {
     290              printf ("Error for mpfr_get_flt(2^(-151),%s)\n",
     291                      i == 0 ? "RNDD" : "RNDU");
     292              printf ("expected %.8e, got %.8e\n", g, f);
     293              exit (1);
     294            }
     295          g = FLT_MIN * FLT_EPSILON;
     296          if (i == 1)
     297            g = -g;
     298          f = mpfr_get_flt (x, (i == 0) ? MPFR_RNDU : MPFR_RNDD);
     299          if (!equal_flt (f, g))
     300            {
     301              printf ("Error for mpfr_get_flt(2^(-151),%s)\n",
     302                      i == 0 ? "RNDU" : "RNDD");
     303              printf ("expected %.8e, got %.8e\n", g, f);
     304              exit (1);
     305            }
     306          f = mpfr_get_flt (x, MPFR_RNDA);
     307          if (!equal_flt (f, g))
     308            {
     309              printf ("Error for mpfr_get_flt(2^(-151),RNDA)\n");
     310              printf ("expected %.8e, got %.8e\n", g, f);
     311              exit (1);
     312            }
     313  
     314          mpfr_set_si_2exp (x, 1, -149, MPFR_RNDN);
     315          g = FLT_MIN * FLT_EPSILON;
     316          if (i == 1)
     317            {
     318              mpfr_neg (x, x, MPFR_RNDN);
     319              g = -g;
     320            }
     321          f = mpfr_get_flt (x, MPFR_RNDN);
     322          if (!equal_flt (f, g))
     323            {
     324              printf ("Error for mpfr_get_flt(2^(-149),RNDN)\n");
     325              printf ("expected %.8e, got %.8e\n", g, f);
     326              exit (1);
     327            }
     328          f = mpfr_get_flt (x, MPFR_RNDZ);
     329          if (!equal_flt (f, g))
     330            {
     331              printf ("Error for mpfr_get_flt(2^(-149),RNDZ)\n");
     332              printf ("expected %.8e, got %.8e\n", g, f);
     333              exit (1);
     334            }
     335          f = mpfr_get_flt (x, MPFR_RNDD);
     336          if (!equal_flt (f, g))
     337            {
     338              printf ("Error for mpfr_get_flt(2^(-149),RNDD)\n");
     339              printf ("expected %.8e, got %.8e\n", g, f);
     340              exit (1);
     341            }
     342          f = mpfr_get_flt (x, MPFR_RNDU);
     343          if (!equal_flt (f, g))
     344            {
     345              printf ("Error for mpfr_get_flt(2^(-149),RNDU)\n");
     346              printf ("expected %.8e, got %.8e\n", g, f);
     347              exit (1);
     348            }
     349          f = mpfr_get_flt (x, MPFR_RNDA);
     350          if (!equal_flt (f, g))
     351            {
     352              printf ("Error for mpfr_get_flt(2^(-149),RNDA)\n");
     353              printf ("expected %.8e, got %.8e\n", g, f);
     354              exit (1);
     355            }
     356        }  /* for loop with tests on subnormals */
     357  
     358    mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN);
     359    g = FLT_MAX;
     360    f = mpfr_get_flt (x, MPFR_RNDZ);
     361    if (f != g)
     362      {
     363        printf ("Error for mpfr_get_flt(2^128,RNDZ)\n");
     364        printf ("expected %.8e, got %.8e\n", g, f);
     365        exit (1);
     366      }
     367    f = mpfr_get_flt (x, MPFR_RNDD);
     368    if (f != g)
     369      {
     370        printf ("Error for mpfr_get_flt(2^128,RNDD)\n");
     371        printf ("expected %.8e, got %.8e\n", g, f);
     372        exit (1);
     373      }
     374  
     375    /* same for negative x */
     376    mpfr_set_si_2exp (x, -1, 128, MPFR_RNDN);
     377    g = -FLT_MAX;
     378    f = mpfr_get_flt (x, MPFR_RNDZ);
     379    if (f != g)
     380      {
     381        printf ("Error for mpfr_get_flt(-2^128,RNDZ)\n");
     382        printf ("expected %.8e, got %.8e\n", g, f);
     383        exit (1);
     384      }
     385    f = mpfr_get_flt (x, MPFR_RNDU);
     386    if (f != g)
     387      {
     388        printf ("Error for mpfr_get_flt(-2^128,RNDD)\n");
     389        printf ("expected %.8e, got %.8e\n", g, f);
     390        exit (1);
     391      }
     392  
     393  #if !defined(MPFR_ERRDIVZERO)
     394    mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN);
     395    f = mpfr_get_flt (x, MPFR_RNDN); /* 2^128 rounds to itself with extended
     396                                        exponent range, we should get +Inf */
     397    g = infp;
     398    if (f != g)
     399      {
     400        printf ("Error for mpfr_get_flt(2^128,RNDN)\n");
     401        printf ("expected %.8e, got %.8e\n", g, f);
     402        exit (1);
     403      }
     404    f = mpfr_get_flt (x, MPFR_RNDU);
     405    if (f != g)
     406      {
     407        printf ("Error for mpfr_get_flt(2^128,RNDU)\n");
     408        printf ("expected %.8e, got %.8e\n", g, f);
     409        exit (1);
     410      }
     411    f = mpfr_get_flt (x, MPFR_RNDA);
     412    if (f != g)
     413      {
     414        printf ("Error for mpfr_get_flt(2^128,RNDA)\n");
     415        printf ("expected %.8e, got %.8e\n", g, f);
     416        exit (1);
     417      }
     418  
     419    /* same for negative x */
     420    mpfr_set_si_2exp (x, -1, 128, MPFR_RNDN);
     421    f = mpfr_get_flt (x, MPFR_RNDN); /* -2^128 rounds to itself with extended
     422                                        exponent range, we should get +Inf */
     423    g = -infp;
     424    if (f != g)
     425      {
     426        printf ("Error for mpfr_get_flt(-2^128,RNDN)\n");
     427        printf ("expected %.8e, got %.8e\n", g, f);
     428        exit (1);
     429      }
     430    f = mpfr_get_flt (x, MPFR_RNDD);
     431    if (f != g)
     432      {
     433        printf ("Error for mpfr_get_flt(-2^128,RNDD)\n");
     434        printf ("expected %.8e, got %.8e\n", g, f);
     435        exit (1);
     436      }
     437    f = mpfr_get_flt (x, MPFR_RNDA);
     438    if (f != g)
     439      {
     440        printf ("Error for mpfr_get_flt(-2^128,RNDA)\n");
     441        printf ("expected %.8e, got %.8e\n", g, f);
     442        exit (1);
     443      }
     444  #endif
     445  
     446    /* corner case: take x with 25 bits just below 2^128 */
     447    mpfr_set_prec (x, 25);
     448    mpfr_set_si_2exp (x, 1, 128, MPFR_RNDN);
     449    mpfr_nextbelow (x);
     450    g = FLT_MAX;
     451    f = mpfr_get_flt (x, MPFR_RNDZ);
     452    if (f != g)
     453      {
     454        printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDZ)\n");
     455        printf ("expected %.8e, got %.8e\n", g, f);
     456        exit (1);
     457      }
     458    f = mpfr_get_flt (x, MPFR_RNDD);
     459    if (f != g)
     460      {
     461        printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDD)\n");
     462        printf ("expected %.8e, got %.8e\n", g, f);
     463        exit (1);
     464      }
     465  #if !defined(MPFR_ERRDIVZERO)
     466    f = mpfr_get_flt (x, MPFR_RNDN); /* first round to 2^128 (even rule),
     467                                        thus we should get +Inf */
     468    g = infp;
     469    if (f != g)
     470      {
     471        printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDN)\n");
     472        printf ("expected %.8e, got %.8e\n", g, f);
     473        exit (1);
     474      }
     475    f = mpfr_get_flt (x, MPFR_RNDU);
     476    if (f != g)
     477      {
     478        printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDU)\n");
     479        printf ("expected %.8e, got %.8e\n", g, f);
     480        exit (1);
     481      }
     482    f = mpfr_get_flt (x, MPFR_RNDA);
     483    if (f != g)
     484      {
     485        printf ("Error for mpfr_get_flt(2^128*(1-2^(-25)),RNDA)\n");
     486        printf ("expected %.8e, got %.8e\n", g, f);
     487        exit (1);
     488      }
     489  #endif
     490  
     491    mpfr_clear (x);
     492    mpfr_clear (y);
     493  
     494    tests_end_mpfr ();
     495    return 0;
     496  }