1 /* Test file for mpfr_custom_* 2 3 Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. 4 Contributed by the AriC and Caramel projects, INRIA. 5 6 This file is part of the GNU MPFR Library. 7 8 The GNU MPFR Library is free software; you can redistribute it and/or modify 9 it under the terms of the GNU Lesser General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or (at your 11 option) any later version. 12 13 The GNU MPFR Library is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16 License for more details. 17 18 You should have received a copy of the GNU Lesser General Public License 19 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 21 51 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 30 long Buffer[BUFFER_SIZE]; 31 char *stack = (char *) Buffer; 32 mpfr_prec_t p = PREC_TESTED; 33 34 #define ALIGNED(s) (((s) + sizeof (long) - 1) / sizeof (long) * sizeof (long)) 35 36 static void * 37 new_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 */ 50 static mpfr_ptr 51 new_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 */ 61 static mpfr_ptr 62 return_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 76 static void 77 test1 (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 */ 99 static long * 100 dummy_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 113 static long * 114 dummy_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 125 static long * 126 dummy_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 139 static long * 140 dummy_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 147 static void 148 test2 (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 168 static void 169 test_nan_inf_zero (void) 170 { 171 mpfr_ptr val; 172 int sign; 173 int kind; 174 char *org = stack; 175 176 val = new_mpfr (MPFR_PREC_MIN); 177 178 mpfr_set_nan (val); 179 kind = (mpfr_custom_get_kind) (val); 180 if (kind != MPFR_NAN_KIND) 181 { 182 printf ("mpfr_custom_get_kind error : "); 183 mpfr_dump (val); 184 printf (" is kind %d instead of %d\n", kind, MPFR_NAN_KIND); 185 exit (1); 186 } 187 188 sign = 1; 189 mpfr_set_inf (val, sign); 190 kind = (mpfr_custom_get_kind) (val); 191 if ((ABS (kind) != MPFR_INF_KIND) || (SIGN (kind) != SIGN (sign))) 192 { 193 printf ("mpfr_custom_get_kind error : "); 194 mpfr_dump (val); 195 printf (" is kind %d instead of %d\n", kind, MPFR_INF_KIND); 196 printf (" have sign %d instead of %d\n", SIGN (kind), SIGN (sign)); 197 exit (1); 198 } 199 200 sign = -1; 201 mpfr_set_zero (val, sign); 202 kind = (mpfr_custom_get_kind) (val); 203 if ((ABS (kind) != MPFR_ZERO_KIND) || (SIGN (kind) != SIGN (sign))) 204 { 205 printf ("mpfr_custom_get_kind error : "); 206 mpfr_dump (val); 207 printf (" is kind %d instead of %d\n", kind, MPFR_ZERO_KIND); 208 printf (" have sign %d instead of %d\n", SIGN (kind), SIGN (sign)); 209 exit (1); 210 } 211 212 stack = org; 213 } 214 215 int 216 main (void) 217 { 218 tests_start_mpfr (); 219 /* We test iff long = mp_limb_t */ 220 if (sizeof (long) == sizeof (mp_limb_t)) 221 { 222 test1 (); 223 test2 (); 224 test_nan_inf_zero (); 225 } 226 tests_end_mpfr (); 227 return 0; 228 } 229