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