1 /* Test mpq_add and mpq_sub. 2 3 Copyright 2001 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 "config.h" 21 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 #include "gmp-impl.h" 27 #include "tests.h" 28 29 30 void 31 check_all (mpq_ptr x, mpq_ptr y, mpq_ptr want_add, mpq_ptr want_sub) 32 { 33 mpq_t got; 34 int neg_x, neg_y, swap; 35 36 mpq_init (got); 37 38 MPQ_CHECK_FORMAT (want_add); 39 MPQ_CHECK_FORMAT (want_sub); 40 MPQ_CHECK_FORMAT (x); 41 MPQ_CHECK_FORMAT (y); 42 43 for (swap = 0; swap <= 1; swap++) 44 { 45 for (neg_x = 0; neg_x <= 1; neg_x++) 46 { 47 for (neg_y = 0; neg_y <= 1; neg_y++) 48 { 49 mpq_add (got, x, y); 50 MPQ_CHECK_FORMAT (got); 51 if (! mpq_equal (got, want_add)) 52 { 53 printf ("mpq_add wrong\n"); 54 mpq_trace (" x ", x); 55 mpq_trace (" y ", y); 56 mpq_trace (" got ", got); 57 mpq_trace (" want", want_add); 58 abort (); 59 } 60 61 mpq_sub (got, x, y); 62 MPQ_CHECK_FORMAT (got); 63 if (! mpq_equal (got, want_sub)) 64 { 65 printf ("mpq_sub wrong\n"); 66 mpq_trace (" x ", x); 67 mpq_trace (" y ", y); 68 mpq_trace (" got ", got); 69 mpq_trace (" want", want_sub); 70 abort (); 71 } 72 73 74 mpq_neg (y, y); 75 mpq_swap (want_add, want_sub); 76 } 77 78 mpq_neg (x, x); 79 mpq_swap (want_add, want_sub); 80 mpq_neg (want_add, want_add); 81 mpq_neg (want_sub, want_sub); 82 } 83 84 mpq_swap (x, y); 85 mpq_neg (want_sub, want_sub); 86 } 87 88 mpq_clear (got); 89 } 90 91 92 void 93 check_data (void) 94 { 95 static const struct { 96 const char *x; 97 const char *y; 98 const char *want_add; 99 const char *want_sub; 100 101 } data[] = { 102 103 { "0", "0", "0", "0" }, 104 { "1", "0", "1", "1" }, 105 { "1", "1", "2", "0" }, 106 107 { "1/2", "1/2", "1", "0" }, 108 { "5/6", "14/15", "53/30", "-1/10" }, 109 }; 110 111 mpq_t x, y, want_add, want_sub; 112 int i; 113 114 mpq_init (x); 115 mpq_init (y); 116 mpq_init (want_add); 117 mpq_init (want_sub); 118 119 for (i = 0; i < numberof (data); i++) 120 { 121 mpq_set_str_or_abort (x, data[i].x, 0); 122 mpq_set_str_or_abort (y, data[i].y, 0); 123 mpq_set_str_or_abort (want_add, data[i].want_add, 0); 124 mpq_set_str_or_abort (want_sub, data[i].want_sub, 0); 125 126 check_all (x, y, want_add, want_sub); 127 } 128 129 mpq_clear (x); 130 mpq_clear (y); 131 mpq_clear (want_add); 132 mpq_clear (want_sub); 133 } 134 135 136 void 137 check_rand (void) 138 { 139 mpq_t x, y, want_add, want_sub; 140 int i; 141 gmp_randstate_ptr rands = RANDS; 142 143 mpq_init (x); 144 mpq_init (y); 145 mpq_init (want_add); 146 mpq_init (want_sub); 147 148 for (i = 0; i < 500; i++) 149 { 150 mpz_errandomb (mpq_numref(x), rands, 512L); 151 mpz_errandomb_nonzero (mpq_denref(x), rands, 512L); 152 mpq_canonicalize (x); 153 154 mpz_errandomb (mpq_numref(y), rands, 512L); 155 mpz_errandomb_nonzero (mpq_denref(y), rands, 512L); 156 mpq_canonicalize (y); 157 158 refmpq_add (want_add, x, y); 159 refmpq_sub (want_sub, x, y); 160 161 check_all (x, y, want_add, want_sub); 162 } 163 164 mpq_clear (x); 165 mpq_clear (y); 166 mpq_clear (want_add); 167 mpq_clear (want_sub); 168 } 169 170 171 int 172 main (void) 173 { 174 tests_start (); 175 176 check_data (); 177 check_rand (); 178 179 tests_end (); 180 181 exit (0); 182 } 183