1 /* Test mpz_fib_ui and mpz_fib2_ui. 2 3 Copyright 2000-2002 Free Software Foundation, Inc. 4 5 This file is part of the GNU MP Library test suite. 6 7 The GNU MP Library test suite is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 3 of the License, 10 or (at your option) any later version. 11 12 The GNU MP Library test suite is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 Public License for more details. 16 17 You should have received a copy of the GNU General Public License along with 18 the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 19 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include "gmp-impl.h" 23 #include "tests.h" 24 25 26 /* Usage: t-fib_ui [x|num] 27 28 Run with no arguments, tests goes up to the initial value of "limit" 29 below. With a number argument tests are carried up that far, or with a 30 literal "x" tests are continued without limit (this being only meant for 31 development purposes). 32 33 The size tests performed are designed to partially replicate what will be 34 going on in mpz_fib_ui. There's plenty of ASSERTs there, but of course 35 they're not normally enabled. 36 37 Misfeatures: 38 39 The tests on MPN_FIB2_SIZE are a bit useless, since that macro includes a 40 +2 for the internal purposes of mpn_fib2_ui. It's probably better to 41 give mpn_fib2_ui a run with assertion checking enabled. */ 42 43 44 #define MPZ_FIB_SIZE_FLOAT(n) \ 45 ((mp_size_t) ((n) * 0.6942419 / GMP_NUMB_BITS + 1)) 46 47 48 void 49 check_fib_table (void) 50 { 51 int i; 52 mp_limb_t want; 53 54 ASSERT_ALWAYS (FIB_TABLE(-1) == 1); 55 ASSERT_ALWAYS (FIB_TABLE(0) == 0); 56 57 for (i = 1; i <= FIB_TABLE_LIMIT; i++) 58 { 59 want = FIB_TABLE(i-1) + FIB_TABLE(i-2); 60 if (FIB_TABLE(i) != want) 61 { 62 printf ("FIB_TABLE(%d) wrong\n", i); 63 gmp_printf (" got %#Nx\n", &FIB_TABLE(i), 1); 64 gmp_printf (" want %#Nx\n", &want, 1); 65 abort (); 66 } 67 } 68 } 69 70 71 int 72 main (int argc, char *argv[]) 73 { 74 unsigned long n; 75 unsigned long limit = 100 * GMP_LIMB_BITS; 76 mpz_t want_fn, want_fn1, got_fn, got_fn1; 77 78 tests_start (); 79 mp_trace_base = -16; 80 if (argc > 1 && argv[1][0] == 'x') 81 limit = ULONG_MAX; 82 else 83 TESTS_REPS (limit, argv, argc); 84 85 check_fib_table (); 86 87 /* start at n==0 */ 88 mpz_init_set_ui (want_fn1, 1); /* F[-1] */ 89 mpz_init_set_ui (want_fn, 0); /* F[0] */ 90 mpz_init (got_fn); 91 mpz_init (got_fn1); 92 93 for (n = 0; n < limit; n++) 94 { 95 /* check our float formula seems right */ 96 if (MPZ_FIB_SIZE_FLOAT (n) < SIZ(want_fn)) 97 { 98 printf ("MPZ_FIB_SIZE_FLOAT wrong at n=%lu\n", n); 99 printf (" MPZ_FIB_SIZE_FLOAT %ld\n", MPZ_FIB_SIZE_FLOAT (n)); 100 printf (" SIZ(want_fn) %d\n", SIZ(want_fn)); 101 abort (); 102 } 103 104 /* check MPN_FIB2_SIZE seems right, compared to actual size and 105 compared to our float formula */ 106 if (MPN_FIB2_SIZE (n) < MPZ_FIB_SIZE_FLOAT (n)) 107 { 108 printf ("MPN_FIB2_SIZE wrong at n=%lu\n", n); 109 printf (" MPN_FIB2_SIZE %ld\n", MPN_FIB2_SIZE (n)); 110 printf (" MPZ_FIB_SIZE_FLOAT %ld\n", MPZ_FIB_SIZE_FLOAT (n)); 111 abort (); 112 } 113 if (MPN_FIB2_SIZE (n) < SIZ(want_fn)) 114 { 115 printf ("MPN_FIB2_SIZE wrong at n=%lu\n", n); 116 printf (" MPN_FIB2_SIZE %ld\n", MPN_FIB2_SIZE (n)); 117 printf (" SIZ(want_fn) %d\n", SIZ(want_fn)); 118 abort (); 119 } 120 121 mpz_fib2_ui (got_fn, got_fn1, n); 122 MPZ_CHECK_FORMAT (got_fn); 123 MPZ_CHECK_FORMAT (got_fn1); 124 if (mpz_cmp (got_fn, want_fn) != 0 || mpz_cmp (got_fn1, want_fn1) != 0) 125 { 126 printf ("mpz_fib2_ui(%lu) wrong\n", n); 127 mpz_trace ("want fn ", want_fn); 128 mpz_trace ("got fn ", got_fn); 129 mpz_trace ("want fn1", want_fn1); 130 mpz_trace ("got fn1", got_fn1); 131 abort (); 132 } 133 134 mpz_fib_ui (got_fn, n); 135 MPZ_CHECK_FORMAT (got_fn); 136 if (mpz_cmp (got_fn, want_fn) != 0) 137 { 138 printf ("mpz_fib_ui(%lu) wrong\n", n); 139 mpz_trace ("want fn", want_fn); 140 mpz_trace ("got fn", got_fn); 141 abort (); 142 } 143 144 mpz_add (want_fn1, want_fn1, want_fn); /* F[n+1] = F[n] + F[n-1] */ 145 mpz_swap (want_fn1, want_fn); 146 } 147 148 mpz_clear (want_fn); 149 mpz_clear (want_fn1); 150 mpz_clear (got_fn); 151 mpz_clear (got_fn1); 152 153 tests_end (); 154 exit (0); 155 } 156