(root)/
coreutils-9.4/
gnulib-tests/
test-frexp.h
       1  /* Test of splitting a double into fraction and mantissa.
       2     Copyright (C) 2012-2023 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation, either version 3 of the License, or
       7     (at your option) any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  static DOUBLE
      18  my_ldexp (DOUBLE x, int d)
      19  {
      20    for (; d > 0; d--)
      21      x *= L_(2.0);
      22    for (; d < 0; d++)
      23      x *= L_(0.5);
      24    return x;
      25  }
      26  
      27  static void
      28  test_function (void)
      29  {
      30    int i;
      31    VOLATILE DOUBLE x;
      32  
      33    { /* NaN.  */
      34      int exp = -9999;
      35      DOUBLE mantissa;
      36      x = NAN;
      37      mantissa = FREXP (x, &exp);
      38      ASSERT (ISNAN (mantissa));
      39    }
      40  
      41    { /* Positive infinity.  */
      42      int exp = -9999;
      43      DOUBLE mantissa;
      44      x = INFINITY;
      45      mantissa = FREXP (x, &exp);
      46      ASSERT (mantissa == x);
      47    }
      48  
      49    { /* Negative infinity.  */
      50      int exp = -9999;
      51      DOUBLE mantissa;
      52      x = - INFINITY;
      53      mantissa = FREXP (x, &exp);
      54      ASSERT (mantissa == x);
      55    }
      56  
      57    { /* Positive zero.  */
      58      int exp = -9999;
      59      DOUBLE mantissa;
      60      x = L_(0.0);
      61      mantissa = FREXP (x, &exp);
      62      ASSERT (exp == 0);
      63      ASSERT (mantissa == x);
      64      ASSERT (!signbit (mantissa));
      65    }
      66  
      67    { /* Negative zero.  */
      68      int exp = -9999;
      69      DOUBLE mantissa;
      70      x = MINUS_ZERO;
      71      mantissa = FREXP (x, &exp);
      72      ASSERT (exp == 0);
      73      ASSERT (mantissa == x);
      74      ASSERT (signbit (mantissa));
      75    }
      76  
      77    for (i = 1, x = L_(1.0); i <= MAX_EXP; i++, x *= L_(2.0))
      78      {
      79        int exp = -9999;
      80        DOUBLE mantissa = FREXP (x, &exp);
      81        ASSERT (exp == i);
      82        ASSERT (mantissa == L_(0.5));
      83      }
      84    for (i = 1, x = L_(1.0); i >= MIN_NORMAL_EXP; i--, x *= L_(0.5))
      85      {
      86        int exp = -9999;
      87        DOUBLE mantissa = FREXP (x, &exp);
      88        ASSERT (exp == i);
      89        ASSERT (mantissa == L_(0.5));
      90      }
      91    for (; i >= MIN_EXP - 100 && x > L_(0.0); i--, x *= L_(0.5))
      92      {
      93        int exp = -9999;
      94        DOUBLE mantissa = FREXP (x, &exp);
      95        ASSERT (exp == i);
      96        ASSERT (mantissa == L_(0.5));
      97      }
      98  
      99    for (i = 1, x = - L_(1.0); i <= MAX_EXP; i++, x *= L_(2.0))
     100      {
     101        int exp = -9999;
     102        DOUBLE mantissa = FREXP (x, &exp);
     103        ASSERT (exp == i);
     104        ASSERT (mantissa == - L_(0.5));
     105      }
     106    for (i = 1, x = - L_(1.0); i >= MIN_NORMAL_EXP; i--, x *= L_(0.5))
     107      {
     108        int exp = -9999;
     109        DOUBLE mantissa = FREXP (x, &exp);
     110        ASSERT (exp == i);
     111        ASSERT (mantissa == - L_(0.5));
     112      }
     113    for (; i >= MIN_EXP - 100 && x < L_(0.0); i--, x *= L_(0.5))
     114      {
     115        int exp = -9999;
     116        DOUBLE mantissa = FREXP (x, &exp);
     117        ASSERT (exp == i);
     118        ASSERT (mantissa == - L_(0.5));
     119      }
     120  
     121    for (i = 1, x = L_(1.01); i <= MAX_EXP; i++, x *= L_(2.0))
     122      {
     123        int exp = -9999;
     124        DOUBLE mantissa = FREXP (x, &exp);
     125        ASSERT (exp == i);
     126        ASSERT (mantissa == L_(0.505));
     127      }
     128    for (i = 1, x = L_(1.01); i >= MIN_NORMAL_EXP; i--, x *= L_(0.5))
     129      {
     130        int exp = -9999;
     131        DOUBLE mantissa = FREXP (x, &exp);
     132        ASSERT (exp == i);
     133        ASSERT (mantissa == L_(0.505));
     134      }
     135    for (; i >= MIN_EXP - 100 && x > L_(0.0); i--, x *= L_(0.5))
     136      {
     137        int exp = -9999;
     138        DOUBLE mantissa = FREXP (x, &exp);
     139        ASSERT (exp == i);
     140        ASSERT (mantissa >= L_(0.5));
     141        ASSERT (mantissa < L_(1.0));
     142        ASSERT (mantissa == my_ldexp (x, - exp));
     143      }
     144  
     145    for (i = 1, x = L_(1.73205); i <= MAX_EXP; i++, x *= L_(2.0))
     146      {
     147        int exp = -9999;
     148        DOUBLE mantissa = FREXP (x, &exp);
     149        ASSERT (exp == i);
     150        ASSERT (mantissa == L_(0.866025));
     151      }
     152    for (i = 1, x = L_(1.73205); i >= MIN_NORMAL_EXP; i--, x *= L_(0.5))
     153      {
     154        int exp = -9999;
     155        DOUBLE mantissa = FREXP (x, &exp);
     156        ASSERT (exp == i);
     157        ASSERT (mantissa == L_(0.866025));
     158      }
     159    for (; i >= MIN_EXP - 100 && x > L_(0.0); i--, x *= L_(0.5))
     160      {
     161        int exp = -9999;
     162        DOUBLE mantissa = FREXP (x, &exp);
     163        ASSERT (exp == i || exp == i + 1);
     164        ASSERT (mantissa >= L_(0.5));
     165        ASSERT (mantissa < L_(1.0));
     166        ASSERT (mantissa == my_ldexp (x, - exp));
     167      }
     168  
     169    /* Randomized tests.  */
     170    for (i = 0; i < SIZEOF (RANDOM); i++)
     171      {
     172        x = L_(20.0) * RANDOM[i] - L_(10.0); /* -10.0 <= x <= 10.0 */
     173        {
     174          int exp = -9999;
     175          DOUBLE mantissa = FREXP (x, &exp);
     176          ASSERT (x == my_ldexp (mantissa, exp));
     177        }
     178      }
     179  }