1/* Test mpq_add and mpq_sub. 2 3Copyright 2001 Free Software Foundation, Inc. 4 5This file is part of the GNU MP Library test suite. 6 7The GNU MP Library test suite is free software; you can redistribute it 8and/or modify it under the terms of the GNU General Public License as 9published by the Free Software Foundation; either version 3 of the License, 10or (at your option) any later version. 11 12The GNU MP Library test suite is distributed in the hope that it will be 13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15Public License for more details. 16 17You should have received a copy of the GNU General Public License along with 18the 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 30void 31check_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 92void 93check_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 136void 137check_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 171int 172main (void) 173{ 174 tests_start (); 175 176 check_data (); 177 check_rand (); 178 179 tests_end (); 180 181 exit (0); 182} 183