github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/gen-fib.c (about)

     1  /* Generate Fibonacci table data.
     2  
     3  Copyright 2001, 2002, 2004, 2012, 2014, 2015 Free Software Foundation, Inc.
     4  
     5  This file is part of the GNU MP Library.
     6  
     7  The GNU MP Library is free software; you can redistribute it and/or modify
     8  it under the terms of either:
     9  
    10    * the GNU Lesser General Public License as published by the Free
    11      Software Foundation; either version 3 of the License, or (at your
    12      option) any later version.
    13  
    14  or
    15  
    16    * the GNU General Public License as published by the Free Software
    17      Foundation; either version 2 of the License, or (at your option) any
    18      later version.
    19  
    20  or both in parallel, as here.
    21  
    22  The GNU MP Library is distributed in the hope that it will be useful, but
    23  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    24  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    25  for more details.
    26  
    27  You should have received copies of the GNU General Public License and the
    28  GNU Lesser General Public License along with the GNU MP Library.  If not,
    29  see https://www.gnu.org/licenses/.  */
    30  
    31  #include <stdio.h>
    32  #include "bootstrap.c"
    33  
    34  mpz_t  *f;
    35  int    fnum, fib_limit, luc_limit;
    36  
    37  void
    38  generate (int numb_bits)
    39  {
    40    mpz_t  limit, l;
    41    int    falloc, i;
    42  
    43    mpz_init2 (limit, numb_bits + 1);
    44    mpz_setbit (limit, numb_bits);
    45  
    46    /* fib(2n) > 2^n, so use 2n as a limit for the table size */
    47    falloc = 2 * numb_bits;
    48    f = (mpz_t*) xmalloc (falloc * sizeof (*f));
    49  
    50    mpz_init_set_ui (f[0], 1L);  /* F[-1] */
    51    mpz_init_set_ui (f[1], 0L);  /* F[0] */
    52  
    53    mpz_init (l);
    54  
    55    for (i = 2; ; i++)
    56      {
    57        assert (i < falloc);
    58  
    59        /* F[i] = F[i-1] + F[i-2] */
    60        mpz_init (f[i]);
    61        mpz_add (f[i], f[i-1], f[i-2]);
    62        if (mpz_cmp (f[i], limit) >= 0)
    63          break;
    64  
    65        fnum = i+1;
    66        fib_limit = i-1;
    67  
    68        /* L[i] = F[i]+2*F[i-1] */
    69        mpz_add (l, f[i], f[i-1]);
    70        mpz_add (l, l, f[i-1]);
    71  
    72        if (mpz_cmp (l, limit) < 0)
    73          luc_limit = i-1;
    74      }
    75  
    76    mpz_clear (limit);
    77  }
    78  
    79  
    80  void
    81  header (int numb_bits)
    82  {
    83    printf ("/* This file generated by gen-fib.c - DO NOT EDIT. */\n");
    84    printf ("\n");
    85    printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
    86    printf ("Error, error, this data is for %d bits\n", numb_bits);
    87    printf ("#endif\n");
    88    printf ("\n");
    89    printf ("#define FIB_TABLE_LIMIT         %d\n", fib_limit);
    90    printf ("#define FIB_TABLE_LUCNUM_LIMIT  %d\n", luc_limit);
    91  }
    92  
    93  void
    94  table (int numb_bits)
    95  {
    96    int  i;
    97  
    98    printf ("/* This file generated by gen-fib.c - DO NOT EDIT. */\n");
    99    printf ("\n");
   100    printf ("#include \"gmp.h\"\n");
   101    printf ("#include \"gmp-impl.h\"\n");
   102    printf ("\n");
   103    printf ("#if GMP_NUMB_BITS != %d\n", numb_bits);
   104    printf ("Error, error, this data is for %d bits\n", numb_bits);
   105    printf ("#endif\n");
   106    printf ("\n");
   107    printf ("const mp_limb_t\n");
   108    printf ("__gmp_fib_table[FIB_TABLE_LIMIT+2] = {\n");
   109  
   110    for (i = 0; i < fnum; i++)
   111      {
   112        printf ("  CNST_LIMB (0x");
   113        mpz_out_str (stdout, 16, f[i]);
   114        printf ("),  /* %d */\n", i-1);
   115      }
   116    printf ("};\n");
   117  }
   118  
   119  int
   120  main (int argc, char *argv[])
   121  {
   122    int  limb_bits, nail_bits, numb_bits;
   123  
   124    if (argc != 4)
   125      {
   126        fprintf (stderr, "Usage: gen-fib <header|table> <limbbits> <nailbits>\n");
   127        exit (1);
   128      }
   129  
   130    limb_bits = atoi (argv[2]);
   131    nail_bits = atoi (argv[3]);
   132  
   133    if (limb_bits <= 0
   134        || nail_bits < 0
   135        || nail_bits >= limb_bits)
   136      {
   137        fprintf (stderr, "Invalid limb/nail bits: %d %d\n",
   138                 limb_bits, nail_bits);
   139        exit (1);
   140      }
   141    numb_bits = limb_bits - nail_bits;
   142  
   143    generate (numb_bits);
   144  
   145    if (strcmp (argv[1], "header") == 0)
   146      header (numb_bits);
   147    else if (strcmp (argv[1], "table") == 0)
   148      table (numb_bits);
   149    else
   150      {
   151        fprintf (stderr, "Invalid header/table choice: %s\n", argv[1]);
   152        exit (1);
   153      }
   154  
   155    return 0;
   156  }