1/* Exercise mpf_mul_ui. 2 3Copyright 2004 Free Software Foundation, Inc. 4 5This file is part of the GNU MP Library. 6 7The GNU MP Library is free software; you can redistribute it and/or modify 8it under the terms of the GNU Lesser General Public License as published by 9the Free Software Foundation; either version 3 of the License, or (at your 10option) any later version. 11 12The GNU MP Library is distributed in the hope that it will be useful, but 13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15License for more details. 16 17You should have received a copy of the GNU Lesser General Public License 18along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ 19 20#include <stdio.h> 21#include <stdlib.h> 22#include "gmp.h" 23#include "gmp-impl.h" 24#include "tests.h" 25 26 27void 28check_one (const char *desc, mpf_ptr got, mpf_srcptr u, unsigned long v) 29{ 30 mp_size_t usize, usign; 31 mp_ptr wp; 32 mpf_t want; 33 34 MPF_CHECK_FORMAT (got); 35 36 /* this code not nailified yet */ 37 ASSERT_ALWAYS (BITS_PER_ULONG <= GMP_NUMB_BITS); 38 usign = SIZ (u); 39 usize = ABS (usign); 40 wp = refmpn_malloc_limbs (usize + 1); 41 wp[usize] = mpn_mul_1 (wp, PTR(u), usize, (mp_limb_t) v); 42 43 PTR(want) = wp; 44 SIZ(want) = (usign >= 0 ? usize+1 : -(usize+1)); 45 EXP(want) = EXP(u) + 1; 46 refmpf_normalize (want); 47 48 if (! refmpf_validate ("mpf_mul_ui", got, want)) 49 { 50 mp_trace_base = -16; 51 printf (" %s\n", desc); 52 mpf_trace (" u", u); 53 printf (" v %ld 0x%lX\n", v, v); 54 abort (); 55 } 56 57 free (wp); 58} 59 60void 61check_rand (void) 62{ 63 unsigned long min_prec = __GMPF_BITS_TO_PREC (1); 64 gmp_randstate_ptr rands = RANDS; 65 mpf_t got, u; 66 unsigned long prec, v; 67 int i; 68 69 /* The nails code in mpf_mul_ui currently isn't exact, so suppress these 70 tests for now. */ 71 if (BITS_PER_ULONG > GMP_NUMB_BITS) 72 return; 73 74 mpf_init (got); 75 mpf_init (u); 76 77 for (i = 0; i < 200; i++) 78 { 79 /* got precision */ 80 prec = min_prec + gmp_urandomm_ui (rands, 15L); 81 refmpf_set_prec_limbs (got, prec); 82 83 /* u precision */ 84 prec = min_prec + gmp_urandomm_ui (rands, 15L); 85 refmpf_set_prec_limbs (u, prec); 86 87 /* u, possibly negative */ 88 mpf_random2 (u, PREC(u), (mp_exp_t) 20); 89 if (gmp_urandomb_ui (rands, 1L)) 90 mpf_neg (u, u); 91 92 /* v, 0 to BITS_PER_ULONG bits (inclusive) */ 93 prec = gmp_urandomm_ui (rands, BITS_PER_ULONG+1); 94 v = gmp_urandomb_ui (rands, prec); 95 96 if ((i % 2) == 0) 97 { 98 /* separate */ 99 mpf_mul_ui (got, u, v); 100 check_one ("separate", got, u, v); 101 } 102 else 103 { 104 /* overlap */ 105 prec = refmpf_set_overlap (got, u); 106 mpf_mul_ui (got, got, v); 107 check_one ("overlap src==dst", got, u, v); 108 109 mpf_set_prec_raw (got, prec); 110 } 111 } 112 113 mpf_clear (got); 114 mpf_clear (u); 115} 116 117void 118check_various (void) 119{ 120 mpf_t u, got, want; 121 char *s; 122 123 mpf_init2 (u, 2*8*sizeof(long)); 124 mpf_init2 (got, 2*8*sizeof(long)); 125 mpf_init2 (want, 2*8*sizeof(long)); 126 127 s = "0 * ULONG_MAX"; 128 mpf_set_ui (u, 0L); 129 mpf_mul_ui (got, u, ULONG_MAX); 130 MPF_CHECK_FORMAT (got); 131 mpf_set_ui (want, 0L); 132 if (mpf_cmp (got, want) != 0) 133 { 134 error: 135 printf ("Wrong result from %s\n", s); 136 mpf_trace ("u ", u); 137 mpf_trace ("got ", got); 138 mpf_trace ("want", want); 139 abort (); 140 } 141 142 s = "1 * ULONG_MAX"; 143 mpf_set_ui (u, 1L); 144 mpf_mul_ui (got, u, ULONG_MAX); 145 MPF_CHECK_FORMAT (got); 146 mpf_set_ui (want, ULONG_MAX); 147 if (mpf_cmp (got, want) != 0) 148 goto error; 149 150 mpf_clear (u); 151 mpf_clear (got); 152 mpf_clear (want); 153} 154 155int 156main (void) 157{ 158 tests_start (); 159 160 check_various (); 161 check_rand (); 162 163 tests_end (); 164 exit (0); 165} 166