1/* Test file for mpfr_custom_* 2 3Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4Contributed by the Arenaire and Cacao projects, INRIA. 5 6This file is part of the GNU MPFR Library. 7 8The GNU MPFR Library is free software; you can redistribute it and/or modify 9it under the terms of the GNU Lesser General Public License as published by 10the Free Software Foundation; either version 3 of the License, or (at your 11option) any later version. 12 13The GNU MPFR Library is distributed in the hope that it will be useful, but 14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16License for more details. 17 18You should have received a copy of the GNU Lesser General Public License 19along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 23#include <stdlib.h> 24 25#include "mpfr-test.h" 26 27#define BUFFER_SIZE 250 28#define PREC_TESTED 200 29 30long Buffer[BUFFER_SIZE]; 31char *stack = (char *) Buffer; 32mpfr_prec_t p = PREC_TESTED; 33 34#define ALIGNED(s) (((s) + sizeof (long) - 1) / sizeof (long) * sizeof (long)) 35 36static void * 37new_st (size_t s) 38{ 39 void *p = (void *) stack; 40 stack += ALIGNED (s); 41 if (MPFR_UNLIKELY (stack > (char *) &Buffer[BUFFER_SIZE])) 42 { 43 printf ("Stack overflow.\n"); 44 exit (1); 45 } 46 return p; 47} 48 49 /* Alloc a new mpfr_t on the main stack */ 50static mpfr_ptr 51new_mpfr (mpfr_prec_t p) 52{ 53 mpfr_ptr x = (mpfr_ptr) new_st (sizeof (mpfr_t)); 54 void *mantissa = new_st (mpfr_custom_get_size (p)); 55 mpfr_custom_init (mantissa, p); 56 mpfr_custom_init_set (x, 0, 0, p, mantissa); 57 return x; 58} 59 60 /* Garbage the stack by keeping only x */ 61static mpfr_ptr 62return_mpfr (mpfr_ptr x, char *old_stack) 63{ 64 void *mantissa = mpfr_custom_get_significand (x); 65 size_t size_mantissa = mpfr_custom_get_size (mpfr_get_prec (x)); 66 mpfr_ptr newx; 67 68 memmove (old_stack, x, sizeof (mpfr_t)); 69 memmove (old_stack + ALIGNED (sizeof (mpfr_t)), mantissa, size_mantissa); 70 newx = (mpfr_ptr) old_stack; 71 mpfr_custom_move (newx, old_stack + ALIGNED (sizeof (mpfr_t))); 72 stack = old_stack + ALIGNED (sizeof (mpfr_t)) + ALIGNED (size_mantissa); 73 return newx; 74} 75 76static void 77test1 (void) 78{ 79 mpfr_ptr x, y; 80 char *org; 81 82 org = stack; 83 x = new_mpfr (p); 84 y = new_mpfr (p); 85 mpfr_set_ui (x, 42, MPFR_RNDN); 86 mpfr_set_ui (y, 17, MPFR_RNDN); 87 mpfr_add (y, x, y, MPFR_RNDN); 88 y = return_mpfr (y, org); 89 if (y != x || mpfr_cmp_ui (y, 59) != 0) 90 { 91 printf ("Compact (1) failed!\n"); 92 exit (1); 93 } 94 stack = org; 95} 96 97/* We build the MPFR variable each time it is needed */ 98/* a[0] is the kind, a[1] is the exponent, &a[2] is the mantissa */ 99static long * 100dummy_new (void) 101{ 102 long *r; 103 104 r = (long *) new_st (ALIGNED (2 * sizeof (long)) + 105 ALIGNED (mpfr_custom_get_size (p))); 106 MPFR_ASSERTN (r != NULL); 107 (mpfr_custom_init) (&r[2], p); 108 r[0] = (int) MPFR_NAN_KIND; 109 r[1] = 0; 110 return r; 111} 112 113static long * 114dummy_set_si (long si) 115{ 116 mpfr_t x; 117 long * r = dummy_new (); 118 (mpfr_custom_init_set) (x, 0, 0, p, &r[2]); 119 mpfr_set_si (x, si, MPFR_RNDN); 120 r[0] = mpfr_custom_get_kind (x); 121 r[1] = mpfr_custom_get_exp (x); 122 return r; 123} 124 125static long * 126dummy_add (long *a, long *b) 127{ 128 mpfr_t x, y, z; 129 long *r = dummy_new (); 130 mpfr_custom_init_set (x, 0, 0, p, &r[2]); 131 (mpfr_custom_init_set) (y, a[0], a[1], p, &a[2]); 132 mpfr_custom_init_set (z, b[0], b[1], p, &b[2]); 133 mpfr_add (x, y, z, MPFR_RNDN); 134 r[0] = (mpfr_custom_get_kind) (x); 135 r[1] = (mpfr_custom_get_exp) (x); 136 return r; 137} 138 139static long * 140dummy_compact (long *r, char *org_stack) 141{ 142 memmove (org_stack, r, 143 ALIGNED (2*sizeof (long)) + ALIGNED ((mpfr_custom_get_size) (p))); 144 return (long *) org_stack; 145} 146 147static void 148test2 (void) 149{ 150 mpfr_t x; 151 char *org = stack; 152 long *a, *b, *c; 153 154 a = dummy_set_si (42); 155 b = dummy_set_si (17); 156 c = dummy_add (a, b); 157 c = dummy_compact (c, org); 158 (mpfr_custom_init_set) (x, c[0], c[1], p, &c[2]); 159 if (c != a || mpfr_cmp_ui (x, 59) != 0) 160 { 161 printf ("Compact (2) failed! c=%p a=%p\n", (void *) c, (void *) a); 162 mpfr_dump (x); 163 exit (1); 164 } 165 stack = org; 166} 167 168int 169main (void) 170{ 171 tests_start_mpfr (); 172 /* We test iff long = mp_limb_t */ 173 if (sizeof (long) == sizeof (mp_limb_t)) 174 { 175 test1 (); 176 test2 (); 177 } 178 tests_end_mpfr (); 179 return 0; 180} 181