Blame tests/mpf/t-trunc.c

Packit 5c3484
/* Test mpf_trunc, mpf_ceil, mpf_floor.
Packit 5c3484
Packit 5c3484
Copyright 2001, 2002 Free Software Foundation, Inc.
Packit 5c3484
Packit 5c3484
This file is part of the GNU MP Library test suite.
Packit 5c3484
Packit 5c3484
The GNU MP Library test suite is free software; you can redistribute it
Packit 5c3484
and/or modify it under the terms of the GNU General Public License as
Packit 5c3484
published by the Free Software Foundation; either version 3 of the License,
Packit 5c3484
or (at your option) any later version.
Packit 5c3484
Packit 5c3484
The GNU MP Library test suite is distributed in the hope that it will be
Packit 5c3484
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 5c3484
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
Packit 5c3484
Public License for more details.
Packit 5c3484
Packit 5c3484
You should have received a copy of the GNU General Public License along with
Packit 5c3484
the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
Packit 5c3484
Packit 5c3484
#include <stdio.h>
Packit 5c3484
#include <stdlib.h>
Packit 5c3484
#include "gmp.h"
Packit 5c3484
#include "gmp-impl.h"
Packit 5c3484
#include "tests.h"
Packit 5c3484
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
check_print (mpf_srcptr src, mpf_srcptr got, mpf_srcptr want)
Packit 5c3484
{
Packit 5c3484
  mp_trace_base = 16;
Packit 5c3484
  mpf_trace ("src ", src);
Packit 5c3484
  mpf_trace ("got ", got);
Packit 5c3484
  mpf_trace ("want", want);
Packit 5c3484
Packit 5c3484
  printf ("got  size=%d exp=%ld\n", SIZ(got), EXP(got));
Packit 5c3484
  mpn_trace ("     limbs=", PTR(got), (mp_size_t) ABSIZ(got));
Packit 5c3484
Packit 5c3484
  printf ("want size=%d exp=%ld\n", SIZ(want), EXP(want));
Packit 5c3484
  mpn_trace ("     limbs=", PTR(want), (mp_size_t) ABSIZ(want));
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
check_one (mpf_srcptr src, mpf_srcptr trunc, mpf_srcptr ceil, mpf_srcptr floor)
Packit 5c3484
{
Packit 5c3484
  mpf_t  got;
Packit 5c3484
Packit 5c3484
  mpf_init2 (got, mpf_get_prec (trunc));
Packit 5c3484
  ASSERT_ALWAYS (PREC(got) == PREC(trunc));
Packit 5c3484
  ASSERT_ALWAYS (PREC(got) == PREC(ceil));
Packit 5c3484
  ASSERT_ALWAYS (PREC(got) == PREC(floor));
Packit 5c3484
Packit 5c3484
#define CHECK_SEP(name, fun, want)              \
Packit 5c3484
  mpf_set_ui (got, 54321L); /* initial junk */  \
Packit 5c3484
  fun (got, src);                               \
Packit 5c3484
  MPF_CHECK_FORMAT (got);                       \
Packit 5c3484
  if (mpf_cmp (got, want) != 0)                 \
