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

数学计算

开发平台:

Unix_Linux

  1. /* Support for diagnostic traces.
  2. Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation,
  3. Inc.
  4. This file is part of the GNU MP Library.
  5. The GNU MP Library is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU Lesser General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or (at your
  8. option) any later version.
  9. The GNU MP Library is distributed in the hope that it will be useful, but
  10. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  11. or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
  12. License for more details.
  13. You should have received a copy of the GNU Lesser General Public License
  14. along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
  15. /* Future: Would like commas printed between limbs in hex or binary, but
  16.    perhaps not always since it might upset cutting and pasting into bc or
  17.    whatever.  */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h> /* for strlen */
  21. #include "gmp.h"
  22. #include "gmp-impl.h"
  23. #include "tests.h"
  24. /* Number base for the various trace printing routines.
  25.    Set this in main() or with the debugger.
  26.    If hexadecimal is going to be fed into GNU bc, remember to use -16
  27.    because bc requires upper case.  */
  28. int  mp_trace_base = 10;
  29. void
  30. mp_trace_start (const char *name)
  31. {
  32.   if (name != NULL && name[0] != '')
  33.     printf ("%s=", name);
  34.   switch (ABS (mp_trace_base)) {
  35.   case  2: printf ("bin:");                         break;
  36.   case  8: printf ("oct:");                         break;
  37.   case 10:                                          break;
  38.   case 16: printf ("0x");                           break;
  39.   default: printf ("base%d:", ABS (mp_trace_base)); break;
  40.   }
  41. }
  42. /* Print "name=valuen" to stdout for an mpq_t value.  */
  43. void
  44. mpq_trace (const char *name, mpq_srcptr q)
  45. {
  46.   mp_trace_start (name);
  47.   if (q == NULL)
  48.     {
  49.       printf ("NULLn");
  50.       return;
  51.     }
  52.   mpq_out_str (stdout, mp_trace_base, q);
  53.   printf ("n");
  54. }
  55. /* Print "name=valuen" to stdout for an mpz_t value.  */
  56. void
  57. mpz_trace (const char *name, mpz_srcptr z)
  58. {
  59.   mpq_t      q;
  60.   mp_limb_t  one;
  61.   if (z == NULL)
  62.     {
  63.       mpq_trace (name, NULL);
  64.       return;
  65.     }
  66.   q->_mp_num._mp_alloc = ALLOC(z);
  67.   q->_mp_num._mp_size = SIZ(z);
  68.   q->_mp_num._mp_d = PTR(z);
  69.   one = 1;
  70.   q->_mp_den._mp_alloc = 1;
  71.   q->_mp_den._mp_size = 1;
  72.   q->_mp_den._mp_d = &one;
  73.   mpq_trace(name, q);
  74. }
  75. /* Print "name=valuen" to stdout for an mpf_t value. */
  76. void
  77. mpf_trace (const char *name, mpf_srcptr f)
  78. {
  79.   mp_trace_start (name);
  80.   if (f == NULL)
  81.     {
  82.       printf ("NULLn");
  83.       return;
  84.     }
  85.   mpf_out_str (stdout, ABS (mp_trace_base), 0, f);
  86.   printf ("n");
  87. }
  88. /* Print "namenum=valuen" to stdout for an mpz_t value.
  89.    "name" should have a "%d" to get the number. */
  90. void
  91. mpz_tracen (const char *name, int num, mpz_srcptr z)
  92. {
  93.   if (name != NULL && name[0] != '')
  94.     {
  95.       printf (name, num);
  96.       putchar ('=');
  97.     }
  98.   mpz_trace (NULL, z);
  99. }
  100. /* Print "name=valuen" to stdout for an mpn style ptr,size. */
  101. void
  102. mpn_trace (const char *name, mp_srcptr ptr, mp_size_t size)
  103. {
  104.   mpz_t  z;
  105.   if (ptr == NULL)
  106.     {
  107.       mpz_trace (name, NULL);
  108.       return;
  109.     }
  110.   MPN_NORMALIZE (ptr, size);
  111.   PTR(z) = (mp_ptr) ptr;
  112.   SIZ(z) = size;
  113.   ALLOC(z) = size;
  114.   mpz_trace (name, z);
  115. }
  116. /* Print "name=valuen" to stdout for a limb, nail doesn't have to be zero. */
  117. void
  118. mp_limb_trace (const char *name, mp_limb_t n)
  119. {
  120. #if GMP_NAIL_BITS != 0
  121.   mp_limb_t  a[2];
  122.   a[0] = n & GMP_NUMB_MASK;
  123.   a[1] = n >> GMP_NUMB_BITS;
  124.   mpn_trace (name, a, (mp_size_t) 2);
  125. #else
  126.   mpn_trace (name, &n, (mp_size_t) 1);
  127. #endif
  128. }
  129. /* Print "namenum=valuen" to stdout for an mpn style ptr,size.
  130.    "name" should have a "%d" to get the number.  */
  131. void
  132. mpn_tracen (const char *name, int num, mp_srcptr ptr, mp_size_t size)
  133. {
  134.   if (name != NULL && name[0] != '')
  135.     {
  136.       printf (name, num);
  137.       putchar ('=');
  138.     }
  139.   mpn_trace (NULL, ptr, size);
  140. }
  141. /* Print "namenum=valuen" to stdout for an array of mpn style ptr,size.
  142.    "a" is an array of pointers, each a[i] is a pointer to "size" many limbs.
  143.    The formal parameter isn't mp_srcptr because that causes compiler
  144.    warnings, but the values aren't modified.
  145.    "name" should have a printf style "%d" to get the array index.  */
  146. void
  147. mpn_tracea (const char *name, const mp_ptr *a, int count, mp_size_t size)
  148. {
  149.   int i;
  150.   for (i = 0; i < count; i++)
  151.     mpn_tracen (name, i, a[i], size);
  152. }
  153. /* Print "valuen" to a file for an mpz_t value.  Any previous contents of
  154.    the file are overwritten, so you need different file names each time this
  155.    is called.
  156.    Overwriting the file is a feature, it means you get old data replaced
  157.    when you run a test program repeatedly.  */
  158. void
  159. mpn_trace_file (const char *filename, mp_srcptr ptr, mp_size_t size)
  160. {
  161.   FILE   *fp;
  162.   mpz_t  z;
  163.   fp = fopen (filename, "w");
  164.   if (fp == NULL)
  165.     {
  166.       perror ("fopen");
  167.       abort();
  168.     }
  169.   MPN_NORMALIZE (ptr, size);
  170.   PTR(z) = (mp_ptr) ptr;
  171.   SIZ(z) = (int) size;
  172.   mpz_out_str (fp, mp_trace_base, z);
  173.   fprintf (fp, "n");
  174.   if (ferror (fp) || fclose (fp) != 0)
  175.     {
  176.       printf ("error writing %sn", filename);
  177.       abort();
  178.     }
  179. }
  180. /* Print "valuen" to a set of files, one file for each element of the given
  181.    array of mpn style ptr,size.  Any previous contents of the files are
  182.    overwritten, so you need different file names each time this is called.
  183.    Each file is "filenameN" where N is 0 to count-1.
  184.    "a" is an array of pointers, each a[i] is a pointer to "size" many limbs.
  185.    The formal parameter isn't mp_srcptr because that causes compiler
  186.    warnings, but the values aren't modified.
  187.    Overwriting the files is a feature, it means you get old data replaced
  188.    when you run a test program repeatedly.  The output style isn't
  189.    particularly pretty, but at least it gets something out, and you can cat
  190.    the files into bc, or whatever. */
  191. void
  192. mpn_tracea_file (const char *filename,
  193.                  const mp_ptr *a, int count, mp_size_t size)
  194. {
  195.   char  *s;
  196.   int   i;
  197.   TMP_DECL;
  198.   TMP_MARK;
  199.   s = (char *) TMP_ALLOC (strlen (filename) + 50);
  200.   for (i = 0; i < count; i++)
  201.     {
  202.       sprintf (s, "%s%d", filename, i);
  203.       mpn_trace_file (s, a[i], size);
  204.     }
  205.   TMP_FREE;
  206. }
  207. void
  208. byte_trace (const char *name, const void *ptr, mp_size_t size)
  209. {
  210.   char       *fmt;
  211.   mp_size_t  i;
  212.   mp_trace_start (name);
  213.   switch (mp_trace_base) {
  214.   case   8: fmt = " %o"; break;
  215.   case  10: fmt = " %d"; break;
  216.   case  16: fmt = " %x"; break;
  217.   case -16: fmt = " %X"; break;
  218.   default: printf ("Oops, unsupported base in byte_tracen"); abort (); break;
  219.   }
  220.   for (i = 0; i < size; i++)
  221.     printf (fmt, (int) ((unsigned char *) ptr)[i]);
  222.   printf ("n");
  223. }
  224. void
  225. byte_tracen (const char *name, int num, const void *ptr, mp_size_t size)
  226. {
  227.   if (name != NULL && name[0] != '')
  228.     {
  229.       printf (name, num);
  230.       putchar ('=');
  231.     }
  232.   byte_trace (NULL, ptr, size);
  233. }
  234. void
  235. d_trace (const char *name, double d)
  236. {
  237.   union {
  238.     double         d;
  239.     unsigned char  b[sizeof(double)];
  240.   } u;
  241.   int  i;
  242.   if (name != NULL && name[0] != '')
  243.     printf ("%s=", name);
  244.   u.d = d;
  245.   printf ("[");
  246.   for (i = 0; i < sizeof (u.b); i++)
  247.     {
  248.       if (i != 0)
  249.         printf (" ");
  250.       printf ("%02X", (int) u.b[i]);
  251.     }
  252.   printf ("] %.20gn", d);
  253. }