Blame gnulib-tests/test-float.c

Packit Service fdd496
/* Test of <float.h> substitute.
Packit Service fdd496
   Copyright (C) 2011-2017 Free Software Foundation, Inc.
Packit Service fdd496
Packit Service fdd496
   This program is free software: you can redistribute it and/or modify
Packit Service fdd496
   it under the terms of the GNU General Public License as published by
Packit Service fdd496
   the Free Software Foundation; either version 3 of the License, or
Packit Service fdd496
   (at your option) any later version.
Packit Service fdd496
Packit Service fdd496
   This program is distributed in the hope that it will be useful,
Packit Service fdd496
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fdd496
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service fdd496
   GNU General Public License for more details.
Packit Service fdd496
Packit Service fdd496
   You should have received a copy of the GNU General Public License
Packit Service fdd496
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
Packit Service fdd496
Packit Service fdd496
/* Written by Bruno Haible <bruno@clisp.org>, 2011.  */
Packit Service fdd496
Packit Service fdd496
#include <config.h>
Packit Service fdd496
Packit Service fdd496
#include <float.h>
Packit Service fdd496
Packit Service fdd496
#include "fpucw.h"
Packit Service fdd496
#include "macros.h"
Packit Service fdd496
Packit Service fdd496
/* Check that FLT_RADIX is a constant expression.  */
Packit Service fdd496
int a[] = { FLT_RADIX };
Packit Service fdd496
Packit Service fdd496
#if FLT_RADIX == 2
Packit Service fdd496
Packit Service fdd496
/* Return 2^n.  */
Packit Service fdd496
static float
Packit Service fdd496
pow2f (int n)
Packit Service fdd496
{
Packit Service fdd496
  int k = n;
Packit Service fdd496
  volatile float x = 1;
Packit Service fdd496
  volatile float y = 2;
Packit Service fdd496
  /* Invariant: 2^n == x * y^k.  */
Packit Service fdd496
  if (k < 0)
Packit Service fdd496
    {
Packit Service fdd496
      y = 0.5f;
Packit Service fdd496
      k = - k;
Packit Service fdd496
    }
Packit Service fdd496
  while (k > 0)
Packit Service fdd496
    {
Packit Service fdd496
      if (k != 2 * (k / 2))
Packit Service fdd496
        {
Packit Service fdd496
          x = x * y;
Packit Service fdd496
          k = k - 1;
Packit Service fdd496
        }
Packit Service fdd496
      if (k == 0)
Packit Service fdd496
        break;
Packit Service fdd496
      y = y * y;
Packit Service fdd496
      k = k / 2;
Packit Service fdd496
    }
Packit Service fdd496
  /* Now k == 0, hence x == 2^n.  */
Packit Service fdd496
  return x;
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
/* Return 2^n.  */
Packit Service fdd496
static double
Packit Service fdd496
pow2d (int n)
Packit Service fdd496
{
Packit Service fdd496
  int k = n;
Packit Service fdd496
  volatile double x = 1;
Packit Service fdd496
  volatile double y = 2;
Packit Service fdd496
  /* Invariant: 2^n == x * y^k.  */
Packit Service fdd496
  if (k < 0)
Packit Service fdd496
    {
Packit Service fdd496
      y = 0.5;
Packit Service fdd496
      k = - k;
Packit Service fdd496
    }
Packit Service fdd496
  while (k > 0)
Packit Service fdd496
    {
Packit Service fdd496
      if (k != 2 * (k / 2))
Packit Service fdd496
        {
Packit Service fdd496
          x = x * y;
Packit Service fdd496
          k = k - 1;
Packit Service fdd496
        }
Packit Service fdd496
      if (k == 0)
Packit Service fdd496
        break;
Packit Service fdd496
      y = y * y;
Packit Service fdd496
      k = k / 2;
Packit Service fdd496
    }
Packit Service fdd496
  /* Now k == 0, hence x == 2^n.  */
Packit Service fdd496
  return x;
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
/* Return 2^n.  */
Packit Service fdd496
static long double
Packit Service fdd496
pow2l (int n)
Packit Service fdd496
{
Packit Service fdd496
  int k = n;
Packit Service fdd496
  volatile long double x = 1;
Packit Service fdd496
  volatile long double y = 2;
Packit Service fdd496
  /* Invariant: 2^n == x * y^k.  */
Packit Service fdd496
  if (k < 0)
Packit Service fdd496
    {
Packit Service fdd496
      y = 0.5L;
Packit Service fdd496
      k = - k;
Packit Service fdd496
    }
Packit Service fdd496
  while (k > 0)
Packit Service fdd496
    {
Packit Service fdd496
      if (k != 2 * (k / 2))
Packit Service fdd496
        {
Packit Service fdd496
          x = x * y;
Packit Service fdd496
          k = k - 1;
Packit Service fdd496
        }
Packit Service fdd496
      if (k == 0)
Packit Service fdd496
        break;
Packit Service fdd496
      y = y * y;
Packit Service fdd496
      k = k / 2;
Packit Service fdd496
    }
Packit Service fdd496
  /* Now k == 0, hence x == 2^n.  */
Packit Service fdd496
  return x;
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
/* ----------------------- Check macros for 'float' ----------------------- */
Packit Service fdd496
Packit Service fdd496
/* Check that the FLT_* macros expand to constant expressions.  */
Packit Service fdd496
int fb[] =
Packit Service fdd496
  {
Packit Service fdd496
    FLT_MANT_DIG, FLT_MIN_EXP, FLT_MAX_EXP,
Packit Service fdd496
    FLT_DIG, FLT_MIN_10_EXP, FLT_MAX_10_EXP
Packit Service fdd496
  };
Packit Service fdd496
float fc[] = { FLT_EPSILON, FLT_MIN, FLT_MAX };
Packit Service fdd496
Packit Service fdd496
static void
Packit Service fdd496
test_float (void)
Packit Service fdd496
{
Packit Service fdd496
  /* Check that the value of FLT_MIN_EXP is well parenthesized.  */
Packit Service fdd496
  ASSERT ((FLT_MIN_EXP % 101111) == (FLT_MIN_EXP) % 101111);
Packit Service fdd496
Packit Service fdd496
  /* Check that the value of DBL_MIN_10_EXP is well parenthesized.  */
Packit Service fdd496
  ASSERT ((FLT_MIN_10_EXP % 101111) == (FLT_MIN_10_EXP) % 101111);
Packit Service fdd496
Packit Service fdd496
  /* Check that 'float' is as specified in IEEE 754.  */
Packit Service fdd496
  ASSERT (FLT_MANT_DIG == 24);
Packit Service fdd496
  ASSERT (FLT_MIN_EXP == -125);
Packit Service fdd496
  ASSERT (FLT_MAX_EXP == 128);
Packit Service fdd496
Packit Service fdd496
  /* Check the value of FLT_MIN_10_EXP.  */
Packit Service fdd496
  ASSERT (FLT_MIN_10_EXP == - (int) (- (FLT_MIN_EXP - 1) * 0.30103));
Packit Service fdd496
Packit Service fdd496
  /* Check the value of FLT_DIG.  */
Packit Service fdd496
  ASSERT (FLT_DIG == (int) ((FLT_MANT_DIG - 1) * 0.30103));
Packit Service fdd496
Packit Service fdd496
  /* Check the value of FLT_MIN_10_EXP.  */
Packit Service fdd496
  ASSERT (FLT_MIN_10_EXP == - (int) (- (FLT_MIN_EXP - 1) * 0.30103));
Packit Service fdd496
Packit Service fdd496
  /* Check the value of FLT_MAX_10_EXP.  */
Packit Service fdd496
  ASSERT (FLT_MAX_10_EXP == (int) (FLT_MAX_EXP * 0.30103));
Packit Service fdd496
Packit Service fdd496
  /* Check the value of FLT_MAX.  */
Packit Service fdd496
  {
Packit Service fdd496
    volatile float m = FLT_MAX;
Packit Service fdd496
    int n;
Packit Service fdd496
Packit Service fdd496
    ASSERT (m + m > m);
Packit Service fdd496
    for (n = 0; n <= 2 * FLT_MANT_DIG; n++)
Packit Service fdd496
      {
Packit Service fdd496
        volatile float pow2_n = pow2f (n); /* 2^n */
Packit Service fdd496
        volatile float x = m + (m / pow2_n);
Packit Service fdd496
        if (x > m)
Packit Service fdd496
          ASSERT (x + x == x);
Packit Service fdd496
        else
Packit Service fdd496
          ASSERT (!(x + x == x));
Packit Service fdd496
      }
Packit Service fdd496
  }
Packit Service fdd496
Packit Service fdd496
  /* Check the value of FLT_MIN.  */
Packit Service fdd496
  {
Packit Service fdd496
    volatile float m = FLT_MIN;
Packit Service fdd496
    volatile float x = pow2f (FLT_MIN_EXP - 1);
Packit Service fdd496
    ASSERT (m == x);
Packit Service fdd496
  }
Packit Service fdd496
Packit Service fdd496
  /* Check the value of FLT_EPSILON.  */
Packit Service fdd496
  {
Packit Service fdd496
    volatile float e = FLT_EPSILON;
Packit Service fdd496
    volatile float me;
Packit Service fdd496
    int n;
Packit Service fdd496
Packit Service fdd496
    me = 1.0f + e;
Packit Service fdd496
    ASSERT (me > 1.0f);
Packit Service fdd496
    ASSERT (me - 1.0f == e);
Packit Service fdd496
    for (n = 0; n <= 2 * FLT_MANT_DIG; n++)
Packit Service fdd496
      {
Packit Service fdd496
        volatile float half_n = pow2f (- n); /* 2^-n */
Packit Service fdd496
        volatile float x = me - half_n;
Packit Service fdd496
        if (x < me)
Packit Service fdd496
          ASSERT (x <= 1.0f);
Packit Service fdd496
      }
Packit Service fdd496
  }
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
/* ----------------------- Check macros for 'double' ----------------------- */
Packit Service fdd496
Packit Service fdd496
/* Check that the DBL_* macros expand to constant expressions.  */
Packit Service fdd496
int db[] =
Packit Service fdd496
  {
Packit Service fdd496
    DBL_MANT_DIG, DBL_MIN_EXP, DBL_MAX_EXP,
Packit Service fdd496
    DBL_DIG, DBL_MIN_10_EXP, DBL_MAX_10_EXP
Packit Service fdd496
  };
Packit Service fdd496
double dc[] = { DBL_EPSILON, DBL_MIN, DBL_MAX };
Packit Service fdd496
Packit Service fdd496
static void
Packit Service fdd496
test_double (void)
Packit Service fdd496
{
Packit Service fdd496
  /* Check that the value of DBL_MIN_EXP is well parenthesized.  */
Packit Service fdd496
  ASSERT ((DBL_MIN_EXP % 101111) == (DBL_MIN_EXP) % 101111);
Packit Service fdd496
Packit Service fdd496
  /* Check that the value of DBL_MIN_10_EXP is well parenthesized.  */
Packit Service fdd496
  ASSERT ((DBL_MIN_10_EXP % 101111) == (DBL_MIN_10_EXP) % 101111);
Packit Service fdd496
Packit Service fdd496
  /* Check that 'double' is as specified in IEEE 754.  */
Packit Service fdd496
  ASSERT (DBL_MANT_DIG == 53);
Packit Service fdd496
  ASSERT (DBL_MIN_EXP == -1021);
Packit Service fdd496
  ASSERT (DBL_MAX_EXP == 1024);
Packit Service fdd496
Packit Service fdd496
  /* Check the value of DBL_MIN_10_EXP.  */
Packit Service fdd496
  ASSERT (DBL_MIN_10_EXP == - (int) (- (DBL_MIN_EXP - 1) * 0.30103));
Packit Service fdd496
Packit Service fdd496
  /* Check the value of DBL_DIG.  */
Packit Service fdd496
  ASSERT (DBL_DIG == (int) ((DBL_MANT_DIG - 1) * 0.30103));
Packit Service fdd496
Packit Service fdd496
  /* Check the value of DBL_MIN_10_EXP.  */
Packit Service fdd496
  ASSERT (DBL_MIN_10_EXP == - (int) (- (DBL_MIN_EXP - 1) * 0.30103));
Packit Service fdd496
Packit Service fdd496
  /* Check the value of DBL_MAX_10_EXP.  */
Packit Service fdd496
  ASSERT (DBL_MAX_10_EXP == (int) (DBL_MAX_EXP * 0.30103));
Packit Service fdd496
Packit Service fdd496
  /* Check the value of DBL_MAX.  */
Packit Service fdd496
  {
Packit Service fdd496
    volatile double m = DBL_MAX;
Packit Service fdd496
    int n;
Packit Service fdd496
Packit Service fdd496
    ASSERT (m + m > m);
Packit Service fdd496
    for (n = 0; n <= 2 * DBL_MANT_DIG; n++)
Packit Service fdd496
      {
Packit Service fdd496
        volatile double pow2_n = pow2d (n); /* 2^n */
Packit Service fdd496
        volatile double x = m + (m / pow2_n);
Packit Service fdd496
        if (x > m)
Packit Service fdd496
          ASSERT (x + x == x);
Packit Service fdd496
        else
Packit Service fdd496
          ASSERT (!(x + x == x));
Packit Service fdd496
      }
Packit Service fdd496
  }
Packit Service fdd496
Packit Service fdd496
  /* Check the value of DBL_MIN.  */
Packit Service fdd496
  {
Packit Service fdd496
    volatile double m = DBL_MIN;
Packit Service fdd496
    volatile double x = pow2d (DBL_MIN_EXP - 1);
Packit Service fdd496
    ASSERT (m == x);
Packit Service fdd496
  }
Packit Service fdd496
Packit Service fdd496
  /* Check the value of DBL_EPSILON.  */
Packit Service fdd496
  {
Packit Service fdd496
    volatile double e = DBL_EPSILON;
Packit Service fdd496
    volatile double me;
Packit Service fdd496
    int n;
Packit Service fdd496
Packit Service fdd496
    me = 1.0 + e;
Packit Service fdd496
    ASSERT (me > 1.0);
Packit Service fdd496
    ASSERT (me - 1.0 == e);
Packit Service fdd496
    for (n = 0; n <= 2 * DBL_MANT_DIG; n++)
Packit Service fdd496
      {
Packit Service fdd496
        volatile double half_n = pow2d (- n); /* 2^-n */
Packit Service fdd496
        volatile double x = me - half_n;
Packit Service fdd496
        if (x < me)
Packit Service fdd496
          ASSERT (x <= 1.0);
Packit Service fdd496
      }
Packit Service fdd496
  }
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
/* -------------------- Check macros for 'long double' -------------------- */
Packit Service fdd496
Packit Service fdd496
/* Check that the LDBL_* macros expand to constant expressions.  */
Packit Service fdd496
int lb[] =
Packit Service fdd496
  {
Packit Service fdd496
    LDBL_MANT_DIG, LDBL_MIN_EXP, LDBL_MAX_EXP,
Packit Service fdd496
    LDBL_DIG, LDBL_MIN_10_EXP, LDBL_MAX_10_EXP
Packit Service fdd496
  };
Packit Service fdd496
long double lc1 = LDBL_EPSILON;
Packit Service fdd496
long double lc2 = LDBL_MIN;
Packit Service fdd496
#if 0 /* LDBL_MAX is not a constant expression on some platforms.  */
Packit Service fdd496
long double lc3 = LDBL_MAX;
Packit Service fdd496
#endif
Packit Service fdd496
Packit Service fdd496
static void
Packit Service fdd496
test_long_double (void)
Packit Service fdd496
{
Packit Service fdd496
  /* Check that the value of LDBL_MIN_EXP is well parenthesized.  */
Packit Service fdd496
  ASSERT ((LDBL_MIN_EXP % 101111) == (LDBL_MIN_EXP) % 101111);
Packit Service fdd496
Packit Service fdd496
  /* Check that the value of LDBL_MIN_10_EXP is well parenthesized.  */
Packit Service fdd496
  ASSERT ((LDBL_MIN_10_EXP % 101111) == (LDBL_MIN_10_EXP) % 101111);
Packit Service fdd496
Packit Service fdd496
  /* Check that 'long double' is at least as wide as 'double'.  */
Packit Service fdd496
  ASSERT (LDBL_MANT_DIG >= DBL_MANT_DIG);
Packit Service fdd496
  ASSERT (LDBL_MIN_EXP - LDBL_MANT_DIG <= DBL_MIN_EXP - DBL_MANT_DIG);
Packit Service fdd496
  ASSERT (LDBL_MAX_EXP >= DBL_MAX_EXP);
Packit Service fdd496
Packit Service fdd496
  /* Check the value of LDBL_DIG.  */
Packit Service fdd496
  ASSERT (LDBL_DIG == (int)((LDBL_MANT_DIG - 1) * 0.30103));
Packit Service fdd496
Packit Service fdd496
  /* Check the value of LDBL_MIN_10_EXP.  */
Packit Service fdd496
  ASSERT (LDBL_MIN_10_EXP == - (int) (- (LDBL_MIN_EXP - 1) * 0.30103));
Packit Service fdd496
Packit Service fdd496
  /* Check the value of LDBL_MAX_10_EXP.  */
Packit Service fdd496
  ASSERT (LDBL_MAX_10_EXP == (int) (LDBL_MAX_EXP * 0.30103));
Packit Service fdd496
Packit Service fdd496
  /* Check the value of LDBL_MAX.  */
Packit Service fdd496
  {
Packit Service fdd496
    volatile long double m = LDBL_MAX;
Packit Service fdd496
    int n;
Packit Service fdd496
Packit Service fdd496
    ASSERT (m + m > m);
Packit Service fdd496
    for (n = 0; n <= 2 * LDBL_MANT_DIG; n++)
Packit Service fdd496
      {
Packit Service fdd496
        volatile long double pow2_n = pow2l (n); /* 2^n */
Packit Service fdd496
        volatile long double x = m + (m / pow2_n);
Packit Service fdd496
        if (x > m)
Packit Service fdd496
          ASSERT (x + x == x);
Packit Service fdd496
        else
Packit Service fdd496
          ASSERT (!(x + x == x));
Packit Service fdd496
      }
Packit Service fdd496
  }
Packit Service fdd496
Packit Service fdd496
  /* Check the value of LDBL_MIN.  */
Packit Service fdd496
  {
Packit Service fdd496
    volatile long double m = LDBL_MIN;
Packit Service fdd496
    volatile long double x = pow2l (LDBL_MIN_EXP - 1);
Packit Service fdd496
    ASSERT (m == x);
Packit Service fdd496
  }
Packit Service fdd496
Packit Service fdd496
  /* Check the value of LDBL_EPSILON.  */
Packit Service fdd496
  {
Packit Service fdd496
    volatile long double e = LDBL_EPSILON;
Packit Service fdd496
    volatile long double me;
Packit Service fdd496
    int n;
Packit Service fdd496
Packit Service fdd496
    me = 1.0L + e;
Packit Service fdd496
    ASSERT (me > 1.0L);
Packit Service fdd496
    ASSERT (me - 1.0L == e);
Packit Service fdd496
    for (n = 0; n <= 2 * LDBL_MANT_DIG; n++)
Packit Service fdd496
      {
Packit Service fdd496
        volatile long double half_n = pow2l (- n); /* 2^-n */
Packit Service fdd496
        volatile long double x = me - half_n;
Packit Service fdd496
        if (x < me)
Packit Service fdd496
          ASSERT (x <= 1.0L);
Packit Service fdd496
      }
Packit Service fdd496
  }
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
int
Packit Service fdd496
main ()
Packit Service fdd496
{
Packit Service fdd496
  test_float ();
Packit Service fdd496
  test_double ();
Packit Service fdd496
Packit Service fdd496
  {
Packit Service fdd496
    DECL_LONG_DOUBLE_ROUNDING
Packit Service fdd496
Packit Service fdd496
    BEGIN_LONG_DOUBLE_ROUNDING ();
Packit Service fdd496
Packit Service fdd496
    test_long_double ();
Packit Service fdd496
Packit Service fdd496
    END_LONG_DOUBLE_ROUNDING ();
Packit Service fdd496
  }
Packit Service fdd496
Packit Service fdd496
  return 0;
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
#else
Packit Service fdd496
Packit Service fdd496
int
Packit Service fdd496
main ()
Packit Service fdd496
{
Packit Service fdd496
  fprintf (stderr, "Skipping test: FLT_RADIX is not 2.\n");
Packit Service fdd496
  return 77;
Packit Service fdd496
}
Packit Service fdd496
Packit Service fdd496
#endif