Packit 5c3484
    {                                           \
Packit 5c3484
	printf ("%s wrong\n", name);            \
Packit 5c3484
	check_print (src, got, want);           \
Packit 5c3484
	abort ();                               \
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  CHECK_SEP ("mpf_trunc", mpf_trunc, trunc);
Packit 5c3484
  CHECK_SEP ("mpf_ceil",  mpf_ceil,  ceil);
Packit 5c3484
  CHECK_SEP ("mpf_floor", mpf_floor, floor);
Packit 5c3484
Packit 5c3484
#define CHECK_INPLACE(name, fun, want)  \
Packit 5c3484
  mpf_set (got, src);                   \
Packit 5c3484
  fun (got, got);                       \
Packit 5c3484
  MPF_CHECK_FORMAT (got);               \
Packit 5c3484
  if (mpf_cmp (got, want) != 0)         \
Packit 5c3484
    {                                   \
Packit 5c3484
	printf ("%s wrong\n", name);    \
Packit 5c3484
	check_print (src, got, want);   \
Packit 5c3484
	abort ();                       \
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  CHECK_INPLACE ("mpf_trunc", mpf_trunc, trunc);
Packit 5c3484
Packit 5c3484
  /* Can't do these unconditionally in case truncation by mpf_set strips
Packit 5c3484
     some low non-zero limbs which would have rounded the result.  */
Packit 5c3484
  if (ABSIZ(src) <= PREC(trunc)+1)
Packit 5c3484
    {
Packit 5c3484
      CHECK_INPLACE ("mpf_ceil",  mpf_ceil,  ceil);
Packit 5c3484
      CHECK_INPLACE ("mpf_floor", mpf_floor, floor);
Packit 5c3484
    }
Packit 5c3484
Packit 5c3484
  mpf_clear (got);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
check_all (mpf_ptr src, mpf_ptr trunc, mpf_ptr ceil, mpf_ptr floor)
Packit 5c3484
{
Packit 5c3484
  /* some of these values are generated with direct field assignments */
Packit 5c3484
  MPF_CHECK_FORMAT (src);
Packit 5c3484
  MPF_CHECK_FORMAT (trunc);
Packit 5c3484
  MPF_CHECK_FORMAT (ceil);
Packit 5c3484
  MPF_CHECK_FORMAT (floor);
Packit 5c3484
Packit 5c3484
  check_one (src, trunc, ceil, floor);
Packit 5c3484
Packit 5c3484
  mpf_neg (src,   src);
Packit 5c3484
  mpf_neg (trunc, trunc);
Packit 5c3484
  mpf_neg (ceil,  ceil);
Packit 5c3484
  mpf_neg (floor, floor);
Packit 5c3484
  check_one (src, trunc, floor, ceil);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
void
Packit 5c3484
check_various (void)
Packit 5c3484
{
Packit 5c3484
  mpf_t  src, trunc, ceil, floor;
Packit 5c3484
  int    n, i;
Packit 5c3484
Packit 5c3484
  mpf_init2 (src, 512L);
Packit 5c3484
  mpf_init2 (trunc, 256L);
Packit 5c3484
  mpf_init2 (ceil,  256L);
Packit 5c3484
  mpf_init2 (floor, 256L);
Packit 5c3484
Packit 5c3484
  /* 0 */
Packit 5c3484
  mpf_set_ui (src, 0L);
Packit 5c3484
  mpf_set_ui (trunc, 0L);
Packit 5c3484
  mpf_set_ui (ceil, 0L);
Packit 5c3484
  mpf_set_ui (floor, 0L);
Packit 5c3484
  check_all (src, trunc, ceil, floor);
Packit 5c3484
Packit 5c3484
  /* 1 */
Packit 5c3484
  mpf_set_ui (src, 1L);
Packit 5c3484
  mpf_set_ui (trunc, 1L);
Packit 5c3484
  mpf_set_ui (ceil, 1L);
Packit 5c3484
  mpf_set_ui (floor, 1L);
Packit 5c3484
  check_all (src, trunc, ceil, floor);
Packit 5c3484
Packit 5c3484
  /* 2^1024 */
Packit 5c3484
  mpf_set_ui (src, 1L);
Packit 5c3484
  mpf_mul_2exp (src,   src,   1024L);
Packit 5c3484
  mpf_set (trunc, src);
Packit 5c3484
  mpf_set (ceil,  src);
Packit 5c3484
  mpf_set (floor, src);
Packit 5c3484
  check_all (src, trunc, ceil, floor);
Packit 5c3484
Packit 5c3484
  /* 1/2^1024, fraction only */
Packit 5c3484
  mpf_set_ui (src, 1L);
Packit 5c3484
  mpf_div_2exp (src,  src, 1024L);
Packit 5c3484
  mpf_set_si (trunc, 0L);
Packit 5c3484
  mpf_set_si (ceil, 1L);
Packit 5c3484
  mpf_set_si (floor, 0L);
Packit 5c3484
  check_all (src, trunc, ceil, floor);
Packit 5c3484
Packit 5c3484
  /* 1/2 */
Packit 5c3484
  mpf_set_ui (src, 1L);
Packit 5c3484
  mpf_div_2exp (src,  src, 1L);
Packit 5c3484
  mpf_set_si (trunc, 0L);
Packit 5c3484
  mpf_set_si (ceil, 1L);
Packit 5c3484
  mpf_set_si (floor, 0L);
Packit 5c3484
  check_all (src, trunc, ceil, floor);
Packit 5c3484
Packit 5c3484
  /* 123+1/2^64 */
Packit 5c3484
  mpf_set_ui (src, 1L);
Packit 5c3484
  mpf_div_2exp (src,  src, 64L);
Packit 5c3484
  mpf_add_ui (src,  src, 123L);
Packit 5c3484
  mpf_set_si (trunc, 123L);
Packit 5c3484
  mpf_set_si (ceil, 124L);
Packit 5c3484
  mpf_set_si (floor, 123L);
Packit 5c3484
  check_all (src, trunc, ceil, floor);
Packit 5c3484
Packit 5c3484
  /* integer of full prec+1 limbs, unchanged */
Packit 5c3484
  n = PREC(trunc)+1;
Packit 5c3484
  ASSERT_ALWAYS (n <= PREC(src)+1);
Packit 5c3484
  EXP(src) = n;
Packit 5c3484
  SIZ(src) = n;
Packit 5c3484
  for (i = 0; i < SIZ(src); i++)
Packit 5c3484
    PTR(src)[i] = i+100;
Packit 5c3484
  mpf_set (trunc, src);
Packit 5c3484
  mpf_set (ceil, src);
Packit 5c3484
  mpf_set (floor, src);
Packit 5c3484
  check_all (src, trunc, ceil, floor);
Packit 5c3484
Packit 5c3484
  /* full prec+1 limbs, 1 trimmed for integer */
Packit 5c3484
  n = PREC(trunc)+1;
Packit 5c3484
  ASSERT_ALWAYS (n <= PREC(src)+1);
Packit 5c3484
  EXP(src) = n-1;
Packit 5c3484
  SIZ(src) = n;
Packit 5c3484
  for (i = 0; i < SIZ(src); i++)
Packit 5c3484
    PTR(src)[i] = i+200;
Packit 5c3484
  EXP(trunc) = n-1;
Packit 5c3484
  SIZ(trunc) = n-1;
Packit 5c3484
  for (i = 0; i < SIZ(trunc); i++)
Packit 5c3484
    PTR(trunc)[i] = i+201;
Packit 5c3484
  mpf_set (floor, trunc);
Packit 5c3484
  mpf_add_ui (ceil, trunc, 1L);
Packit 5c3484
  check_all (src, trunc, ceil, floor);
Packit 5c3484
Packit 5c3484
  /* prec+3 limbs, 2 trimmed for size */
Packit 5c3484
  n = PREC(trunc)+3;
Packit 5c3484
  ASSERT_ALWAYS (n <= PREC(src)+1);
Packit 5c3484
  EXP(src) = n;
Packit 5c3484
  SIZ(src) = n;
Packit 5c3484
  for (i = 0; i < SIZ(src); i++)
Packit 5c3484
    PTR(src)[i] = i+300;
Packit 5c3484
  EXP(trunc) = n;
Packit 5c3484
  SIZ(trunc) = n-2;
Packit 5c3484
  for (i = 0; i < SIZ(trunc); i++)
Packit 5c3484
    PTR(trunc)[i] = i+302;
Packit 5c3484
  mpf_set (floor, trunc);
Packit 5c3484
  mpf_set (ceil, trunc);
Packit 5c3484
  PTR(ceil)[0]++;
Packit 5c3484
  check_all (src, trunc, ceil, floor);
Packit 5c3484
Packit 5c3484
  /* prec+4 limbs, 2 trimmed for size, 1 trimmed for integer */
Packit 5c3484
  n = PREC(trunc)+4;
Packit 5c3484
  ASSERT_ALWAYS (n <= PREC(src)+1);
Packit 5c3484
  EXP(src) = n-1;
Packit 5c3484
  SIZ(src) = n;
Packit 5c3484
  for (i = 0; i < SIZ(src); i++)
Packit 5c3484
    PTR(src)[i] = i+400;
Packit 5c3484
  EXP(trunc) = n-1;
Packit 5c3484
  SIZ(trunc) = n-3;
Packit 5c3484
  for (i = 0; i < SIZ(trunc); i++)
Packit 5c3484
    PTR(trunc)[i] = i+403;
Packit 5c3484
  mpf_set (floor, trunc);
Packit 5c3484
  mpf_set (ceil, trunc);
Packit 5c3484
  PTR(ceil)[0]++;
Packit 5c3484
  check_all (src, trunc, ceil, floor);
Packit 5c3484
Packit 5c3484
  /* F.F, carry out of ceil */
Packit 5c3484
  EXP(src) = 1;
Packit 5c3484
  SIZ(src) = 2;
Packit 5c3484
  PTR(src)[0] = GMP_NUMB_MAX;
Packit 5c3484
  PTR(src)[1] = GMP_NUMB_MAX;
Packit 5c3484
  EXP(trunc) = 1;
Packit 5c3484
  SIZ(trunc) = 1;
Packit 5c3484
  PTR(trunc)[0] = GMP_NUMB_MAX;
Packit 5c3484
  mpf_set (floor, trunc);
Packit 5c3484
  EXP(ceil) = 2;
Packit 5c3484
  SIZ(ceil) = 1;
Packit 5c3484
  PTR(ceil)[0] = 1;
Packit 5c3484
  check_all (src, trunc, ceil, floor);
Packit 5c3484
Packit 5c3484
  /* FF.F, carry out of ceil */
Packit 5c3484
  EXP(src) = 2;
Packit 5c3484
  SIZ(src) = 3;
Packit 5c3484
  PTR(src)[0] = GMP_NUMB_MAX;
Packit 5c3484
  PTR(src)[1] = GMP_NUMB_MAX;
Packit 5c3484
  PTR(src)[2] = GMP_NUMB_MAX;
Packit 5c3484
  EXP(trunc) = 2;
Packit 5c3484
  SIZ(trunc) = 2;
Packit 5c3484
  PTR(trunc)[0] = GMP_NUMB_MAX;
Packit 5c3484
  PTR(trunc)[1] = GMP_NUMB_MAX;
Packit 5c3484
  mpf_set (floor, trunc);
Packit 5c3484
  EXP(ceil) = 3;
Packit 5c3484
  SIZ(ceil) = 1;
Packit 5c3484
  PTR(ceil)[0] = 1;
Packit 5c3484
  check_all (src, trunc, ceil, floor);
Packit 5c3484
Packit 5c3484
  mpf_clear (src);
Packit 5c3484
  mpf_clear (trunc);
Packit 5c3484
  mpf_clear (ceil);
Packit 5c3484
  mpf_clear (floor);
Packit 5c3484
}
Packit 5c3484
Packit 5c3484
int
Packit 5c3484
main (void)
Packit 5c3484
{
Packit 5c3484
  tests_start ();
Packit 5c3484
Packit 5c3484
  check_various ();
Packit 5c3484
Packit 5c3484
  tests_end ();
Packit 5c3484
  exit (0);
Packit 5c3484
}