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

数学计算

开发平台:

Unix_Linux

  1. /* Test mpz_get_d_2exp.
  2. Copyright 2002, 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. static void
  20. check_onebit (void)
  21. {
  22.   static const unsigned long data[] = {
  23.     1, 32, 52, 53, 54, 63, 64, 65, 128, 256, 511, 512, 513
  24.   };
  25.   mpz_t   z;
  26.   double  got, want;
  27.   long    got_exp, want_exp;
  28.   int     i;
  29.   mpz_init (z);
  30.   for (i = 0; i < numberof (data); i++)
  31.     {
  32.       mpz_set_ui (z, 1L);
  33.       mpz_mul_2exp (z, z, data[i]);
  34.       want = 0.5;
  35.       want_exp = data[i] + 1;
  36.       got = mpz_get_d_2exp (&got_exp, z);
  37.       if (got != want || got_exp != want_exp)
  38.         {
  39.           printf    ("mpz_get_d_2exp wrong on 2**%ldn", data[i]);
  40.           mpz_trace ("   z    ", z);
  41.           d_trace   ("   want ", want);
  42.           d_trace   ("   got  ", got);
  43.           printf    ("   want exp %ldn", want_exp);
  44.           printf    ("   got exp  %ldn", got_exp);
  45.           abort();
  46.         }
  47.       mpz_set_si (z, -1L);
  48.       mpz_mul_2exp (z, z, data[i]);
  49.       want = -0.5;
  50.       want_exp = data[i] + 1;
  51.       got = mpz_get_d_2exp (&got_exp, z);
  52.       if (got != want || got_exp != want_exp)
  53.         {
  54.           printf    ("mpz_get_d_2exp wrong on -2**%ldn", data[i]);
  55.           mpz_trace ("   z    ", z);
  56.           d_trace   ("   want ", want);
  57.           d_trace   ("   got  ", got);
  58.           printf    ("   want exp %ldn", want_exp);
  59.           printf    ("   got exp  %ldn", got_exp);
  60.           abort();
  61.         }
  62.     }
  63.   mpz_clear (z);
  64. }
  65. /* Check that hardware rounding doesn't make mpz_get_d_2exp return a value
  66.    outside its defined range. */
  67. static void
  68. check_round (void)
  69. {
  70.   static const unsigned long data[] = { 1, 32, 53, 54, 64, 128, 256, 512 };
  71.   mpz_t   z;
  72.   double  got;
  73.   long    got_exp;
  74.   int     i, rnd_mode, old_rnd_mode;
  75.   mpz_init (z);
  76.   old_rnd_mode = tests_hardware_getround ();
  77.   for (rnd_mode = 0; rnd_mode < 4; rnd_mode++)
  78.     {
  79.       tests_hardware_setround (rnd_mode);
  80.       for (i = 0; i < numberof (data); i++)
  81.         {
  82.           mpz_set_ui (z, 1L);
  83.           mpz_mul_2exp (z, z, data[i]);
  84.           mpz_sub_ui (z, z, 1L);
  85.           got = mpz_get_d_2exp (&got_exp, z);
  86.           if (got < 0.5 || got >= 1.0)
  87.             {
  88.               printf    ("mpz_get_d_2exp wrong on 2**%lu-1n", data[i]);
  89.               printf    ("result out of range, expect 0.5 <= got < 1.0n");
  90.               printf    ("   rnd_mode = %dn", rnd_mode);
  91.               printf    ("   data[i]  = %lun", data[i]);
  92.               mpz_trace ("   z    ", z);
  93.               d_trace   ("   got  ", got);
  94.               printf    ("   got exp  %ldn", got_exp);
  95.               abort();
  96.             }
  97.           mpz_neg (z, z);
  98.           got = mpz_get_d_2exp (&got_exp, z);
  99.           if (got <= -1.0 || got > -0.5)
  100.             {
  101.               printf    ("mpz_get_d_2exp wrong on -2**%lu-1n", data[i]);
  102.               printf    ("result out of range, expect -1.0 < got <= -0.5n");
  103.               printf    ("   rnd_mode = %dn", rnd_mode);
  104.               printf    ("   data[i]  = %lun", data[i]);
  105.               mpz_trace ("   z    ", z);
  106.               d_trace   ("   got  ", got);
  107.               printf    ("   got exp  %ldn", got_exp);
  108.               abort();
  109.             }
  110.         }
  111.     }
  112.   mpz_clear (z);
  113.   tests_hardware_setround (old_rnd_mode);
  114. }
  115. static void
  116. check_rand (void)
  117. {
  118.   gmp_randstate_ptr rands = RANDS;
  119.   int     i;
  120.   mpz_t   z;
  121.   double  got;
  122.   long    got_exp;
  123.   unsigned long  bits;
  124.   mpz_init (z);
  125.   for (i = 0; i < 200; i++)
  126.     {
  127.       bits = gmp_urandomm_ui (rands, 512L);
  128.       mpz_urandomb (z, rands, bits);
  129.       got = mpz_get_d_2exp (&got_exp, z);
  130.       if (mpz_sgn (z) == 0)
  131.         continue;
  132.       bits = mpz_sizeinbase (z, 2);
  133.       if (got < 0.5 || got >= 1.0)
  134.         {
  135.           printf    ("mpz_get_d_2exp out of range, expect 0.5 <= got < 1.0n");
  136.           mpz_trace ("   z    ", z);
  137.           d_trace   ("   got  ", got);
  138.           printf    ("   got exp  %ldn", got_exp);
  139.           abort();
  140.         }
  141.       /* FIXME: If mpz_get_d_2exp rounds upwards we might have got_exp ==
  142.          bits+1, so leave this test disabled until we decide if that's what
  143.          should happen, or not.  */
  144. #if 0
  145.       if (got_exp != bits)
  146.         {
  147.           printf    ("mpz_get_d_2exp wrong exponentn", i);
  148.           mpz_trace ("   z    ", z);
  149.           d_trace   ("   bits ", bits);
  150.           d_trace   ("   got  ", got);
  151.           printf    ("   got exp  %ldn", got_exp);
  152.           abort();
  153.         }
  154. #endif
  155.     }
  156.   mpz_clear (z);
  157. }
  158. int
  159. main (void)
  160. {
  161.   tests_start ();
  162.   mp_trace_base = -16;
  163.   check_onebit ();
  164.   check_round ();
  165.   check_rand ();
  166.   tests_end ();
  167.   exit (0);
  168. }