t-divrem_1.c
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:4k
源码类别:

数学计算

开发平台:

Unix_Linux

  1. /* Test mpn_divrem_1 and mpn_preinv_divrem_1.
  2. Copyright 2003 Free Software Foundation, Inc.
  3. This file is part of the GNU MP Library.
  4. The GNU MP Library is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or (at your
  7. option) any later version.
  8. The GNU MP Library is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  11. License for more details.
  12. You should have received a copy of the GNU Lesser General Public License
  13. along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include "gmp.h"
  17. #include "gmp-impl.h"
  18. #include "tests.h"
  19. void
  20. check_data (void)
  21. {
  22.   static const struct {
  23.     mp_limb_t  n[1];
  24.     mp_size_t  nsize;
  25.     mp_limb_t  d;
  26.     mp_size_t  qxn;
  27.     mp_limb_t  want_q[5];
  28.     mp_limb_t  want_r;
  29.   } data[] = {
  30.     { { 0 }, 1, 1, 0,
  31.       { 0 }, 0},
  32.     { { 5 }, 1, 2, 0,
  33.       { 2 }, 1},
  34. #if GMP_NUMB_BITS == 32
  35.     { { 0x3C }, 1, 0xF2, 1,
  36.       { 0x3F789854, 0 }, 0x98 },
  37. #endif
  38. #if GMP_NUMB_BITS == 64
  39.     { { 0x3C }, 1, 0xF2, 1,
  40.       { CNST_LIMB(0x3F789854A0CB1B81), 0 }, 0x0E },
  41.     /* This case exposed some wrong code generated by SGI cc on mips64 irix
  42.        6.5 with -n32 -O2, in the fractional loop for normalized divisor
  43.        using udiv_qrnnd_preinv.  A test "x>al" in one of the sub_ddmmss
  44.        expansions came out wrong, leading to an incorrect quotient.  */
  45.     { { CNST_LIMB(0x3C00000000000000) }, 1, CNST_LIMB(0xF200000000000000), 1,
  46.       { CNST_LIMB(0x3F789854A0CB1B81), 0 }, CNST_LIMB(0x0E00000000000000) },
  47. #endif
  48.   };
  49.   mp_limb_t  dinv, got_r, got_q[numberof(data[0].want_q)];
  50.   mp_size_t  qsize;
  51.   int        i, shift;
  52.   for (i = 0; i < numberof (data); i++)
  53.     {
  54.       qsize = data[i].nsize + data[i].qxn;
  55.       ASSERT_ALWAYS (qsize <= numberof (got_q));
  56.       got_r = mpn_divrem_1 (got_q, data[i].qxn, data[i].n, data[i].nsize,
  57.                             data[i].d);
  58.       if (got_r != data[i].want_r
  59.           || refmpn_cmp (got_q, data[i].want_q, qsize) != 0)
  60.         {
  61.           printf        ("mpn_divrem_1 wrong at data[%d]n", i);
  62.         bad:
  63.           mpn_trace     ("  n", data[i].n, data[i].nsize);
  64.           printf        ("  nsize=%ldn", (long) data[i].nsize);
  65.           mp_limb_trace ("  d", data[i].d);
  66.           printf        ("  qxn=%ldn", (long) data[i].qxn);
  67.           mpn_trace     ("  want q", data[i].want_q, qsize);
  68.           mpn_trace     ("  got  q", got_q, qsize);
  69.           mp_limb_trace ("  want r", data[i].want_r);
  70.           mp_limb_trace ("  got  r", got_r);
  71.           abort ();
  72.         }
  73.       /* test if available */
  74. #if USE_PREINV_DIVREM_1 || HAVE_NATIVE_mpn_preinv_divrem_1
  75.       shift = refmpn_count_leading_zeros (data[i].d);
  76.       dinv = refmpn_invert_limb (data[i].d << shift);
  77.       got_r = mpn_preinv_divrem_1 (got_q, data[i].qxn,
  78.                                    data[i].n, data[i].nsize,
  79.                                    data[i].d, dinv, shift);
  80.       if (got_r != data[i].want_r
  81.           || refmpn_cmp (got_q, data[i].want_q, qsize) != 0)
  82.         {
  83.           printf        ("mpn_preinv divrem_1 wrong at data[%d]n", i);
  84.           printf        ("  shift=%dn", shift);
  85.           mp_limb_trace ("  dinv", dinv);
  86.           goto bad;
  87.         }
  88. #endif
  89.     }
  90. }
  91. int
  92. main (void)
  93. {
  94.   tests_start ();
  95.   mp_trace_base = -16;
  96.   check_data ();
  97.   tests_end ();
  98.   exit (0);
  99. }