1 /* mpirxx.h -- C++ class wrapper for GMP types. -*- C++ -*- 2 3 Copyright 2001, 2002, 2003, 2006, 2008 Free Software Foundation, Inc. 4 5 Copyright 2009 William Hart 6 7 This file is part of the GNU MP Library. 8 9 The GNU MP Library is free software; you can redistribute it and/or modify 10 it under the terms of the GNU Lesser General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or (at your 12 option) any later version. 13 14 The GNU MP Library is distributed in the hope that it will be useful, but 15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17 License for more details. 18 19 You should have received a copy of the GNU Lesser General Public License 20 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ 21 22 /* the C++ compiler must implement the following features: 23 - member templates 24 - partial specialization of templates 25 - namespace support 26 for g++, this means version 2.91 or higher 27 for other compilers, I don't know */ 28 #ifdef __GNUC__ 29 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 91) 30 #error mpirxx.h requires g++ version 2.91 (egcs 1.1.2) or higher 31 #endif 32 #endif 33 34 #ifndef __GMP_PLUSPLUS__ 35 #define __GMP_PLUSPLUS__ 36 37 #include <iosfwd> 38 39 #include <cstring> /* for strlen */ 40 #include <string> 41 #include <stdexcept> 42 #include <cfloat> 43 #include <mpir.h> 44 45 46 /**************** Function objects ****************/ 47 /* Any evaluation of a __gmp_expr ends up calling one of these functions 48 all intermediate functions being inline, the evaluation should optimize 49 to a direct call to the relevant function, thus yielding no overhead 50 over the C interface. */ 51 52 struct __gmp_unary_plus 53 { eval__gmp_unary_plus54 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_set(z, w); } eval__gmp_unary_plus55 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_set(q, r); } eval__gmp_unary_plus56 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_set(f, g); } 57 }; 58 59 struct __gmp_unary_minus 60 { eval__gmp_unary_minus61 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_neg(z, w); } eval__gmp_unary_minus62 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_neg(q, r); } eval__gmp_unary_minus63 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_neg(f, g); } 64 }; 65 66 struct __gmp_unary_com 67 { eval__gmp_unary_com68 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_com(z, w); } 69 }; 70 71 struct __gmp_binary_plus 72 { eval__gmp_binary_plus73 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) 74 { mpz_add(z, w, v); } 75 eval__gmp_binary_plus76 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) 77 { mpz_add_ui(z, w, l); } eval__gmp_binary_plus78 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) 79 { mpz_add_ui(z, w, l); } eval__gmp_binary_plus80 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) 81 { 82 if (l >= 0) 83 mpz_add_ui(z, w, l); 84 else 85 mpz_sub_ui(z, w, -l); 86 } eval__gmp_binary_plus87 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) 88 { 89 if (l >= 0) 90 mpz_add_ui(z, w, l); 91 else 92 mpz_sub_ui(z, w, -l); 93 } eval__gmp_binary_plus94 static void eval(mpz_ptr z, mpz_srcptr w, double d) 95 { 96 mpz_t temp; 97 mpz_init_set_d(temp, d); 98 mpz_add(z, w, temp); 99 mpz_clear(temp); 100 } eval__gmp_binary_plus101 static void eval(mpz_ptr z, double d, mpz_srcptr w) 102 { 103 mpz_t temp; 104 mpz_init_set_d(temp, d); 105 mpz_add(z, temp, w); 106 mpz_clear(temp); 107 } 108 eval__gmp_binary_plus109 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s) 110 { mpq_add(q, r, s); } 111 eval__gmp_binary_plus112 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l) 113 { mpq_set(q, r); mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); } eval__gmp_binary_plus114 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r) 115 { mpq_set(q, r); mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); } eval__gmp_binary_plus116 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l) 117 { 118 mpq_set(q, r); 119 if (l >= 0) 120 mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); 121 else 122 mpz_submul_ui(mpq_numref(q), mpq_denref(q), -l); 123 } eval__gmp_binary_plus124 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r) 125 { 126 mpq_set(q, r); 127 if (l >= 0) 128 mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); 129 else 130 mpz_submul_ui(mpq_numref(q), mpq_denref(q), -l); 131 } eval__gmp_binary_plus132 static void eval(mpq_ptr q, mpq_srcptr r, double d) 133 { 134 mpq_t temp; 135 mpq_init(temp); 136 mpq_set_d(temp, d); 137 mpq_add(q, r, temp); 138 mpq_clear(temp); 139 } eval__gmp_binary_plus140 static void eval(mpq_ptr q, double d, mpq_srcptr r) 141 { 142 mpq_t temp; 143 mpq_init(temp); 144 mpq_set_d(temp, d); 145 mpq_add(q, temp, r); 146 mpq_clear(temp); 147 } 148 eval__gmp_binary_plus149 static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z) 150 { mpq_set(q, r); mpz_addmul(mpq_numref(q), mpq_denref(q), z); } eval__gmp_binary_plus151 static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r) 152 { mpq_set(q, r); mpz_addmul(mpq_numref(q), mpq_denref(q), z); } 153 eval__gmp_binary_plus154 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h) 155 { mpf_add(f, g, h); } 156 eval__gmp_binary_plus157 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l) 158 { mpf_add_ui(f, g, l); } eval__gmp_binary_plus159 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g) 160 { mpf_add_ui(f, g, l); } eval__gmp_binary_plus161 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l) 162 { 163 if (l >= 0) 164 mpf_add_ui(f, g, l); 165 else 166 mpf_sub_ui(f, g, -l); 167 } eval__gmp_binary_plus168 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g) 169 { 170 if (l >= 0) 171 mpf_add_ui(f, g, l); 172 else 173 mpf_sub_ui(f, g, -l); 174 } eval__gmp_binary_plus175 static void eval(mpf_ptr f, mpf_srcptr g, double d) 176 { 177 mpf_t temp; 178 mpf_init2(temp, 8*sizeof(double)); 179 mpf_set_d(temp, d); 180 mpf_add(f, g, temp); 181 mpf_clear(temp); 182 } eval__gmp_binary_plus183 static void eval(mpf_ptr f, double d, mpf_srcptr g) 184 { 185 mpf_t temp; 186 mpf_init2(temp, 8*sizeof(double)); 187 mpf_set_d(temp, d); 188 mpf_add(f, temp, g); 189 mpf_clear(temp); 190 } 191 }; 192 193 struct __gmp_binary_minus 194 { eval__gmp_binary_minus195 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) 196 { mpz_sub(z, w, v); } 197 eval__gmp_binary_minus198 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) 199 { mpz_sub_ui(z, w, l); } eval__gmp_binary_minus200 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) 201 { mpz_ui_sub(z, l, w); } eval__gmp_binary_minus202 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) 203 { 204 if (l >= 0) 205 mpz_sub_ui(z, w, l); 206 else 207 mpz_add_ui(z, w, -l); 208 } eval__gmp_binary_minus209 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) 210 { 211 if (l >= 0) 212 mpz_ui_sub(z, l, w); 213 else 214 { 215 mpz_add_ui(z, w, -l); 216 mpz_neg(z, z); 217 } 218 } eval__gmp_binary_minus219 static void eval(mpz_ptr z, mpz_srcptr w, double d) 220 { 221 mpz_t temp; 222 mpz_init_set_d(temp, d); 223 mpz_sub(z, w, temp); 224 mpz_clear(temp); 225 } eval__gmp_binary_minus226 static void eval(mpz_ptr z, double d, mpz_srcptr w) 227 { 228 mpz_t temp; 229 mpz_init_set_d(temp, d); 230 mpz_sub(z, temp, w); 231 mpz_clear(temp); 232 } 233 eval__gmp_binary_minus234 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s) 235 { mpq_sub(q, r, s); } 236 eval__gmp_binary_minus237 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l) 238 { mpq_set(q, r); mpz_submul_ui(mpq_numref(q), mpq_denref(q), l); } eval__gmp_binary_minus239 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r) 240 { mpq_neg(q, r); mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); } eval__gmp_binary_minus241 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l) 242 { 243 mpq_set(q, r); 244 if (l >= 0) 245 mpz_submul_ui(mpq_numref(q), mpq_denref(q), l); 246 else 247 mpz_addmul_ui(mpq_numref(q), mpq_denref(q), -l); 248 } eval__gmp_binary_minus249 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r) 250 { 251 mpq_neg(q, r); 252 if (l >= 0) 253 mpz_addmul_ui(mpq_numref(q), mpq_denref(q), l); 254 else 255 mpz_submul_ui(mpq_numref(q), mpq_denref(q), -l); 256 } eval__gmp_binary_minus257 static void eval(mpq_ptr q, mpq_srcptr r, double d) 258 { 259 mpq_t temp; 260 mpq_init(temp); 261 mpq_set_d(temp, d); 262 mpq_sub(q, r, temp); 263 mpq_clear(temp); 264 } eval__gmp_binary_minus265 static void eval(mpq_ptr q, double d, mpq_srcptr r) 266 { 267 mpq_t temp; 268 mpq_init(temp); 269 mpq_set_d(temp, d); 270 mpq_sub(q, temp, r); 271 mpq_clear(temp); 272 } 273 eval__gmp_binary_minus274 static void eval(mpq_ptr q, mpq_srcptr r, mpz_srcptr z) 275 { mpq_set(q, r); mpz_submul(mpq_numref(q), mpq_denref(q), z); } eval__gmp_binary_minus276 static void eval(mpq_ptr q, mpz_srcptr z, mpq_srcptr r) 277 { mpq_neg(q, r); mpz_addmul(mpq_numref(q), mpq_denref(q), z); } 278 eval__gmp_binary_minus279 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h) 280 { mpf_sub(f, g, h); } 281 eval__gmp_binary_minus282 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l) 283 { mpf_sub_ui(f, g, l); } eval__gmp_binary_minus284 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g) 285 { mpf_ui_sub(f, l, g); } eval__gmp_binary_minus286 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l) 287 { 288 if (l >= 0) 289 mpf_sub_ui(f, g, l); 290 else 291 mpf_add_ui(f, g, -l); 292 } eval__gmp_binary_minus293 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g) 294 { 295 if (l >= 0) 296 mpf_sub_ui(f, g, l); 297 else 298 mpf_add_ui(f, g, -l); 299 mpf_neg(f, f); 300 } eval__gmp_binary_minus301 static void eval(mpf_ptr f, mpf_srcptr g, double d) 302 { 303 mpf_t temp; 304 mpf_init2(temp, 8*sizeof(double)); 305 mpf_set_d(temp, d); 306 mpf_sub(f, g, temp); 307 mpf_clear(temp); 308 } eval__gmp_binary_minus309 static void eval(mpf_ptr f, double d, mpf_srcptr g) 310 { 311 mpf_t temp; 312 mpf_init2(temp, 8*sizeof(double)); 313 mpf_set_d(temp, d); 314 mpf_sub(f, temp, g); 315 mpf_clear(temp); 316 } 317 }; 318 319 struct __gmp_binary_multiplies 320 { eval__gmp_binary_multiplies321 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) 322 { mpz_mul(z, w, v); } 323 eval__gmp_binary_multiplies324 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) 325 { mpz_mul_ui(z, w, l); } eval__gmp_binary_multiplies326 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) 327 { mpz_mul_ui(z, w, l); } eval__gmp_binary_multiplies328 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) 329 { mpz_mul_si (z, w, l); } eval__gmp_binary_multiplies330 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) 331 { mpz_mul_si (z, w, l); } eval__gmp_binary_multiplies332 static void eval(mpz_ptr z, mpz_srcptr w, double d) 333 { 334 mpz_t temp; 335 mpz_init_set_d(temp, d); 336 mpz_mul(z, w, temp); 337 mpz_clear(temp); 338 } eval__gmp_binary_multiplies339 static void eval(mpz_ptr z, double d, mpz_srcptr w) 340 { 341 mpz_t temp; 342 mpz_init_set_d(temp, d); 343 mpz_mul(z, temp, w); 344 mpz_clear(temp); 345 } 346 eval__gmp_binary_multiplies347 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s) 348 { mpq_mul(q, r, s); } 349 eval__gmp_binary_multiplies350 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l) 351 { 352 mpq_t temp; 353 mpq_init(temp); 354 mpq_set_ui(temp, l, 1); 355 mpq_mul(q, r, temp); 356 mpq_clear(temp); 357 } eval__gmp_binary_multiplies358 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r) 359 { 360 mpq_t temp; 361 mpq_init(temp); 362 mpq_set_ui(temp, l, 1); 363 mpq_mul(q, temp, r); 364 mpq_clear(temp); 365 } eval__gmp_binary_multiplies366 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l) 367 { 368 mpq_t temp; 369 mpq_init(temp); 370 mpq_set_si(temp, l, 1); 371 mpq_mul(q, r, temp); 372 mpq_clear(temp); 373 } eval__gmp_binary_multiplies374 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r) 375 { 376 mpq_t temp; 377 mpq_init(temp); 378 mpq_set_si(temp, l, 1); 379 mpq_mul(q, temp, r); 380 mpq_clear(temp); 381 } eval__gmp_binary_multiplies382 static void eval(mpq_ptr q, mpq_srcptr r, double d) 383 { 384 mpq_t temp; 385 mpq_init(temp); 386 mpq_set_d(temp, d); 387 mpq_mul(q, r, temp); 388 mpq_clear(temp); 389 } eval__gmp_binary_multiplies390 static void eval(mpq_ptr q, double d, mpq_srcptr r) 391 { 392 mpq_t temp; 393 mpq_init(temp); 394 mpq_set_d(temp, d); 395 mpq_mul(q, temp, r); 396 mpq_clear(temp); 397 } 398 eval__gmp_binary_multiplies399 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h) 400 { mpf_mul(f, g, h); } 401 eval__gmp_binary_multiplies402 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l) 403 { mpf_mul_ui(f, g, l); } eval__gmp_binary_multiplies404 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g) 405 { mpf_mul_ui(f, g, l); } eval__gmp_binary_multiplies406 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l) 407 { 408 if (l >= 0) 409 mpf_mul_ui(f, g, l); 410 else 411 { 412 mpf_mul_ui(f, g, -l); 413 mpf_neg(f, f); 414 } 415 } eval__gmp_binary_multiplies416 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g) 417 { 418 if (l >= 0) 419 mpf_mul_ui(f, g, l); 420 else 421 { 422 mpf_mul_ui(f, g, -l); 423 mpf_neg(f, f); 424 } 425 } eval__gmp_binary_multiplies426 static void eval(mpf_ptr f, mpf_srcptr g, double d) 427 { 428 mpf_t temp; 429 mpf_init2(temp, 8*sizeof(double)); 430 mpf_set_d(temp, d); 431 mpf_mul(f, g, temp); 432 mpf_clear(temp); 433 } eval__gmp_binary_multiplies434 static void eval(mpf_ptr f, double d, mpf_srcptr g) 435 { 436 mpf_t temp; 437 mpf_init2(temp, 8*sizeof(double)); 438 mpf_set_d(temp, d); 439 mpf_mul(f, temp, g); 440 mpf_clear(temp); 441 } 442 }; 443 444 struct __gmp_binary_divides 445 { eval__gmp_binary_divides446 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) 447 { mpz_tdiv_q(z, w, v); } 448 eval__gmp_binary_divides449 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) 450 { mpz_tdiv_q_ui(z, w, l); } eval__gmp_binary_divides451 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) 452 { 453 if (mpz_sgn(w) >= 0) 454 { 455 if (mpz_fits_ulong_p(w)) 456 mpz_set_ui(z, l / mpz_get_ui(w)); 457 else 458 mpz_set_ui(z, 0); 459 } 460 else 461 { 462 mpz_neg(z, w); 463 if (mpz_fits_ulong_p(z)) 464 { 465 mpz_set_ui(z, l / mpz_get_ui(z)); 466 mpz_neg(z, z); 467 } 468 else 469 mpz_set_ui(z, 0); 470 } 471 } eval__gmp_binary_divides472 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) 473 { 474 if (l >= 0) 475 mpz_tdiv_q_ui(z, w, l); 476 else 477 { 478 mpz_tdiv_q_ui(z, w, -l); 479 mpz_neg(z, z); 480 } 481 } eval__gmp_binary_divides482 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) 483 { 484 if (mpz_fits_slong_p(w)) 485 mpz_set_si(z, l / mpz_get_si(w)); 486 else 487 { 488 /* if w is bigger than a long then the quotient must be zero, unless 489 l==LONG_MIN and w==-LONG_MIN in which case the quotient is -1 */ 490 mpz_set_si (z, (mpz_cmpabs_ui (w, (l >= 0 ? l : -l)) == 0 ? -1 : 0)); 491 } 492 } eval__gmp_binary_divides493 static void eval(mpz_ptr z, mpz_srcptr w, double d) 494 { 495 mpz_t temp; 496 mpz_init_set_d(temp, d); 497 mpz_tdiv_q(z, w, temp); 498 mpz_clear(temp); 499 } eval__gmp_binary_divides500 static void eval(mpz_ptr z, double d, mpz_srcptr w) 501 { 502 mpz_t temp; 503 mpz_init_set_d(temp, d); 504 mpz_tdiv_q(z, temp, w); 505 mpz_clear(temp); 506 } 507 eval__gmp_binary_divides508 static void eval(mpq_ptr q, mpq_srcptr r, mpq_srcptr s) 509 { mpq_div(q, r, s); } 510 eval__gmp_binary_divides511 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l) 512 { 513 mpq_t temp; 514 mpq_init(temp); 515 mpq_set_ui(temp, l, 1); 516 mpq_div(q, r, temp); 517 mpq_clear(temp); 518 } eval__gmp_binary_divides519 static void eval(mpq_ptr q, unsigned long int l, mpq_srcptr r) 520 { 521 mpq_t temp; 522 mpq_init(temp); 523 mpq_set_ui(temp, l, 1); 524 mpq_div(q, temp, r); 525 mpq_clear(temp); 526 } eval__gmp_binary_divides527 static void eval(mpq_ptr q, mpq_srcptr r, signed long int l) 528 { 529 mpq_t temp; 530 mpq_init(temp); 531 mpq_set_si(temp, l, 1); 532 mpq_div(q, r, temp); 533 mpq_clear(temp); 534 } eval__gmp_binary_divides535 static void eval(mpq_ptr q, signed long int l, mpq_srcptr r) 536 { 537 mpq_t temp; 538 mpq_init(temp); 539 mpq_set_si(temp, l, 1); 540 mpq_div(q, temp, r); 541 mpq_clear(temp); 542 } eval__gmp_binary_divides543 static void eval(mpq_ptr q, mpq_srcptr r, double d) 544 { 545 mpq_t temp; 546 mpq_init(temp); 547 mpq_set_d(temp, d); 548 mpq_div(q, r, temp); 549 mpq_clear(temp); 550 } eval__gmp_binary_divides551 static void eval(mpq_ptr q, double d, mpq_srcptr r) 552 { 553 mpq_t temp; 554 mpq_init(temp); 555 mpq_set_d(temp, d); 556 mpq_div(q, temp, r); 557 mpq_clear(temp); 558 } 559 eval__gmp_binary_divides560 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h) 561 { mpf_div(f, g, h); } 562 eval__gmp_binary_divides563 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l) 564 { mpf_div_ui(f, g, l); } eval__gmp_binary_divides565 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g) 566 { mpf_ui_div(f, l, g); } eval__gmp_binary_divides567 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l) 568 { 569 if (l >= 0) 570 mpf_div_ui(f, g, l); 571 else 572 { 573 mpf_div_ui(f, g, -l); 574 mpf_neg(f, f); 575 } 576 } eval__gmp_binary_divides577 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g) 578 { 579 if (l >= 0) 580 mpf_ui_div(f, l, g); 581 else 582 { 583 mpf_ui_div(f, -l, g); 584 mpf_neg(f, f); 585 } 586 } eval__gmp_binary_divides587 static void eval(mpf_ptr f, mpf_srcptr g, double d) 588 { 589 mpf_t temp; 590 mpf_init2(temp, 8*sizeof(double)); 591 mpf_set_d(temp, d); 592 mpf_div(f, g, temp); 593 mpf_clear(temp); 594 } eval__gmp_binary_divides595 static void eval(mpf_ptr f, double d, mpf_srcptr g) 596 { 597 mpf_t temp; 598 mpf_init2(temp, 8*sizeof(double)); 599 mpf_set_d(temp, d); 600 mpf_div(f, temp, g); 601 mpf_clear(temp); 602 } 603 }; 604 605 struct __gmp_binary_modulus 606 { eval__gmp_binary_modulus607 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) 608 { mpz_tdiv_r(z, w, v); } 609 eval__gmp_binary_modulus610 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) 611 { mpz_tdiv_r_ui(z, w, l); } eval__gmp_binary_modulus612 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) 613 { 614 if (mpz_sgn(w) >= 0) 615 { 616 if (mpz_fits_ulong_p(w)) 617 mpz_set_ui(z, l % mpz_get_ui(w)); 618 else 619 mpz_set_ui(z, l); 620 } 621 else 622 { 623 mpz_neg(z, w); 624 if (mpz_fits_ulong_p(z)) 625 mpz_set_ui(z, l % mpz_get_ui(z)); 626 else 627 mpz_set_ui(z, l); 628 } 629 } eval__gmp_binary_modulus630 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) 631 { 632 mpz_tdiv_r_ui (z, w, (l >= 0 ? l : -l)); 633 } eval__gmp_binary_modulus634 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) 635 { 636 if (mpz_fits_slong_p(w)) 637 mpz_set_si(z, l % mpz_get_si(w)); 638 else 639 { 640 /* if w is bigger than a long then the remainder is l unchanged, 641 unless l==LONG_MIN and w==-LONG_MIN in which case it's 0 */ 642 mpz_set_si (z, mpz_cmpabs_ui (w, (l >= 0 ? l : -l)) == 0 ? 0 : l); 643 } 644 } eval__gmp_binary_modulus645 static void eval(mpz_ptr z, mpz_srcptr w, double d) 646 { 647 mpz_t temp; 648 mpz_init_set_d(temp, d); 649 mpz_tdiv_r(z, w, temp); 650 mpz_clear(temp); 651 } eval__gmp_binary_modulus652 static void eval(mpz_ptr z, double d, mpz_srcptr w) 653 { 654 mpz_t temp; 655 mpz_init_set_d(temp, d); 656 mpz_tdiv_r(z, temp, w); 657 mpz_clear(temp); 658 } 659 }; 660 661 // Max allocations for plain types when converted to mpz_t 662 #define __GMP_DBL_LIMBS (2 + DBL_MAX_EXP / GMP_NUMB_BITS) 663 #define __GMP_ULI_LIMBS (1 + (8 * sizeof (long) - 1) / GMP_NUMB_BITS) 664 665 #define __GMPXX_TMP_UI \ 666 mpz_t temp; \ 667 mp_limb_t limbs[__GMP_ULI_LIMBS]; \ 668 temp->_mp_d = limbs; \ 669 temp->_mp_alloc = __GMP_ULI_LIMBS; \ 670 mpz_set_ui (temp, l) 671 #define __GMPXX_TMP_SI \ 672 mpz_t temp; \ 673 mp_limb_t limbs[__GMP_ULI_LIMBS]; \ 674 temp->_mp_d = limbs; \ 675 temp->_mp_alloc = __GMP_ULI_LIMBS; \ 676 mpz_set_si (temp, l) 677 #define __GMPXX_TMP_D \ 678 mpz_t temp; \ 679 mp_limb_t limbs[__GMP_DBL_LIMBS]; \ 680 temp->_mp_d = limbs; \ 681 temp->_mp_alloc = __GMP_DBL_LIMBS; \ 682 mpz_set_d (temp, d) 683 684 struct __gmp_binary_and 685 { eval__gmp_binary_and686 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) 687 { mpz_and(z, w, v); } 688 eval__gmp_binary_and689 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) 690 { __GMPXX_TMP_UI; mpz_and (z, w, temp); } eval__gmp_binary_and691 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) 692 { __GMPXX_TMP_UI; mpz_and (z, w, temp); } eval__gmp_binary_and693 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) 694 { __GMPXX_TMP_SI; mpz_and (z, w, temp); } eval__gmp_binary_and695 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) 696 { __GMPXX_TMP_SI; mpz_and (z, w, temp); } eval__gmp_binary_and697 static void eval(mpz_ptr z, mpz_srcptr w, double d) 698 { __GMPXX_TMP_D; mpz_and (z, w, temp); } eval__gmp_binary_and699 static void eval(mpz_ptr z, double d, mpz_srcptr w) 700 { __GMPXX_TMP_D; mpz_and (z, w, temp); } 701 }; 702 703 struct __gmp_binary_ior 704 { eval__gmp_binary_ior705 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) 706 { mpz_ior(z, w, v); } eval__gmp_binary_ior707 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) 708 { __GMPXX_TMP_UI; mpz_ior (z, w, temp); } eval__gmp_binary_ior709 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) 710 { __GMPXX_TMP_UI; mpz_ior (z, w, temp); } eval__gmp_binary_ior711 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) 712 { __GMPXX_TMP_SI; mpz_ior (z, w, temp); } eval__gmp_binary_ior713 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) 714 { __GMPXX_TMP_SI; mpz_ior (z, w, temp); } eval__gmp_binary_ior715 static void eval(mpz_ptr z, mpz_srcptr w, double d) 716 { __GMPXX_TMP_D; mpz_ior (z, w, temp); } eval__gmp_binary_ior717 static void eval(mpz_ptr z, double d, mpz_srcptr w) 718 { __GMPXX_TMP_D; mpz_ior (z, w, temp); } 719 }; 720 721 struct __gmp_binary_xor 722 { eval__gmp_binary_xor723 static void eval(mpz_ptr z, mpz_srcptr w, mpz_srcptr v) 724 { mpz_xor(z, w, v); } eval__gmp_binary_xor725 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) 726 { __GMPXX_TMP_UI; mpz_xor (z, w, temp); } eval__gmp_binary_xor727 static void eval(mpz_ptr z, unsigned long int l, mpz_srcptr w) 728 { __GMPXX_TMP_UI; mpz_xor (z, w, temp); } eval__gmp_binary_xor729 static void eval(mpz_ptr z, mpz_srcptr w, signed long int l) 730 { __GMPXX_TMP_SI; mpz_xor (z, w, temp); } eval__gmp_binary_xor731 static void eval(mpz_ptr z, signed long int l, mpz_srcptr w) 732 { __GMPXX_TMP_SI; mpz_xor (z, w, temp); } eval__gmp_binary_xor733 static void eval(mpz_ptr z, mpz_srcptr w, double d) 734 { __GMPXX_TMP_D; mpz_xor (z, w, temp); } eval__gmp_binary_xor735 static void eval(mpz_ptr z, double d, mpz_srcptr w) 736 { __GMPXX_TMP_D; mpz_xor (z, w, temp); } 737 }; 738 739 struct __gmp_binary_lshift 740 { eval__gmp_binary_lshift741 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) 742 { mpz_mul_2exp(z, w, l); } eval__gmp_binary_lshift743 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l) 744 { mpq_mul_2exp(q, r, l); } eval__gmp_binary_lshift745 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l) 746 { mpf_mul_2exp(f, g, l); } 747 }; 748 749 struct __gmp_binary_rshift 750 { eval__gmp_binary_rshift751 static void eval(mpz_ptr z, mpz_srcptr w, unsigned long int l) 752 { mpz_fdiv_q_2exp(z, w, l); } eval__gmp_binary_rshift753 static void eval(mpq_ptr q, mpq_srcptr r, unsigned long int l) 754 { mpq_div_2exp(q, r, l); } eval__gmp_binary_rshift755 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l) 756 { mpf_div_2exp(f, g, l); } 757 }; 758 759 struct __gmp_binary_equal 760 { eval__gmp_binary_equal761 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) == 0; } 762 eval__gmp_binary_equal763 static bool eval(mpz_srcptr z, unsigned long int l) 764 { return mpz_cmp_ui(z, l) == 0; } eval__gmp_binary_equal765 static bool eval(unsigned long int l, mpz_srcptr z) 766 { return mpz_cmp_ui(z, l) == 0; } eval__gmp_binary_equal767 static bool eval(mpz_srcptr z, signed long int l) 768 { return mpz_cmp_si(z, l) == 0; } eval__gmp_binary_equal769 static bool eval(signed long int l, mpz_srcptr z) 770 { return mpz_cmp_si(z, l) == 0; } eval__gmp_binary_equal771 static bool eval(mpz_srcptr z, double d) 772 { return mpz_cmp_d(z, d) == 0; } eval__gmp_binary_equal773 static bool eval(double d, mpz_srcptr z) 774 { return mpz_cmp_d(z, d) == 0; } 775 eval__gmp_binary_equal776 static bool eval(mpq_srcptr q, mpq_srcptr r) 777 { return mpq_equal(q, r) != 0; } 778 eval__gmp_binary_equal779 static bool eval(mpq_srcptr q, unsigned long int l) 780 { return mpq_cmp_ui(q, l, 1) == 0; } eval__gmp_binary_equal781 static bool eval(unsigned long int l, mpq_srcptr q) 782 { return mpq_cmp_ui(q, l, 1) == 0; } eval__gmp_binary_equal783 static bool eval(mpq_srcptr q, signed long int l) 784 { return mpq_cmp_si(q, l, 1) == 0; } eval__gmp_binary_equal785 static bool eval(signed long int l, mpq_srcptr q) 786 { return mpq_cmp_si(q, l, 1) == 0; } eval__gmp_binary_equal787 static bool eval(mpq_srcptr q, double d) 788 { 789 bool b; 790 mpq_t temp; 791 mpq_init(temp); 792 mpq_set_d(temp, d); 793 b = (mpq_equal(q, temp) != 0); 794 mpq_clear(temp); 795 return b; 796 } eval__gmp_binary_equal797 static bool eval(double d, mpq_srcptr q) 798 { 799 bool b; 800 mpq_t temp; 801 mpq_init(temp); 802 mpq_set_d(temp, d); 803 b = (mpq_equal(temp, q) != 0); 804 mpq_clear(temp); 805 return b; 806 } 807 eval__gmp_binary_equal808 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) == 0; } 809 eval__gmp_binary_equal810 static bool eval(mpf_srcptr f, unsigned long int l) 811 { return mpf_cmp_ui(f, l) == 0; } eval__gmp_binary_equal812 static bool eval(unsigned long int l, mpf_srcptr f) 813 { return mpf_cmp_ui(f, l) == 0; } eval__gmp_binary_equal814 static bool eval(mpf_srcptr f, signed long int l) 815 { return mpf_cmp_si(f, l) == 0; } eval__gmp_binary_equal816 static bool eval(signed long int l, mpf_srcptr f) 817 { return mpf_cmp_si(f, l) == 0; } eval__gmp_binary_equal818 static bool eval(mpf_srcptr f, double d) 819 { return mpf_cmp_d(f, d) == 0; } eval__gmp_binary_equal820 static bool eval(double d, mpf_srcptr f) 821 { return mpf_cmp_d(f, d) == 0; } 822 }; 823 824 struct __gmp_binary_not_equal 825 { eval__gmp_binary_not_equal826 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) != 0; } 827 eval__gmp_binary_not_equal828 static bool eval(mpz_srcptr z, unsigned long int l) 829 { return mpz_cmp_ui(z, l) != 0; } eval__gmp_binary_not_equal830 static bool eval(unsigned long int l, mpz_srcptr z) 831 { return mpz_cmp_ui(z, l) != 0; } eval__gmp_binary_not_equal832 static bool eval(mpz_srcptr z, signed long int l) 833 { return mpz_cmp_si(z, l) != 0; } eval__gmp_binary_not_equal834 static bool eval(signed long int l, mpz_srcptr z) 835 { return mpz_cmp_si(z, l) != 0; } eval__gmp_binary_not_equal836 static bool eval(mpz_srcptr z, double d) 837 { return mpz_cmp_d(z, d) != 0; } eval__gmp_binary_not_equal838 static bool eval(double d, mpz_srcptr z) 839 { return mpz_cmp_d(z, d) != 0; } 840 eval__gmp_binary_not_equal841 static bool eval(mpq_srcptr q, mpq_srcptr r) 842 { return mpq_equal(q, r) == 0; } 843 eval__gmp_binary_not_equal844 static bool eval(mpq_srcptr q, unsigned long int l) 845 { return mpq_cmp_ui(q, l, 1) != 0; } eval__gmp_binary_not_equal846 static bool eval(unsigned long int l, mpq_srcptr q) 847 { return mpq_cmp_ui(q, l, 1) != 0; } eval__gmp_binary_not_equal848 static bool eval(mpq_srcptr q, signed long int l) 849 { return mpq_cmp_si(q, l, 1) != 0; } eval__gmp_binary_not_equal850 static bool eval(signed long int l, mpq_srcptr q) 851 { return mpq_cmp_si(q, l, 1) != 0; } eval__gmp_binary_not_equal852 static bool eval(mpq_srcptr q, double d) 853 { 854 bool b; 855 mpq_t temp; 856 mpq_init(temp); 857 mpq_set_d(temp, d); 858 b = (mpq_equal(q, temp) == 0); 859 mpq_clear(temp); 860 return b; 861 } eval__gmp_binary_not_equal862 static bool eval(double d, mpq_srcptr q) 863 { 864 bool b; 865 mpq_t temp; 866 mpq_init(temp); 867 mpq_set_d(temp, d); 868 b = (mpq_equal(temp, q) == 0); 869 mpq_clear(temp); 870 return b; 871 } 872 eval__gmp_binary_not_equal873 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) != 0; } 874 eval__gmp_binary_not_equal875 static bool eval(mpf_srcptr f, unsigned long int l) 876 { return mpf_cmp_ui(f, l) != 0; } eval__gmp_binary_not_equal877 static bool eval(unsigned long int l, mpf_srcptr f) 878 { return mpf_cmp_ui(f, l) != 0; } eval__gmp_binary_not_equal879 static bool eval(mpf_srcptr f, signed long int l) 880 { return mpf_cmp_si(f, l) != 0; } eval__gmp_binary_not_equal881 static bool eval(signed long int l, mpf_srcptr f) 882 { return mpf_cmp_si(f, l) != 0; } eval__gmp_binary_not_equal883 static bool eval(mpf_srcptr f, double d) 884 { return mpf_cmp_d(f, d) != 0; } eval__gmp_binary_not_equal885 static bool eval(double d, mpf_srcptr f) 886 { return mpf_cmp_d(f, d) != 0; } 887 }; 888 889 struct __gmp_binary_less 890 { eval__gmp_binary_less891 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) < 0; } 892 eval__gmp_binary_less893 static bool eval(mpz_srcptr z, unsigned long int l) 894 { return mpz_cmp_ui(z, l) < 0; } eval__gmp_binary_less895 static bool eval(unsigned long int l, mpz_srcptr z) 896 { return mpz_cmp_ui(z, l) > 0; } eval__gmp_binary_less897 static bool eval(mpz_srcptr z, signed long int l) 898 { return mpz_cmp_si(z, l) < 0; } eval__gmp_binary_less899 static bool eval(signed long int l, mpz_srcptr z) 900 { return mpz_cmp_si(z, l) > 0; } eval__gmp_binary_less901 static bool eval(mpz_srcptr z, double d) 902 { return mpz_cmp_d(z, d) < 0; } eval__gmp_binary_less903 static bool eval(double d, mpz_srcptr z) 904 { return mpz_cmp_d(z, d) > 0; } 905 eval__gmp_binary_less906 static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) < 0; } 907 eval__gmp_binary_less908 static bool eval(mpq_srcptr q, unsigned long int l) 909 { return mpq_cmp_ui(q, l, 1) < 0; } eval__gmp_binary_less910 static bool eval(unsigned long int l, mpq_srcptr q) 911 { return mpq_cmp_ui(q, l, 1) > 0; } eval__gmp_binary_less912 static bool eval(mpq_srcptr q, signed long int l) 913 { return mpq_cmp_si(q, l, 1) < 0; } eval__gmp_binary_less914 static bool eval(signed long int l, mpq_srcptr q) 915 { return mpq_cmp_si(q, l, 1) > 0; } eval__gmp_binary_less916 static bool eval(mpq_srcptr q, double d) 917 { 918 bool b; 919 mpq_t temp; 920 mpq_init(temp); 921 mpq_set_d(temp, d); 922 b = (mpq_cmp(q, temp) < 0); 923 mpq_clear(temp); 924 return b; 925 } eval__gmp_binary_less926 static bool eval(double d, mpq_srcptr q) 927 { 928 bool b; 929 mpq_t temp; 930 mpq_init(temp); 931 mpq_set_d(temp, d); 932 b = (mpq_cmp(temp, q) < 0); 933 mpq_clear(temp); 934 return b; 935 } 936 eval__gmp_binary_less937 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) < 0; } 938 eval__gmp_binary_less939 static bool eval(mpf_srcptr f, unsigned long int l) 940 { return mpf_cmp_ui(f, l) < 0; } eval__gmp_binary_less941 static bool eval(unsigned long int l, mpf_srcptr f) 942 { return mpf_cmp_ui(f, l) > 0; } eval__gmp_binary_less943 static bool eval(mpf_srcptr f, signed long int l) 944 { return mpf_cmp_si(f, l) < 0; } eval__gmp_binary_less945 static bool eval(signed long int l, mpf_srcptr f) 946 { return mpf_cmp_si(f, l) > 0; } eval__gmp_binary_less947 static bool eval(mpf_srcptr f, double d) 948 { return mpf_cmp_d(f, d) < 0; } eval__gmp_binary_less949 static bool eval(double d, mpf_srcptr f) 950 { return mpf_cmp_d(f, d) > 0; } 951 }; 952 953 struct __gmp_binary_less_equal 954 { eval__gmp_binary_less_equal955 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) <= 0; } 956 eval__gmp_binary_less_equal957 static bool eval(mpz_srcptr z, unsigned long int l) 958 { return mpz_cmp_ui(z, l) <= 0; } eval__gmp_binary_less_equal959 static bool eval(unsigned long int l, mpz_srcptr z) 960 { return mpz_cmp_ui(z, l) >= 0; } eval__gmp_binary_less_equal961 static bool eval(mpz_srcptr z, signed long int l) 962 { return mpz_cmp_si(z, l) <= 0; } eval__gmp_binary_less_equal963 static bool eval(signed long int l, mpz_srcptr z) 964 { return mpz_cmp_si(z, l) >= 0; } eval__gmp_binary_less_equal965 static bool eval(mpz_srcptr z, double d) 966 { return mpz_cmp_d(z, d) <= 0; } eval__gmp_binary_less_equal967 static bool eval(double d, mpz_srcptr z) 968 { return mpz_cmp_d(z, d) >= 0; } 969 eval__gmp_binary_less_equal970 static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) <= 0; } 971 eval__gmp_binary_less_equal972 static bool eval(mpq_srcptr q, unsigned long int l) 973 { return mpq_cmp_ui(q, l, 1) <= 0; } eval__gmp_binary_less_equal974 static bool eval(unsigned long int l, mpq_srcptr q) 975 { return mpq_cmp_ui(q, l, 1) >= 0; } eval__gmp_binary_less_equal976 static bool eval(mpq_srcptr q, signed long int l) 977 { return mpq_cmp_si(q, l, 1) <= 0; } eval__gmp_binary_less_equal978 static bool eval(signed long int l, mpq_srcptr q) 979 { return mpq_cmp_si(q, l, 1) >= 0; } eval__gmp_binary_less_equal980 static bool eval(mpq_srcptr q, double d) 981 { 982 bool b; 983 mpq_t temp; 984 mpq_init(temp); 985 mpq_set_d(temp, d); 986 b = (mpq_cmp(q, temp) <= 0); 987 mpq_clear(temp); 988 return b; 989 } eval__gmp_binary_less_equal990 static bool eval(double d, mpq_srcptr q) 991 { 992 bool b; 993 mpq_t temp; 994 mpq_init(temp); 995 mpq_set_d(temp, d); 996 b = (mpq_cmp(temp, q) <= 0); 997 mpq_clear(temp); 998 return b; 999 } 1000 eval__gmp_binary_less_equal1001 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) <= 0; } 1002 eval__gmp_binary_less_equal1003 static bool eval(mpf_srcptr f, unsigned long int l) 1004 { return mpf_cmp_ui(f, l) <= 0; } eval__gmp_binary_less_equal1005 static bool eval(unsigned long int l, mpf_srcptr f) 1006 { return mpf_cmp_ui(f, l) >= 0; } eval__gmp_binary_less_equal1007 static bool eval(mpf_srcptr f, signed long int l) 1008 { return mpf_cmp_si(f, l) <= 0; } eval__gmp_binary_less_equal1009 static bool eval(signed long int l, mpf_srcptr f) 1010 { return mpf_cmp_si(f, l) >= 0; } eval__gmp_binary_less_equal1011 static bool eval(mpf_srcptr f, double d) 1012 { return mpf_cmp_d(f, d) <= 0; } eval__gmp_binary_less_equal1013 static bool eval(double d, mpf_srcptr f) 1014 { return mpf_cmp_d(f, d) >= 0; } 1015 }; 1016 1017 struct __gmp_binary_greater 1018 { eval__gmp_binary_greater1019 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) > 0; } 1020 eval__gmp_binary_greater1021 static bool eval(mpz_srcptr z, unsigned long int l) 1022 { return mpz_cmp_ui(z, l) > 0; } eval__gmp_binary_greater1023 static bool eval(unsigned long int l, mpz_srcptr z) 1024 { return mpz_cmp_ui(z, l) < 0; } eval__gmp_binary_greater1025 static bool eval(mpz_srcptr z, signed long int l) 1026 { return mpz_cmp_si(z, l) > 0; } eval__gmp_binary_greater1027 static bool eval(signed long int l, mpz_srcptr z) 1028 { return mpz_cmp_si(z, l) < 0; } eval__gmp_binary_greater1029 static bool eval(mpz_srcptr z, double d) 1030 { return mpz_cmp_d(z, d) > 0; } eval__gmp_binary_greater1031 static bool eval(double d, mpz_srcptr z) 1032 { return mpz_cmp_d(z, d) < 0; } 1033 eval__gmp_binary_greater1034 static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) > 0; } 1035 eval__gmp_binary_greater1036 static bool eval(mpq_srcptr q, unsigned long int l) 1037 { return mpq_cmp_ui(q, l, 1) > 0; } eval__gmp_binary_greater1038 static bool eval(unsigned long int l, mpq_srcptr q) 1039 { return mpq_cmp_ui(q, l, 1) < 0; } eval__gmp_binary_greater1040 static bool eval(mpq_srcptr q, signed long int l) 1041 { return mpq_cmp_si(q, l, 1) > 0; } eval__gmp_binary_greater1042 static bool eval(signed long int l, mpq_srcptr q) 1043 { return mpq_cmp_si(q, l, 1) < 0; } eval__gmp_binary_greater1044 static bool eval(mpq_srcptr q, double d) 1045 { 1046 bool b; 1047 mpq_t temp; 1048 mpq_init(temp); 1049 mpq_set_d(temp, d); 1050 b = (mpq_cmp(q, temp) > 0); 1051 mpq_clear(temp); 1052 return b; 1053 } eval__gmp_binary_greater1054 static bool eval(double d, mpq_srcptr q) 1055 { 1056 bool b; 1057 mpq_t temp; 1058 mpq_init(temp); 1059 mpq_set_d(temp, d); 1060 b = (mpq_cmp(temp, q) > 0); 1061 mpq_clear(temp); 1062 return b; 1063 } 1064 eval__gmp_binary_greater1065 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) > 0; } 1066 eval__gmp_binary_greater1067 static bool eval(mpf_srcptr f, unsigned long int l) 1068 { return mpf_cmp_ui(f, l) > 0; } eval__gmp_binary_greater1069 static bool eval(unsigned long int l, mpf_srcptr f) 1070 { return mpf_cmp_ui(f, l) < 0; } eval__gmp_binary_greater1071 static bool eval(mpf_srcptr f, signed long int l) 1072 { return mpf_cmp_si(f, l) > 0; } eval__gmp_binary_greater1073 static bool eval(signed long int l, mpf_srcptr f) 1074 { return mpf_cmp_si(f, l) < 0; } eval__gmp_binary_greater1075 static bool eval(mpf_srcptr f, double d) 1076 { return mpf_cmp_d(f, d) > 0; } eval__gmp_binary_greater1077 static bool eval(double d, mpf_srcptr f) 1078 { return mpf_cmp_d(f, d) < 0; } 1079 }; 1080 1081 struct __gmp_binary_greater_equal 1082 { eval__gmp_binary_greater_equal1083 static bool eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w) >= 0; } 1084 eval__gmp_binary_greater_equal1085 static bool eval(mpz_srcptr z, unsigned long int l) 1086 { return mpz_cmp_ui(z, l) >= 0; } eval__gmp_binary_greater_equal1087 static bool eval(unsigned long int l, mpz_srcptr z) 1088 { return mpz_cmp_ui(z, l) <= 0; } eval__gmp_binary_greater_equal1089 static bool eval(mpz_srcptr z, signed long int l) 1090 { return mpz_cmp_si(z, l) >= 0; } eval__gmp_binary_greater_equal1091 static bool eval(signed long int l, mpz_srcptr z) 1092 { return mpz_cmp_si(z, l) <= 0; } eval__gmp_binary_greater_equal1093 static bool eval(mpz_srcptr z, double d) 1094 { return mpz_cmp_d(z, d) >= 0; } eval__gmp_binary_greater_equal1095 static bool eval(double d, mpz_srcptr z) 1096 { return mpz_cmp_d(z, d) <= 0; } 1097 eval__gmp_binary_greater_equal1098 static bool eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r) >= 0; } 1099 eval__gmp_binary_greater_equal1100 static bool eval(mpq_srcptr q, unsigned long int l) 1101 { return mpq_cmp_ui(q, l, 1) >= 0; } eval__gmp_binary_greater_equal1102 static bool eval(unsigned long int l, mpq_srcptr q) 1103 { return mpq_cmp_ui(q, l, 1) <= 0; } eval__gmp_binary_greater_equal1104 static bool eval(mpq_srcptr q, signed long int l) 1105 { return mpq_cmp_si(q, l, 1) >= 0; } eval__gmp_binary_greater_equal1106 static bool eval(signed long int l, mpq_srcptr q) 1107 { return mpq_cmp_si(q, l, 1) <= 0; } eval__gmp_binary_greater_equal1108 static bool eval(mpq_srcptr q, double d) 1109 { 1110 bool b; 1111 mpq_t temp; 1112 mpq_init(temp); 1113 mpq_set_d(temp, d); 1114 b = (mpq_cmp(q, temp) >= 0); 1115 mpq_clear(temp); 1116 return b; 1117 } eval__gmp_binary_greater_equal1118 static bool eval(double d, mpq_srcptr q) 1119 { 1120 bool b; 1121 mpq_t temp; 1122 mpq_init(temp); 1123 mpq_set_d(temp, d); 1124 b = (mpq_cmp(temp, q) >= 0); 1125 mpq_clear(temp); 1126 return b; 1127 } 1128 eval__gmp_binary_greater_equal1129 static bool eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g) >= 0; } 1130 eval__gmp_binary_greater_equal1131 static bool eval(mpf_srcptr f, unsigned long int l) 1132 { return mpf_cmp_ui(f, l) >= 0; } eval__gmp_binary_greater_equal1133 static bool eval(unsigned long int l, mpf_srcptr f) 1134 { return mpf_cmp_ui(f, l) <= 0; } eval__gmp_binary_greater_equal1135 static bool eval(mpf_srcptr f, signed long int l) 1136 { return mpf_cmp_si(f, l) >= 0; } eval__gmp_binary_greater_equal1137 static bool eval(signed long int l, mpf_srcptr f) 1138 { return mpf_cmp_si(f, l) <= 0; } eval__gmp_binary_greater_equal1139 static bool eval(mpf_srcptr f, double d) 1140 { return mpf_cmp_d(f, d) >= 0; } eval__gmp_binary_greater_equal1141 static bool eval(double d, mpf_srcptr f) 1142 { return mpf_cmp_d(f, d) <= 0; } 1143 }; 1144 1145 struct __gmp_unary_increment 1146 { eval__gmp_unary_increment1147 static void eval(mpz_ptr z) { mpz_add_ui(z, z, 1); } eval__gmp_unary_increment1148 static void eval(mpq_ptr q) 1149 { mpz_add(mpq_numref(q), mpq_numref(q), mpq_denref(q)); } eval__gmp_unary_increment1150 static void eval(mpf_ptr f) { mpf_add_ui(f, f, 1); } 1151 }; 1152 1153 struct __gmp_unary_decrement 1154 { eval__gmp_unary_decrement1155 static void eval(mpz_ptr z) { mpz_sub_ui(z, z, 1); } eval__gmp_unary_decrement1156 static void eval(mpq_ptr q) 1157 { mpz_sub(mpq_numref(q), mpq_numref(q), mpq_denref(q)); } eval__gmp_unary_decrement1158 static void eval(mpf_ptr f) { mpf_sub_ui(f, f, 1); } 1159 }; 1160 1161 struct __gmp_abs_function 1162 { eval__gmp_abs_function1163 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_abs(z, w); } eval__gmp_abs_function1164 static void eval(mpq_ptr q, mpq_srcptr r) { mpq_abs(q, r); } eval__gmp_abs_function1165 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_abs(f, g); } 1166 }; 1167 1168 struct __gmp_trunc_function 1169 { eval__gmp_trunc_function1170 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_trunc(f, g); } 1171 }; 1172 1173 struct __gmp_floor_function 1174 { eval__gmp_floor_function1175 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_floor(f, g); } 1176 }; 1177 1178 struct __gmp_ceil_function 1179 { eval__gmp_ceil_function1180 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_ceil(f, g); } 1181 }; 1182 1183 struct __gmp_sqrt_function 1184 { eval__gmp_sqrt_function1185 static void eval(mpz_ptr z, mpz_srcptr w) { mpz_sqrt(z, w); } eval__gmp_sqrt_function1186 static void eval(mpf_ptr f, mpf_srcptr g) { mpf_sqrt(f, g); } 1187 }; 1188 1189 struct __gmp_hypot_function 1190 { eval__gmp_hypot_function1191 static void eval(mpf_ptr f, mpf_srcptr g, mpf_srcptr h) 1192 { 1193 mpf_t temp; 1194 mpf_init2(temp, mpf_get_prec(f)); 1195 mpf_mul(temp, g, g); 1196 mpf_mul(f, h, h); 1197 mpf_add(f, f, temp); 1198 mpf_sqrt(f, f); 1199 mpf_clear(temp); 1200 } 1201 eval__gmp_hypot_function1202 static void eval(mpf_ptr f, mpf_srcptr g, unsigned long int l) 1203 { 1204 mpf_t temp; 1205 mpf_init2(temp, mpf_get_prec(f)); 1206 mpf_mul(temp, g, g); 1207 mpf_set_ui(f, l); 1208 mpf_mul(f, f, f); 1209 mpf_add(f, f, temp); 1210 mpf_sqrt(f, f); 1211 mpf_clear(temp); 1212 } eval__gmp_hypot_function1213 static void eval(mpf_ptr f, unsigned long int l, mpf_srcptr g) 1214 { 1215 mpf_t temp; 1216 mpf_init2(temp, mpf_get_prec(f)); 1217 mpf_mul(temp, g, g); 1218 mpf_set_ui(f, l); 1219 mpf_mul(f, f, f); 1220 mpf_add(f, f, temp); 1221 mpf_sqrt(f, f); 1222 mpf_clear(temp); 1223 } eval__gmp_hypot_function1224 static void eval(mpf_ptr f, mpf_srcptr g, signed long int l) 1225 { 1226 mpf_t temp; 1227 mpf_init2(temp, mpf_get_prec(f)); 1228 mpf_mul(temp, g, g); 1229 mpf_set_si(f, l); 1230 mpf_mul(f, f, f); 1231 mpf_add(f, f, temp); 1232 mpf_sqrt(f, f); 1233 mpf_clear(temp); 1234 } eval__gmp_hypot_function1235 static void eval(mpf_ptr f, signed long int l, mpf_srcptr g) 1236 { 1237 mpf_t temp; 1238 mpf_init2(temp, mpf_get_prec(f)); 1239 mpf_mul(temp, g, g); 1240 mpf_set_si(f, l); 1241 mpf_mul(f, f, f); 1242 mpf_add(f, f, temp); 1243 mpf_sqrt(f, f); 1244 mpf_clear(temp); 1245 } eval__gmp_hypot_function1246 static void eval(mpf_ptr f, mpf_srcptr g, double d) 1247 { 1248 mpf_t temp; 1249 mpf_init2(temp, mpf_get_prec(f)); 1250 mpf_mul(temp, g, g); 1251 mpf_set_d(f, d); 1252 mpf_mul(f, f, f); 1253 mpf_add(f, f, temp); 1254 mpf_sqrt(f, f); 1255 mpf_clear(temp); 1256 } eval__gmp_hypot_function1257 static void eval(mpf_ptr f, double d, mpf_srcptr g) 1258 { 1259 mpf_t temp; 1260 mpf_init2(temp, mpf_get_prec(f)); 1261 mpf_mul(temp, g, g); 1262 mpf_set_d(f, d); 1263 mpf_mul(f, f, f); 1264 mpf_add(f, f, temp); 1265 mpf_sqrt(f, f); 1266 mpf_clear(temp); 1267 } 1268 }; 1269 1270 struct __gmp_sgn_function 1271 { eval__gmp_sgn_function1272 static int eval(mpz_srcptr z) { return mpz_sgn(z); } eval__gmp_sgn_function1273 static int eval(mpq_srcptr q) { return mpq_sgn(q); } eval__gmp_sgn_function1274 static int eval(mpf_srcptr f) { return mpf_sgn(f); } 1275 }; 1276 1277 struct __gmp_cmp_function 1278 { eval__gmp_cmp_function1279 static int eval(mpz_srcptr z, mpz_srcptr w) { return mpz_cmp(z, w); } 1280 eval__gmp_cmp_function1281 static int eval(mpz_srcptr z, unsigned long int l) 1282 { return mpz_cmp_ui(z, l); } eval__gmp_cmp_function1283 static int eval(unsigned long int l, mpz_srcptr z) 1284 { return -mpz_cmp_ui(z, l); } eval__gmp_cmp_function1285 static int eval(mpz_srcptr z, signed long int l) 1286 { return mpz_cmp_si(z, l); } eval__gmp_cmp_function1287 static int eval(signed long int l, mpz_srcptr z) 1288 { return -mpz_cmp_si(z, l); } eval__gmp_cmp_function1289 static int eval(mpz_srcptr z, double d) 1290 { return mpz_cmp_d(z, d); } eval__gmp_cmp_function1291 static int eval(double d, mpz_srcptr z) 1292 { return -mpz_cmp_d(z, d); } 1293 eval__gmp_cmp_function1294 static int eval(mpq_srcptr q, mpq_srcptr r) { return mpq_cmp(q, r); } 1295 eval__gmp_cmp_function1296 static int eval(mpq_srcptr q, unsigned long int l) 1297 { return mpq_cmp_ui(q, l, 1); } eval__gmp_cmp_function1298 static int eval(unsigned long int l, mpq_srcptr q) 1299 { return -mpq_cmp_ui(q, l, 1); } eval__gmp_cmp_function1300 static int eval(mpq_srcptr q, signed long int l) 1301 { return mpq_cmp_si(q, l, 1); } eval__gmp_cmp_function1302 static int eval(signed long int l, mpq_srcptr q) 1303 { return -mpq_cmp_si(q, l, 1); } eval__gmp_cmp_function1304 static int eval(mpq_srcptr q, double d) 1305 { 1306 int i; 1307 mpq_t temp; 1308 mpq_init(temp); 1309 mpq_set_d(temp, d); 1310 i = mpq_cmp(q, temp); 1311 mpq_clear(temp); 1312 return i; 1313 } eval__gmp_cmp_function1314 static int eval(double d, mpq_srcptr q) 1315 { 1316 int i; 1317 mpq_t temp; 1318 mpq_init(temp); 1319 mpq_set_d(temp, d); 1320 i = mpq_cmp(temp, q); 1321 mpq_clear(temp); 1322 return i; 1323 } 1324 eval__gmp_cmp_function1325 static int eval(mpf_srcptr f, mpf_srcptr g) { return mpf_cmp(f, g); } 1326 eval__gmp_cmp_function1327 static int eval(mpf_srcptr f, unsigned long int l) 1328 { return mpf_cmp_ui(f, l); } eval__gmp_cmp_function1329 static int eval(unsigned long int l, mpf_srcptr f) 1330 { return -mpf_cmp_ui(f, l); } eval__gmp_cmp_function1331 static int eval(mpf_srcptr f, signed long int l) 1332 { return mpf_cmp_si(f, l); } eval__gmp_cmp_function1333 static int eval(signed long int l, mpf_srcptr f) 1334 { return -mpf_cmp_si(f, l); } eval__gmp_cmp_function1335 static int eval(mpf_srcptr f, double d) 1336 { return mpf_cmp_d(f, d); } eval__gmp_cmp_function1337 static int eval(double d, mpf_srcptr f) 1338 { return -mpf_cmp_d(f, d); } 1339 }; 1340 1341 struct __gmp_rand_function 1342 { eval__gmp_rand_function1343 static void eval(mpz_ptr z, gmp_randstate_t s, unsigned long int l) 1344 { mpz_urandomb(z, s, l); } eval__gmp_rand_function1345 static void eval(mpz_ptr z, gmp_randstate_t s, mpz_srcptr w) 1346 { mpz_urandomm(z, s, w); } eval__gmp_rand_function1347 static void eval(mpf_ptr f, gmp_randstate_t s, mp_bitcnt_t prec) 1348 { mpf_urandomb(f, s, prec); } 1349 }; 1350 1351 1352 /**************** Auxiliary classes ****************/ 1353 1354 /* this is much the same as gmp_allocated_string in gmp-impl.h 1355 since gmp-impl.h is not publicly available, I redefine it here 1356 I use a different name to avoid possible clashes */ 1357 extern "C" { 1358 struct __gmp_alloc_cstring_c 1359 { 1360 void (*free_func) (void *, size_t); 1361 }; 1362 } 1363 1364 struct __gmp_alloc_cstring : __gmp_alloc_cstring_c 1365 { 1366 char *str; __gmp_alloc_cstring__gmp_alloc_cstring1367 __gmp_alloc_cstring(char *s) { str = s; } ~__gmp_alloc_cstring__gmp_alloc_cstring1368 ~__gmp_alloc_cstring() 1369 { 1370 mp_get_memory_functions (NULL, NULL, &free_func); 1371 (*free_func) (str, std::strlen(str)+1); 1372 } 1373 }; 1374 1375 // general expression template class 1376 template <class T, class U> 1377 class __gmp_expr; 1378 1379 1380 // templates for resolving expression types 1381 template <class T> 1382 struct __gmp_resolve_ref 1383 { 1384 typedef T ref_type; 1385 }; 1386 1387 template <class T, class U> 1388 struct __gmp_resolve_ref<__gmp_expr<T, U> > 1389 { 1390 typedef const __gmp_expr<T, U> & ref_type; 1391 }; 1392 1393 1394 template <class T, class U = T> 1395 struct __gmp_resolve_expr; 1396 1397 template <> 1398 struct __gmp_resolve_expr<mpz_t> 1399 { 1400 typedef mpz_t value_type; 1401 typedef mpz_ptr ptr_type; 1402 }; 1403 1404 template <> 1405 struct __gmp_resolve_expr<mpq_t> 1406 { 1407 typedef mpq_t value_type; 1408 typedef mpq_ptr ptr_type; 1409 }; 1410 1411 template <> 1412 struct __gmp_resolve_expr<mpf_t> 1413 { 1414 typedef mpf_t value_type; 1415 typedef mpf_ptr ptr_type; 1416 }; 1417 1418 template <> 1419 struct __gmp_resolve_expr<mpz_t, mpq_t> 1420 { 1421 typedef mpq_t value_type; 1422 }; 1423 1424 template <> 1425 struct __gmp_resolve_expr<mpq_t, mpz_t> 1426 { 1427 typedef mpq_t value_type; 1428 }; 1429 1430 template <> 1431 struct __gmp_resolve_expr<mpz_t, mpf_t> 1432 { 1433 typedef mpf_t value_type; 1434 }; 1435 1436 template <> 1437 struct __gmp_resolve_expr<mpf_t, mpz_t> 1438 { 1439 typedef mpf_t value_type; 1440 }; 1441 1442 template <> 1443 struct __gmp_resolve_expr<mpq_t, mpf_t> 1444 { 1445 typedef mpf_t value_type; 1446 }; 1447 1448 template <> 1449 struct __gmp_resolve_expr<mpf_t, mpq_t> 1450 { 1451 typedef mpf_t value_type; 1452 }; 1453 1454 1455 1456 template <class T, class U, class V> 1457 struct __gmp_resolve_temp 1458 { 1459 typedef __gmp_expr<T, T> temp_type; 1460 }; 1461 1462 template <class T> 1463 struct __gmp_resolve_temp<T, T, T> 1464 { 1465 typedef const __gmp_expr<T, T> & temp_type; 1466 }; 1467 1468 1469 // classes for evaluating unary and binary expressions 1470 template <class T, class Op> 1471 struct __gmp_unary_expr 1472 { 1473 const T &val; 1474 1475 __gmp_unary_expr(const T &v) : val(v) { } 1476 private: 1477 __gmp_unary_expr(); 1478 }; 1479 1480 template <class T, class U, class Op> 1481 struct __gmp_binary_expr 1482 { 1483 typename __gmp_resolve_ref<T>::ref_type val1; 1484 typename __gmp_resolve_ref<U>::ref_type val2; 1485 1486 __gmp_binary_expr(const T &v1, const U &v2) : val1(v1), val2(v2) { } 1487 private: 1488 __gmp_binary_expr(); 1489 }; 1490 1491 1492 // functions for evaluating expressions 1493 template <class T, class U> 1494 void __gmp_set_expr(mpz_ptr, const __gmp_expr<T, U> &); 1495 template <class T, class U> 1496 void __gmp_set_expr(mpq_ptr, const __gmp_expr<T, U> &); 1497 template <class T, class U> 1498 void __gmp_set_expr(mpf_ptr, const __gmp_expr<T, U> &); 1499 1500 1501 /**************** Macros for in-class declarations ****************/ 1502 /* This is just repetitive code that is easier to maintain if it's written 1503 only once */ 1504 1505 #define __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \ 1506 template <class T, class U> \ 1507 __gmp_expr<value_type, value_type> & fun(const __gmp_expr<T, U> &); 1508 1509 #define __GMPN_DECLARE_COMPOUND_OPERATOR(fun) \ 1510 __gmp_expr & fun(signed char); \ 1511 __gmp_expr & fun(unsigned char); \ 1512 __gmp_expr & fun(signed int); \ 1513 __gmp_expr & fun(unsigned int); \ 1514 __gmp_expr & fun(signed short int); \ 1515 __gmp_expr & fun(unsigned short int); \ 1516 __gmp_expr & fun(signed long int); \ 1517 __gmp_expr & fun(unsigned long int); \ 1518 __gmp_expr & fun(float); \ 1519 __gmp_expr & fun(double); \ 1520 __gmp_expr & fun(long double); 1521 1522 #define __GMP_DECLARE_COMPOUND_OPERATOR(fun) \ 1523 __GMPP_DECLARE_COMPOUND_OPERATOR(fun) \ 1524 __GMPN_DECLARE_COMPOUND_OPERATOR(fun) 1525 1526 #define __GMP_DECLARE_COMPOUND_OPERATOR_UI(fun) \ 1527 __gmp_expr & fun(unsigned long int); 1528 1529 #define __GMP_DECLARE_INCREMENT_OPERATOR(fun) \ 1530 inline __gmp_expr & fun(); \ 1531 inline __gmp_expr fun(int); 1532 1533 1534 /**************** mpz_class -- wrapper for mpz_t ****************/ 1535 1536 template <> 1537 class __gmp_expr<mpz_t, mpz_t> 1538 { 1539 private: 1540 typedef mpz_t value_type; 1541 value_type mp; 1542 public: 1543 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } 1544 1545 // constructors and destructor 1546 __gmp_expr() { mpz_init(mp); } 1547 1548 __gmp_expr(const __gmp_expr &z) { mpz_init_set(mp, z.mp); } 1549 template <class T, class U> 1550 __gmp_expr(const __gmp_expr<T, U> &expr) 1551 { mpz_init(mp); __gmp_set_expr(mp, expr); } 1552 1553 __gmp_expr(signed char c) { mpz_init_set_si(mp, c); } 1554 __gmp_expr(unsigned char c) { mpz_init_set_ui(mp, c); } 1555 1556 __gmp_expr(signed int i) { mpz_init_set_si(mp, i); } 1557 __gmp_expr(unsigned int i) { mpz_init_set_ui(mp, i); } 1558 1559 __gmp_expr(signed short int s) { mpz_init_set_si(mp, s); } 1560 __gmp_expr(unsigned short int s) { mpz_init_set_ui(mp, s); } 1561 1562 __gmp_expr(signed long int l) { mpz_init_set_si(mp, l); } 1563 __gmp_expr(unsigned long int l) { mpz_init_set_ui(mp, l); } 1564 1565 __gmp_expr(float f) { mpz_init_set_d(mp, f); } 1566 __gmp_expr(double d) { mpz_init_set_d(mp, d); } 1567 // __gmp_expr(long double ld) { mpz_init_set_d(mp, ld); } 1568 1569 explicit __gmp_expr(const char *s) 1570 { 1571 if (mpz_init_set_str (mp, s, 0) != 0) 1572 { 1573 mpz_clear (mp); 1574 throw std::invalid_argument ("mpz_set_str"); 1575 } 1576 } 1577 __gmp_expr(const char *s, int base) 1578 { 1579 if (mpz_init_set_str (mp, s, base) != 0) 1580 { 1581 mpz_clear (mp); 1582 throw std::invalid_argument ("mpz_set_str"); 1583 } 1584 } 1585 explicit __gmp_expr(const std::string &s) 1586 { 1587 if (mpz_init_set_str (mp, s.c_str(), 0) != 0) 1588 { 1589 mpz_clear (mp); 1590 throw std::invalid_argument ("mpz_set_str"); 1591 } 1592 } 1593 __gmp_expr(const std::string &s, int base) 1594 { 1595 if (mpz_init_set_str(mp, s.c_str(), base) != 0) 1596 { 1597 mpz_clear (mp); 1598 throw std::invalid_argument ("mpz_set_str"); 1599 } 1600 } 1601 1602 explicit __gmp_expr(mpz_srcptr z) { mpz_init_set(mp, z); } 1603 1604 ~__gmp_expr() { mpz_clear(mp); } 1605 1606 // assignment operators 1607 __gmp_expr & operator=(const __gmp_expr &z) 1608 { mpz_set(mp, z.mp); return *this; } 1609 template <class T, class U> 1610 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr) 1611 { __gmp_set_expr(mp, expr); return *this; } 1612 1613 __gmp_expr & operator=(signed char c) { mpz_set_si(mp, c); return *this; } 1614 __gmp_expr & operator=(unsigned char c) { mpz_set_ui(mp, c); return *this; } 1615 1616 __gmp_expr & operator=(signed int i) { mpz_set_si(mp, i); return *this; } 1617 __gmp_expr & operator=(unsigned int i) { mpz_set_ui(mp, i); return *this; } 1618 1619 __gmp_expr & operator=(signed short int s) 1620 { mpz_set_si(mp, s); return *this; } 1621 __gmp_expr & operator=(unsigned short int s) 1622 { mpz_set_ui(mp, s); return *this; } 1623 1624 __gmp_expr & operator=(signed long int l) 1625 { mpz_set_si(mp, l); return *this; } 1626 __gmp_expr & operator=(unsigned long int l) 1627 { mpz_set_ui(mp, l); return *this; } 1628 1629 __gmp_expr & operator=(float f) { mpz_set_d(mp, f); return *this; } 1630 __gmp_expr & operator=(double d) { mpz_set_d(mp, d); return *this; } 1631 // __gmp_expr & operator=(long double ld) 1632 // { mpz_set_ld(mp, ld); return *this; } 1633 1634 __gmp_expr & operator=(const char *s) 1635 { 1636 if (mpz_set_str (mp, s, 0) != 0) 1637 throw std::invalid_argument ("mpz_set_str"); 1638 return *this; 1639 } 1640 __gmp_expr & operator=(const std::string &s) 1641 { 1642 if (mpz_set_str(mp, s.c_str(), 0) != 0) 1643 throw std::invalid_argument ("mpz_set_str"); 1644 return *this; 1645 } 1646 1647 // string input/output functions 1648 int set_str(const char *s, int base) 1649 { return mpz_set_str(mp, s, base); } 1650 int set_str(const std::string &s, int base) 1651 { return mpz_set_str(mp, s.c_str(), base); } 1652 std::string get_str(int base = 10) const 1653 { 1654 __gmp_alloc_cstring temp(mpz_get_str(0, base, mp)); 1655 return std::string(temp.str); 1656 } 1657 1658 // conversion functions 1659 mpz_srcptr __get_mp() const { return mp; } 1660 mpz_ptr __get_mp() { return mp; } 1661 mpz_srcptr get_mpz_t() const { return mp; } 1662 mpz_ptr get_mpz_t() { return mp; } 1663 1664 signed long int get_si() const { return mpz_get_si(mp); } 1665 unsigned long int get_ui() const { return mpz_get_ui(mp); } 1666 double get_d() const { return mpz_get_d(mp); } 1667 1668 // bool fits_schar_p() const { return mpz_fits_schar_p(mp); } 1669 // bool fits_uchar_p() const { return mpz_fits_uchar_p(mp); } 1670 bool fits_sint_p() const { return mpz_fits_sint_p(mp); } 1671 bool fits_uint_p() const { return mpz_fits_uint_p(mp); } 1672 bool fits_sshort_p() const { return mpz_fits_sshort_p(mp); } 1673 bool fits_ushort_p() const { return mpz_fits_ushort_p(mp); } 1674 bool fits_slong_p() const { return mpz_fits_slong_p(mp); } 1675 bool fits_ulong_p() const { return mpz_fits_ulong_p(mp); } 1676 // bool fits_float_p() const { return mpz_fits_float_p(mp); } 1677 // bool fits_double_p() const { return mpz_fits_double_p(mp); } 1678 // bool fits_ldouble_p() const { return mpz_fits_ldouble_p(mp); } 1679 1680 // member operators 1681 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=) 1682 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=) 1683 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=) 1684 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=) 1685 __GMP_DECLARE_COMPOUND_OPERATOR(operator%=) 1686 1687 __GMPP_DECLARE_COMPOUND_OPERATOR(operator&=) 1688 __GMPP_DECLARE_COMPOUND_OPERATOR(operator|=) 1689 __GMPP_DECLARE_COMPOUND_OPERATOR(operator^=) 1690 1691 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=) 1692 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=) 1693 1694 __GMP_DECLARE_INCREMENT_OPERATOR(operator++) 1695 __GMP_DECLARE_INCREMENT_OPERATOR(operator--) 1696 }; 1697 1698 typedef __gmp_expr<mpz_t, mpz_t> mpz_class; 1699 1700 1701 /**************** mpq_class -- wrapper for mpq_t ****************/ 1702 1703 template <> 1704 class __gmp_expr<mpq_t, mpq_t> 1705 { 1706 private: 1707 typedef mpq_t value_type; 1708 value_type mp; 1709 public: 1710 mp_bitcnt_t get_prec() const { return mpf_get_default_prec(); } 1711 void canonicalize() { mpq_canonicalize(mp); } 1712 1713 // constructors and destructor 1714 __gmp_expr() { mpq_init(mp); } 1715 1716 __gmp_expr(const __gmp_expr &q) { mpq_init(mp); mpq_set(mp, q.mp); } 1717 template <class T, class U> 1718 __gmp_expr(const __gmp_expr<T, U> &expr) 1719 { mpq_init(mp); __gmp_set_expr(mp, expr); } 1720 1721 __gmp_expr(signed char c) { mpq_init(mp); mpq_set_si(mp, c, 1); } 1722 __gmp_expr(unsigned char c) { mpq_init(mp); mpq_set_ui(mp, c, 1); } 1723 1724 __gmp_expr(signed int i) { mpq_init(mp); mpq_set_si(mp, i, 1); } 1725 __gmp_expr(unsigned int i) { mpq_init(mp); mpq_set_ui(mp, i, 1); } 1726 1727 __gmp_expr(signed short int s) { mpq_init(mp); mpq_set_si(mp, s, 1); } 1728 __gmp_expr(unsigned short int s) { mpq_init(mp); mpq_set_ui(mp, s, 1); } 1729 1730 __gmp_expr(signed long int l) { mpq_init(mp); mpq_set_si(mp, l, 1); } 1731 __gmp_expr(unsigned long int l) { mpq_init(mp); mpq_set_ui(mp, l, 1); } 1732 1733 __gmp_expr(float f) { mpq_init(mp); mpq_set_d(mp, f); } 1734 __gmp_expr(double d) { mpq_init(mp); mpq_set_d(mp, d); } 1735 // __gmp_expr(long double ld) { mpq_init(mp); mpq_set_ld(mp, ld); } 1736 1737 explicit __gmp_expr(const char *s) 1738 { 1739 mpq_init (mp); 1740 if (mpq_set_str (mp, s, 0) != 0) 1741 { 1742 mpq_clear (mp); 1743 throw std::invalid_argument ("mpq_set_str"); 1744 } 1745 } 1746 __gmp_expr(const char *s, int base) 1747 { 1748 mpq_init (mp); 1749 if (mpq_set_str(mp, s, base) != 0) 1750 { 1751 mpq_clear (mp); 1752 throw std::invalid_argument ("mpq_set_str"); 1753 } 1754 } 1755 explicit __gmp_expr(const std::string &s) 1756 { 1757 mpq_init (mp); 1758 if (mpq_set_str (mp, s.c_str(), 0) != 0) 1759 { 1760 mpq_clear (mp); 1761 throw std::invalid_argument ("mpq_set_str"); 1762 } 1763 } 1764 __gmp_expr(const std::string &s, int base) 1765 { 1766 mpq_init(mp); 1767 if (mpq_set_str (mp, s.c_str(), base) != 0) 1768 { 1769 mpq_clear (mp); 1770 throw std::invalid_argument ("mpq_set_str"); 1771 } 1772 } 1773 explicit __gmp_expr(mpq_srcptr q) { mpq_init(mp); mpq_set(mp, q); } 1774 1775 __gmp_expr(const mpz_class &num, const mpz_class &den) 1776 { 1777 mpq_init(mp); 1778 mpz_set(mpq_numref(mp), num.get_mpz_t()); 1779 mpz_set(mpq_denref(mp), den.get_mpz_t()); 1780 } 1781 1782 ~__gmp_expr() { mpq_clear(mp); } 1783 1784 // assignment operators 1785 __gmp_expr & operator=(const __gmp_expr &q) 1786 { mpq_set(mp, q.mp); return *this; } 1787 template <class T, class U> 1788 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr) 1789 { __gmp_set_expr(mp, expr); return *this; } 1790 1791 __gmp_expr & operator=(signed char c) 1792 { mpq_set_si(mp, c, 1); return *this; } 1793 __gmp_expr & operator=(unsigned char c) 1794 { mpq_set_ui(mp, c, 1); return *this; } 1795 1796 __gmp_expr & operator=(signed int i) { mpq_set_si(mp, i, 1); return *this; } 1797 __gmp_expr & operator=(unsigned int i) 1798 { mpq_set_ui(mp, i, 1); return *this; } 1799 1800 __gmp_expr & operator=(signed short int s) 1801 { mpq_set_si(mp, s, 1); return *this; } 1802 __gmp_expr & operator=(unsigned short int s) 1803 { mpq_set_ui(mp, s, 1); return *this; } 1804 1805 __gmp_expr & operator=(signed long int l) 1806 { mpq_set_si(mp, l, 1); return *this; } 1807 __gmp_expr & operator=(unsigned long int l) 1808 { mpq_set_ui(mp, l, 1); return *this; } 1809 1810 __gmp_expr & operator=(float f) { mpq_set_d(mp, f); return *this; } 1811 __gmp_expr & operator=(double d) { mpq_set_d(mp, d); return *this; } 1812 // __gmp_expr & operator=(long double ld) 1813 // { mpq_set_ld(mp, ld); return *this; } 1814 1815 __gmp_expr & operator=(const char *s) 1816 { 1817 if (mpq_set_str (mp, s, 0) != 0) 1818 throw std::invalid_argument ("mpq_set_str"); 1819 return *this; 1820 } 1821 __gmp_expr & operator=(const std::string &s) 1822 { 1823 if (mpq_set_str(mp, s.c_str(), 0) != 0) 1824 throw std::invalid_argument ("mpq_set_str"); 1825 return *this; 1826 } 1827 1828 // string input/output functions 1829 int set_str(const char *s, int base) 1830 { return mpq_set_str(mp, s, base); } 1831 int set_str(const std::string &s, int base) 1832 { return mpq_set_str(mp, s.c_str(), base); } 1833 std::string get_str(int base = 10) const 1834 { 1835 __gmp_alloc_cstring temp(mpq_get_str(0, base, mp)); 1836 return std::string(temp.str); 1837 } 1838 1839 // conversion functions 1840 1841 // casting a reference to an mpz_t to mpz_class & is a dirty hack, 1842 // but works because the internal representation of mpz_class is 1843 // exactly an mpz_t 1844 const mpz_class & get_num() const 1845 { return reinterpret_cast<const mpz_class &>(*mpq_numref(mp)); } 1846 mpz_class & get_num() 1847 { return reinterpret_cast<mpz_class &>(*mpq_numref(mp)); } 1848 const mpz_class & get_den() const 1849 { return reinterpret_cast<const mpz_class &>(*mpq_denref(mp)); } 1850 mpz_class & get_den() 1851 { return reinterpret_cast<mpz_class &>(*mpq_denref(mp)); } 1852 1853 mpq_srcptr __get_mp() const { return mp; } 1854 mpq_ptr __get_mp() { return mp; } 1855 mpq_srcptr get_mpq_t() const { return mp; } 1856 mpq_ptr get_mpq_t() { return mp; } 1857 1858 mpz_srcptr get_num_mpz_t() const { return mpq_numref(mp); } 1859 mpz_ptr get_num_mpz_t() { return mpq_numref(mp); } 1860 mpz_srcptr get_den_mpz_t() const { return mpq_denref(mp); } 1861 mpz_ptr get_den_mpz_t() { return mpq_denref(mp); } 1862 1863 double get_d() const { return mpq_get_d(mp); } 1864 1865 // compound assignments 1866 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=) 1867 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=) 1868 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=) 1869 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=) 1870 1871 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=) 1872 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=) 1873 1874 __GMP_DECLARE_INCREMENT_OPERATOR(operator++) 1875 __GMP_DECLARE_INCREMENT_OPERATOR(operator--) 1876 }; 1877 1878 typedef __gmp_expr<mpq_t, mpq_t> mpq_class; 1879 1880 1881 /**************** mpf_class -- wrapper for mpf_t ****************/ 1882 1883 template <> 1884 class __gmp_expr<mpf_t, mpf_t> 1885 { 1886 private: 1887 typedef mpf_t value_type; 1888 value_type mp; 1889 public: 1890 mp_bitcnt_t get_prec() const { return mpf_get_prec(mp); } 1891 1892 void set_prec(mp_bitcnt_t prec) { mpf_set_prec(mp, prec); } 1893 void set_prec_raw(mp_bitcnt_t prec) { mpf_set_prec_raw(mp, prec); } 1894 1895 // constructors and destructor 1896 __gmp_expr() { mpf_init(mp); } 1897 1898 __gmp_expr(const __gmp_expr &f) 1899 { mpf_init2(mp, f.get_prec()); mpf_set(mp, f.mp); } 1900 __gmp_expr(const __gmp_expr &f, mp_bitcnt_t prec) 1901 { mpf_init2(mp, prec); mpf_set(mp, f.mp); } 1902 template <class T, class U> 1903 __gmp_expr(const __gmp_expr<T, U> &expr) 1904 { mpf_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); } 1905 template <class T, class U> 1906 __gmp_expr(const __gmp_expr<T, U> &expr, mp_bitcnt_t prec) 1907 { mpf_init2(mp, prec); __gmp_set_expr(mp, expr); } 1908 1909 __gmp_expr(signed char c) { mpf_init_set_si(mp, c); } 1910 __gmp_expr(signed char c, mp_bitcnt_t prec) 1911 { mpf_init2(mp, prec); mpf_set_si(mp, c); } 1912 __gmp_expr(unsigned char c) { mpf_init_set_ui(mp, c); } 1913 __gmp_expr(unsigned char c, mp_bitcnt_t prec) 1914 { mpf_init2(mp, prec); mpf_set_ui(mp, c); } 1915 1916 __gmp_expr(signed int i) { mpf_init_set_si(mp, i); } 1917 __gmp_expr(signed int i, mp_bitcnt_t prec) 1918 { mpf_init2(mp, prec); mpf_set_si(mp, i); } 1919 __gmp_expr(unsigned int i) { mpf_init_set_ui(mp, i); } 1920 __gmp_expr(unsigned int i, mp_bitcnt_t prec) 1921 { mpf_init2(mp, prec); mpf_set_ui(mp, i); } 1922 1923 __gmp_expr(signed short int s) { mpf_init_set_si(mp, s); } 1924 __gmp_expr(signed short int s, mp_bitcnt_t prec) 1925 { mpf_init2(mp, prec); mpf_set_si(mp, s); } 1926 __gmp_expr(unsigned short int s) { mpf_init_set_ui(mp, s); } 1927 __gmp_expr(unsigned short int s, mp_bitcnt_t prec) 1928 { mpf_init2(mp, prec); mpf_set_ui(mp, s); } 1929 1930 __gmp_expr(signed long int l) { mpf_init_set_si(mp, l); } 1931 __gmp_expr(signed long int l, mp_bitcnt_t prec) 1932 { mpf_init2(mp, prec); mpf_set_si(mp, l); } 1933 __gmp_expr(unsigned long int l) { mpf_init_set_ui(mp, l); } 1934 __gmp_expr(unsigned long int l, mp_bitcnt_t prec) 1935 { mpf_init2(mp, prec); mpf_set_ui(mp, l); } 1936 1937 __gmp_expr(float f) { mpf_init_set_d(mp, f); } 1938 __gmp_expr(float f, mp_bitcnt_t prec) 1939 { mpf_init2(mp, prec); mpf_set_d(mp, f); } 1940 __gmp_expr(double d) { mpf_init_set_d(mp, d); } 1941 __gmp_expr(double d, mp_bitcnt_t prec) 1942 { mpf_init2(mp, prec); mpf_set_d(mp, d); } 1943 // __gmp_expr(long double ld) { mpf_init_set_d(mp, ld); } 1944 // __gmp_expr(long double ld, mp_bitcnt_t prec) 1945 // { mpf_init2(mp, prec); mpf_set_d(mp, ld); } 1946 1947 explicit __gmp_expr(const char *s) 1948 { 1949 if (mpf_init_set_str (mp, s, 0) != 0) 1950 { 1951 mpf_clear (mp); 1952 throw std::invalid_argument ("mpf_set_str"); 1953 } 1954 } 1955 __gmp_expr(const char *s, mp_bitcnt_t prec, int base = 0) 1956 { 1957 mpf_init2(mp, prec); 1958 if (mpf_set_str(mp, s, base) != 0) 1959 { 1960 mpf_clear (mp); 1961 throw std::invalid_argument ("mpf_set_str"); 1962 } 1963 } 1964 explicit __gmp_expr(const std::string &s) 1965 { 1966 if (mpf_init_set_str(mp, s.c_str(), 0) != 0) 1967 { 1968 mpf_clear (mp); 1969 throw std::invalid_argument ("mpf_set_str"); 1970 } 1971 } 1972 __gmp_expr(const std::string &s, mp_bitcnt_t prec, int base = 0) 1973 { 1974 mpf_init2(mp, prec); 1975 if (mpf_set_str(mp, s.c_str(), base) != 0) 1976 { 1977 mpf_clear (mp); 1978 throw std::invalid_argument ("mpf_set_str"); 1979 } 1980 } 1981 1982 explicit __gmp_expr(mpf_srcptr f) 1983 { mpf_init2(mp, mpf_get_prec(f)); mpf_set(mp, f); } 1984 __gmp_expr(mpf_srcptr f, mp_bitcnt_t prec) 1985 { mpf_init2(mp, prec); mpf_set(mp, f); } 1986 1987 ~__gmp_expr() { mpf_clear(mp); } 1988 1989 // assignment operators 1990 __gmp_expr & operator=(const __gmp_expr &f) 1991 { mpf_set(mp, f.mp); return *this; } 1992 template <class T, class U> 1993 __gmp_expr<value_type, value_type> & operator=(const __gmp_expr<T, U> &expr) 1994 { __gmp_set_expr(mp, expr); return *this; } 1995 1996 __gmp_expr & operator=(signed char c) { mpf_set_si(mp, c); return *this; } 1997 __gmp_expr & operator=(unsigned char c) { mpf_set_ui(mp, c); return *this; } 1998 1999 __gmp_expr & operator=(signed int i) { mpf_set_si(mp, i); return *this; } 2000 __gmp_expr & operator=(unsigned int i) { mpf_set_ui(mp, i); return *this; } 2001 2002 __gmp_expr & operator=(signed short int s) 2003 { mpf_set_si(mp, s); return *this; } 2004 __gmp_expr & operator=(unsigned short int s) 2005 { mpf_set_ui(mp, s); return *this; } 2006 2007 __gmp_expr & operator=(signed long int l) 2008 { mpf_set_si(mp, l); return *this; } 2009 __gmp_expr & operator=(unsigned long int l) 2010 { mpf_set_ui(mp, l); return *this; } 2011 2012 __gmp_expr & operator=(float f) { mpf_set_d(mp, f); return *this; } 2013 __gmp_expr & operator=(double d) { mpf_set_d(mp, d); return *this; } 2014 // __gmp_expr & operator=(long double ld) 2015 // { mpf_set_ld(mp, ld); return *this; } 2016 2017 __gmp_expr & operator=(const char *s) 2018 { 2019 if (mpf_set_str (mp, s, 0) != 0) 2020 throw std::invalid_argument ("mpf_set_str"); 2021 return *this; 2022 } 2023 __gmp_expr & operator=(const std::string &s) 2024 { 2025 if (mpf_set_str(mp, s.c_str(), 0) != 0) 2026 throw std::invalid_argument ("mpf_set_str"); 2027 return *this; 2028 } 2029 2030 // string input/output functions 2031 int set_str(const char *s, int base) 2032 { return mpf_set_str(mp, s, base); } 2033 int set_str(const std::string &s, int base) 2034 { return mpf_set_str(mp, s.c_str(), base); } 2035 std::string get_str(mp_exp_t &expo, int base = 10, size_t size = 0) const 2036 { 2037 __gmp_alloc_cstring temp(mpf_get_str(0, &expo, base, size, mp)); 2038 return std::string(temp.str); 2039 } 2040 2041 // conversion functions 2042 mpf_srcptr __get_mp() const { return mp; } 2043 mpf_ptr __get_mp() { return mp; } 2044 mpf_srcptr get_mpf_t() const { return mp; } 2045 mpf_ptr get_mpf_t() { return mp; } 2046 2047 signed long int get_si() const { return mpf_get_si(mp); } 2048 unsigned long int get_ui() const { return mpf_get_ui(mp); } 2049 double get_d() const { return mpf_get_d(mp); } 2050 2051 // bool fits_schar_p() const { return mpf_fits_schar_p(mp); } 2052 // bool fits_uchar_p() const { return mpf_fits_uchar_p(mp); } 2053 bool fits_sint_p() const { return mpf_fits_sint_p(mp); } 2054 bool fits_uint_p() const { return mpf_fits_uint_p(mp); } 2055 bool fits_sshort_p() const { return mpf_fits_sshort_p(mp); } 2056 bool fits_ushort_p() const { return mpf_fits_ushort_p(mp); } 2057 bool fits_slong_p() const { return mpf_fits_slong_p(mp); } 2058 bool fits_ulong_p() const { return mpf_fits_ulong_p(mp); } 2059 // bool fits_float_p() const { return mpf_fits_float_p(mp); } 2060 // bool fits_double_p() const { return mpf_fits_double_p(mp); } 2061 // bool fits_ldouble_p() const { return mpf_fits_ldouble_p(mp); } 2062 2063 // compound assignments 2064 __GMP_DECLARE_COMPOUND_OPERATOR(operator+=) 2065 __GMP_DECLARE_COMPOUND_OPERATOR(operator-=) 2066 __GMP_DECLARE_COMPOUND_OPERATOR(operator*=) 2067 __GMP_DECLARE_COMPOUND_OPERATOR(operator/=) 2068 2069 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator<<=) 2070 __GMP_DECLARE_COMPOUND_OPERATOR_UI(operator>>=) 2071 2072 __GMP_DECLARE_INCREMENT_OPERATOR(operator++) 2073 __GMP_DECLARE_INCREMENT_OPERATOR(operator--) 2074 }; 2075 2076 typedef __gmp_expr<mpf_t, mpf_t> mpf_class; 2077 2078 2079 2080 /**************** I/O operators ****************/ 2081 2082 // these should (and will) be provided separately 2083 2084 template <class T> 2085 inline std::ostream & operator<< 2086 (std::ostream &o, const __gmp_expr<T, T> &expr) 2087 { 2088 return o << expr.__get_mp(); 2089 } 2090 2091 template <class T, class U> 2092 inline std::ostream & operator<< 2093 (std::ostream &o, const __gmp_expr<T, U> &expr) 2094 { 2095 __gmp_expr<T, T> temp(expr); 2096 return o << temp.__get_mp(); 2097 } 2098 2099 2100 template <class T> 2101 inline std::istream & operator>>(std::istream &i, __gmp_expr<T, T> &expr) 2102 { 2103 return i >> expr.__get_mp(); 2104 } 2105 2106 inline std::istream & operator>>(std::istream &i, mpq_class &q) 2107 { 2108 i >> q.get_mpq_t(); 2109 // q.canonicalize(); // you might want to uncomment this 2110 return i; 2111 } 2112 2113 2114 /**************** Functions for type conversion ****************/ 2115 2116 template <> 2117 inline void __gmp_set_expr(mpz_ptr z, const mpz_class &w) 2118 { 2119 mpz_set(z, w.get_mpz_t()); 2120 } 2121 2122 template <class T> 2123 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpz_t, T> &expr) 2124 { 2125 expr.eval(z); 2126 } 2127 2128 template <> 2129 inline void __gmp_set_expr(mpz_ptr z, const mpq_class &q) 2130 { 2131 mpz_set_q(z, q.get_mpq_t()); 2132 } 2133 2134 template <class T> 2135 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpq_t, T> &expr) 2136 { 2137 mpq_class temp(expr); 2138 mpz_set_q(z, temp.get_mpq_t()); 2139 } 2140 2141 template <class T> 2142 inline void __gmp_set_expr(mpz_ptr z, const mpf_class &f) 2143 { 2144 mpz_set_f(z, f.get_mpf_t()); 2145 } 2146 2147 template <class T> 2148 inline void __gmp_set_expr(mpz_ptr z, const __gmp_expr<mpf_t, T> &expr) 2149 { 2150 mpf_class temp(expr); 2151 mpz_set_f(z, temp.get_mpf_t()); 2152 } 2153 2154 template <> 2155 inline void __gmp_set_expr(mpq_ptr q, const mpz_class &z) 2156 { 2157 mpq_set_z(q, z.get_mpz_t()); 2158 } 2159 2160 template <class T> 2161 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpz_t, T> &expr) 2162 { 2163 mpz_class temp(expr); 2164 mpq_set_z(q, temp.get_mpz_t()); 2165 } 2166 2167 template <> 2168 inline void __gmp_set_expr(mpq_ptr q, const mpq_class &r) 2169 { 2170 mpq_set(q, r.get_mpq_t()); 2171 } 2172 2173 template <class T> 2174 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpq_t, T> &expr) 2175 { 2176 expr.eval(q); 2177 } 2178 2179 template <class T> 2180 inline void __gmp_set_expr(mpq_ptr q, const mpf_class &f) 2181 { 2182 mpq_set_f(q, f.get_mpf_t()); 2183 } 2184 2185 template <class T> 2186 inline void __gmp_set_expr(mpq_ptr q, const __gmp_expr<mpf_t, T> &expr) 2187 { 2188 mpf_class temp(expr); 2189 mpq_set_f(q, temp.get_mpf_t()); 2190 } 2191 2192 template <class T> 2193 inline void __gmp_set_expr(mpf_ptr f, const mpz_class &z) 2194 { 2195 mpf_set_z(f, z.get_mpz_t()); 2196 } 2197 2198 template <class T> 2199 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpz_t, T> &expr) 2200 { 2201 mpz_class temp(expr); 2202 mpf_set_z(f, temp.get_mpz_t()); 2203 } 2204 2205 template <class T> 2206 inline void __gmp_set_expr(mpf_ptr f, const mpq_class &q) 2207 { 2208 mpf_set_q(f, q.get_mpq_t()); 2209 } 2210 2211 template <class T> 2212 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpq_t, T> &expr) 2213 { 2214 mpq_class temp(expr); 2215 mpf_set_q(f, temp.get_mpq_t()); 2216 } 2217 2218 template <> 2219 inline void __gmp_set_expr(mpf_ptr f, const mpf_class &g) 2220 { 2221 mpf_set(f, g.get_mpf_t()); 2222 } 2223 2224 template <class T> 2225 inline void __gmp_set_expr(mpf_ptr f, const __gmp_expr<mpf_t, T> &expr) 2226 { 2227 expr.eval(f, mpf_get_prec(f)); 2228 } 2229 2230 2231 /**************** Specializations of __gmp_expr ****************/ 2232 /* The eval() method of __gmp_expr<T, U> evaluates the corresponding 2233 expression and assigns the result to its argument, which is either an 2234 mpz_t, mpq_t, or mpf_t as specified by the T argument. 2235 Compound expressions are evaluated recursively (temporaries are created 2236 to hold intermediate values), while for simple expressions the eval() 2237 method of the appropriate function object (available as the Op argument 2238 of either __gmp_unary_expr<T, Op> or __gmp_binary_expr<T, U, Op>) is 2239 called. */ 2240 2241 2242 /**************** Unary expressions ****************/ 2243 /* cases: 2244 - simple: argument is mp*_class, that is, __gmp_expr<T, T> 2245 - compound: argument is __gmp_expr<T, U> (with U not equal to T) */ 2246 2247 2248 // simple expressions 2249 2250 template <class T, class Op> 2251 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, T>, Op> > 2252 { 2253 private: 2254 typedef __gmp_expr<T, T> val_type; 2255 2256 __gmp_unary_expr<val_type, Op> expr; 2257 public: 2258 __gmp_expr(const val_type &val) : expr(val) { } 2259 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2260 unsigned long int = 0) const 2261 { Op::eval(p, expr.val.__get_mp()); } 2262 const val_type & get_val() const { return expr.val; } 2263 unsigned long int get_prec() const { return expr.val.get_prec(); } 2264 }; 2265 2266 2267 // compound expressions 2268 2269 template <class T, class U, class Op> 2270 class __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, Op> > 2271 { 2272 private: 2273 typedef __gmp_expr<T, U> val_type; 2274 2275 __gmp_unary_expr<val_type, Op> expr; 2276 public: 2277 __gmp_expr(const val_type &val) : expr(val) { } 2278 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const 2279 { __gmp_expr<T, T> temp(expr.val); Op::eval(p, temp.__get_mp()); } 2280 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2281 mp_bitcnt_t prec) const 2282 { __gmp_expr<T, T> temp(expr.val, prec); Op::eval(p, temp.__get_mp()); } 2283 const val_type & get_val() const { return expr.val; } 2284 unsigned long int get_prec() const { return expr.val.get_prec(); } 2285 }; 2286 2287 2288 /**************** Binary expressions ****************/ 2289 /* simple: 2290 - arguments are both mp*_class 2291 - one argument is mp*_class, one is a built-in type 2292 compound: 2293 - one is mp*_class, one is __gmp_expr<T, U> 2294 - one is __gmp_expr<T, U>, one is built-in 2295 - both arguments are __gmp_expr<...> */ 2296 2297 2298 // simple expressions 2299 2300 template <class T, class Op> 2301 class __gmp_expr 2302 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, T>, Op> > 2303 { 2304 private: 2305 typedef __gmp_expr<T, T> val1_type; 2306 typedef __gmp_expr<T, T> val2_type; 2307 2308 __gmp_binary_expr<val1_type, val2_type, Op> expr; 2309 public: 2310 __gmp_expr(const val1_type &val1, const val2_type &val2) 2311 : expr(val1, val2) { } 2312 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2313 unsigned long int = 0) const 2314 { Op::eval(p, expr.val1.__get_mp(), expr.val2.__get_mp()); } 2315 const val1_type & get_val1() const { return expr.val1; } 2316 const val2_type & get_val2() const { return expr.val2; } 2317 unsigned long int get_prec() const 2318 { 2319 mp_bitcnt_t prec1 = expr.val1.get_prec(), 2320 prec2 = expr.val2.get_prec(); 2321 return (prec1 > prec2) ? prec1 : prec2; 2322 } 2323 }; 2324 2325 2326 // simple expressions, T is a built-in numerical type 2327 2328 template <class T, class U, class Op> 2329 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, T>, U, Op> > 2330 { 2331 private: 2332 typedef __gmp_expr<T, T> val1_type; 2333 typedef U val2_type; 2334 2335 __gmp_binary_expr<val1_type, val2_type, Op> expr; 2336 public: 2337 __gmp_expr(const val1_type &val1, const val2_type &val2) 2338 : expr(val1, val2) { } 2339 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2340 unsigned long int = 0) const 2341 { Op::eval(p, expr.val1.__get_mp(), expr.val2); } 2342 const val1_type & get_val1() const { return expr.val1; } 2343 const val2_type & get_val2() const { return expr.val2; } 2344 unsigned long int get_prec() const { return expr.val1.get_prec(); } 2345 }; 2346 2347 template <class T, class U, class Op> 2348 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, T>, Op> > 2349 { 2350 private: 2351 typedef U val1_type; 2352 typedef __gmp_expr<T, T> val2_type; 2353 2354 __gmp_binary_expr<val1_type, val2_type, Op> expr; 2355 public: 2356 __gmp_expr(const val1_type &val1, const val2_type &val2) 2357 : expr(val1, val2) { } 2358 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2359 unsigned long int = 0) const 2360 { Op::eval(p, expr.val1, expr.val2.__get_mp()); } 2361 const val1_type & get_val1() const { return expr.val1; } 2362 const val2_type & get_val2() const { return expr.val2; } 2363 unsigned long int get_prec() const { return expr.val2.get_prec(); } 2364 }; 2365 2366 2367 // compound expressions, one argument is a subexpression 2368 2369 template <class T, class U, class V, class Op> 2370 class __gmp_expr 2371 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<U, V>, Op> > 2372 { 2373 private: 2374 typedef __gmp_expr<T, T> val1_type; 2375 typedef __gmp_expr<U, V> val2_type; 2376 2377 __gmp_binary_expr<val1_type, val2_type, Op> expr; 2378 public: 2379 __gmp_expr(const val1_type &val1, const val2_type &val2) 2380 : expr(val1, val2) { } 2381 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const 2382 { 2383 __gmp_expr<T, T> temp(expr.val2); 2384 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp()); 2385 } 2386 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2387 mp_bitcnt_t prec) const 2388 { 2389 __gmp_expr<T, T> temp(expr.val2, prec); 2390 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp()); 2391 } 2392 const val1_type & get_val1() const { return expr.val1; } 2393 const val2_type & get_val2() const { return expr.val2; } 2394 unsigned long int get_prec() const 2395 { 2396 mp_bitcnt_t prec1 = expr.val1.get_prec(), 2397 prec2 = expr.val2.get_prec(); 2398 return (prec1 > prec2) ? prec1 : prec2; 2399 } 2400 }; 2401 2402 template <class T, class U, class V, class Op> 2403 class __gmp_expr 2404 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, T>, Op> > 2405 { 2406 private: 2407 typedef __gmp_expr<U, V> val1_type; 2408 typedef __gmp_expr<T, T> val2_type; 2409 2410 __gmp_binary_expr<val1_type, val2_type, Op> expr; 2411 public: 2412 __gmp_expr(const val1_type &val1, const val2_type &val2) 2413 : expr(val1, val2) { } 2414 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const 2415 { 2416 __gmp_expr<T, T> temp(expr.val1); 2417 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp()); 2418 } 2419 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2420 mp_bitcnt_t prec) const 2421 { 2422 __gmp_expr<T, T> temp(expr.val1, prec); 2423 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp()); 2424 } 2425 const val1_type & get_val1() const { return expr.val1; } 2426 const val2_type & get_val2() const { return expr.val2; } 2427 unsigned long int get_prec() const 2428 { 2429 mp_bitcnt_t prec1 = expr.val1.get_prec(), 2430 prec2 = expr.val2.get_prec(); 2431 return (prec1 > prec2) ? prec1 : prec2; 2432 } 2433 }; 2434 2435 template <class T, class U, class Op> 2436 class __gmp_expr 2437 <T, __gmp_binary_expr<__gmp_expr<T, T>, __gmp_expr<T, U>, Op> > 2438 { 2439 private: 2440 typedef __gmp_expr<T, T> val1_type; 2441 typedef __gmp_expr<T, U> val2_type; 2442 2443 __gmp_binary_expr<val1_type, val2_type, Op> expr; 2444 public: 2445 __gmp_expr(const val1_type &val1, const val2_type &val2) 2446 : expr(val1, val2) { } 2447 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const 2448 { 2449 __gmp_expr<T, T> temp(expr.val2); 2450 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp()); 2451 } 2452 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2453 mp_bitcnt_t prec) const 2454 { 2455 __gmp_expr<T, T> temp(expr.val2, prec); 2456 Op::eval(p, expr.val1.__get_mp(), temp.__get_mp()); 2457 } 2458 const val1_type & get_val1() const { return expr.val1; } 2459 const val2_type & get_val2() const { return expr.val2; } 2460 unsigned long int get_prec() const 2461 { 2462 mp_bitcnt_t prec1 = expr.val1.get_prec(), 2463 prec2 = expr.val2.get_prec(); 2464 return (prec1 > prec2) ? prec1 : prec2; 2465 } 2466 }; 2467 2468 template <class T, class U, class Op> 2469 class __gmp_expr 2470 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, T>, Op> > 2471 { 2472 private: 2473 typedef __gmp_expr<T, U> val1_type; 2474 typedef __gmp_expr<T, T> val2_type; 2475 2476 __gmp_binary_expr<val1_type, val2_type, Op> expr; 2477 public: 2478 __gmp_expr(const val1_type &val1, const val2_type &val2) 2479 : expr(val1, val2) { } 2480 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const 2481 { 2482 __gmp_expr<T, T> temp(expr.val1); 2483 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp()); 2484 } 2485 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2486 mp_bitcnt_t prec) const 2487 { 2488 __gmp_expr<T, T> temp(expr.val1, prec); 2489 Op::eval(p, temp.__get_mp(), expr.val2.__get_mp()); 2490 } 2491 const val1_type & get_val1() const { return expr.val1; } 2492 const val2_type & get_val2() const { return expr.val2; } 2493 unsigned long int get_prec() const 2494 { 2495 mp_bitcnt_t prec1 = expr.val1.get_prec(), 2496 prec2 = expr.val2.get_prec(); 2497 return (prec1 > prec2) ? prec1 : prec2; 2498 } 2499 }; 2500 2501 2502 // one argument is a subexpression, one is a built-in 2503 2504 template <class T, class U, class V, class Op> 2505 class __gmp_expr<T, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> > 2506 { 2507 private: 2508 typedef __gmp_expr<T, U> val1_type; 2509 typedef V val2_type; 2510 2511 __gmp_binary_expr<val1_type, val2_type, Op> expr; 2512 public: 2513 __gmp_expr(const val1_type &val1, const val2_type &val2) 2514 : expr(val1, val2) { } 2515 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const 2516 { 2517 __gmp_expr<T, T> temp(expr.val1); 2518 Op::eval(p, temp.__get_mp(), expr.val2); 2519 } 2520 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2521 mp_bitcnt_t prec) const 2522 { 2523 __gmp_expr<T, T> temp(expr.val1, prec); 2524 Op::eval(p, temp.__get_mp(), expr.val2); 2525 } 2526 const val1_type & get_val1() const { return expr.val1; } 2527 const val2_type & get_val2() const { return expr.val2; } 2528 unsigned long int get_prec() const { return expr.val1.get_prec(); } 2529 }; 2530 2531 template <class T, class U, class V, class Op> 2532 class __gmp_expr<T, __gmp_binary_expr<U, __gmp_expr<T, V>, Op> > 2533 { 2534 private: 2535 typedef U val1_type; 2536 typedef __gmp_expr<T, V> val2_type; 2537 2538 __gmp_binary_expr<val1_type, val2_type, Op> expr; 2539 public: 2540 __gmp_expr(const val1_type &val1, const val2_type &val2) 2541 : expr(val1, val2) { } 2542 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const 2543 { 2544 __gmp_expr<T, T> temp(expr.val2); 2545 Op::eval(p, expr.val1, temp.__get_mp()); 2546 } 2547 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2548 mp_bitcnt_t prec) const 2549 { 2550 __gmp_expr<T, T> temp(expr.val2, prec); 2551 Op::eval(p, expr.val1, temp.__get_mp()); 2552 } 2553 const val1_type & get_val1() const { return expr.val1; } 2554 const val2_type & get_val2() const { return expr.val2; } 2555 unsigned long int get_prec() const { return expr.val2.get_prec(); } 2556 }; 2557 2558 2559 // both arguments are subexpressions 2560 2561 template <class T, class U, class V, class W, class Op> 2562 class __gmp_expr 2563 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> > 2564 { 2565 private: 2566 typedef __gmp_expr<T, U> val1_type; 2567 typedef __gmp_expr<V, W> val2_type; 2568 2569 __gmp_binary_expr<val1_type, val2_type, Op> expr; 2570 public: 2571 __gmp_expr(const val1_type &val1, const val2_type &val2) 2572 : expr(val1, val2) { } 2573 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const 2574 { 2575 __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2); 2576 Op::eval(p, temp1.__get_mp(), temp2.__get_mp()); 2577 } 2578 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2579 mp_bitcnt_t prec) const 2580 { 2581 __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec); 2582 Op::eval(p, temp1.__get_mp(), temp2.__get_mp()); 2583 } 2584 const val1_type & get_val1() const { return expr.val1; } 2585 const val2_type & get_val2() const { return expr.val2; } 2586 unsigned long int get_prec() const 2587 { 2588 mp_bitcnt_t prec1 = expr.val1.get_prec(), 2589 prec2 = expr.val2.get_prec(); 2590 return (prec1 > prec2) ? prec1 : prec2; 2591 } 2592 }; 2593 2594 template <class T, class U, class V, class W, class Op> 2595 class __gmp_expr 2596 <T, __gmp_binary_expr<__gmp_expr<U, V>, __gmp_expr<T, W>, Op> > 2597 { 2598 private: 2599 typedef __gmp_expr<U, V> val1_type; 2600 typedef __gmp_expr<T, W> val2_type; 2601 2602 __gmp_binary_expr<val1_type, val2_type, Op> expr; 2603 public: 2604 __gmp_expr(const val1_type &val1, const val2_type &val2) 2605 : expr(val1, val2) { } 2606 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const 2607 { 2608 __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2); 2609 Op::eval(p, temp1.__get_mp(), temp2.__get_mp()); 2610 } 2611 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2612 mp_bitcnt_t prec) const 2613 { 2614 __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec); 2615 Op::eval(p, temp1.__get_mp(), temp2.__get_mp()); 2616 } 2617 const val1_type & get_val1() const { return expr.val1; } 2618 const val2_type & get_val2() const { return expr.val2; } 2619 unsigned long int get_prec() const 2620 { 2621 mp_bitcnt_t prec1 = expr.val1.get_prec(), 2622 prec2 = expr.val2.get_prec(); 2623 return (prec1 > prec2) ? prec1 : prec2; 2624 } 2625 }; 2626 2627 template <class T, class U, class V, class Op> 2628 class __gmp_expr 2629 <T, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<T, V>, Op> > 2630 { 2631 private: 2632 typedef __gmp_expr<T, U> val1_type; 2633 typedef __gmp_expr<T, V> val2_type; 2634 2635 __gmp_binary_expr<val1_type, val2_type, Op> expr; 2636 public: 2637 __gmp_expr(const val1_type &val1, const val2_type &val2) 2638 : expr(val1, val2) { } 2639 void eval(typename __gmp_resolve_expr<T>::ptr_type p) const 2640 { 2641 __gmp_expr<T, T> temp1(expr.val1), temp2(expr.val2); 2642 Op::eval(p, temp1.__get_mp(), temp2.__get_mp()); 2643 } 2644 void eval(typename __gmp_resolve_expr<T>::ptr_type p, 2645 mp_bitcnt_t prec) const 2646 { 2647 __gmp_expr<T, T> temp1(expr.val1, prec), temp2(expr.val2, prec); 2648 Op::eval(p, temp1.__get_mp(), temp2.__get_mp()); 2649 } 2650 const val1_type & get_val1() const { return expr.val1; } 2651 const val2_type & get_val2() const { return expr.val2; } 2652 unsigned long int get_prec() const 2653 { 2654 mp_bitcnt_t prec1 = expr.val1.get_prec(), 2655 prec2 = expr.val2.get_prec(); 2656 return (prec1 > prec2) ? prec1 : prec2; 2657 } 2658 }; 2659 2660 2661 /**************** Special cases ****************/ 2662 2663 /* Some operations (i.e., add and subtract) with mixed mpz/mpq arguments 2664 can be done directly without first converting the mpz to mpq. 2665 Appropriate specializations of __gmp_expr are required. */ 2666 2667 2668 #define __GMPZQ_DEFINE_EXPR(eval_fun) \ 2669 \ 2670 template <> \ 2671 class __gmp_expr<mpq_t, __gmp_binary_expr<mpz_class, mpq_class, eval_fun> > \ 2672 { \ 2673 private: \ 2674 typedef mpz_class val1_type; \ 2675 typedef mpq_class val2_type; \ 2676 \ 2677 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \ 2678 public: \ 2679 __gmp_expr(const val1_type &val1, const val2_type &val2) \ 2680 : expr(val1, val2) { } \ 2681 void eval(mpq_ptr q) const \ 2682 { eval_fun::eval(q, expr.val1.get_mpz_t(), expr.val2.get_mpq_t()); } \ 2683 const val1_type & get_val1() const { return expr.val1; } \ 2684 const val2_type & get_val2() const { return expr.val2; } \ 2685 unsigned long int get_prec() const { return mpf_get_default_prec(); } \ 2686 }; \ 2687 \ 2688 template <> \ 2689 class __gmp_expr<mpq_t, __gmp_binary_expr<mpq_class, mpz_class, eval_fun> > \ 2690 { \ 2691 private: \ 2692 typedef mpq_class val1_type; \ 2693 typedef mpz_class val2_type; \ 2694 \ 2695 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \ 2696 public: \ 2697 __gmp_expr(const val1_type &val1, const val2_type &val2) \ 2698 : expr(val1, val2) { } \ 2699 void eval(mpq_ptr q) const \ 2700 { eval_fun::eval(q, expr.val1.get_mpq_t(), expr.val2.get_mpz_t()); } \ 2701 const val1_type & get_val1() const { return expr.val1; } \ 2702 const val2_type & get_val2() const { return expr.val2; } \ 2703 unsigned long int get_prec() const { return mpf_get_default_prec(); } \ 2704 }; \ 2705 \ 2706 template <class T> \ 2707 class __gmp_expr \ 2708 <mpq_t, __gmp_binary_expr<mpz_class, __gmp_expr<mpq_t, T>, eval_fun> > \ 2709 { \ 2710 private: \ 2711 typedef mpz_class val1_type; \ 2712 typedef __gmp_expr<mpq_t, T> val2_type; \ 2713 \ 2714 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \ 2715 public: \ 2716 __gmp_expr(const val1_type &val1, const val2_type &val2) \ 2717 : expr(val1, val2) { } \ 2718 void eval(mpq_ptr q) const \ 2719 { \ 2720 mpq_class temp(expr.val2); \ 2721 eval_fun::eval(q, expr.val1.get_mpz_t(), temp.get_mpq_t()); \ 2722 } \ 2723 const val1_type & get_val1() const { return expr.val1; } \ 2724 const val2_type & get_val2() const { return expr.val2; } \ 2725 unsigned long int get_prec() const { return mpf_get_default_prec(); } \ 2726 }; \ 2727 \ 2728 template <class T> \ 2729 class __gmp_expr \ 2730 <mpq_t, __gmp_binary_expr<mpq_class, __gmp_expr<mpz_t, T>, eval_fun> > \ 2731 { \ 2732 private: \ 2733 typedef mpq_class val1_type; \ 2734 typedef __gmp_expr<mpz_t, T> val2_type; \ 2735 \ 2736 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \ 2737 public: \ 2738 __gmp_expr(const val1_type &val1, const val2_type &val2) \ 2739 : expr(val1, val2) { } \ 2740 void eval(mpq_ptr q) const \ 2741 { \ 2742 mpz_class temp(expr.val2); \ 2743 eval_fun::eval(q, expr.val1.get_mpq_t(), temp.get_mpz_t()); \ 2744 } \ 2745 const val1_type & get_val1() const { return expr.val1; } \ 2746 const val2_type & get_val2() const { return expr.val2; } \ 2747 unsigned long int get_prec() const { return mpf_get_default_prec(); } \ 2748 }; \ 2749 \ 2750 template <class T> \ 2751 class __gmp_expr \ 2752 <mpq_t, __gmp_binary_expr<__gmp_expr<mpz_t, T>, mpq_class, eval_fun> > \ 2753 { \ 2754 private: \ 2755 typedef __gmp_expr<mpz_t, T> val1_type; \ 2756 typedef mpq_class val2_type; \ 2757 \ 2758 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \ 2759 public: \ 2760 __gmp_expr(const val1_type &val1, const val2_type &val2) \ 2761 : expr(val1, val2) { } \ 2762 void eval(mpq_ptr q) const \ 2763 { \ 2764 mpz_class temp(expr.val1); \ 2765 eval_fun::eval(q, temp.get_mpz_t(), expr.val2.get_mpq_t()); \ 2766 } \ 2767 const val1_type & get_val1() const { return expr.val1; } \ 2768 const val2_type & get_val2() const { return expr.val2; } \ 2769 unsigned long int get_prec() const { return mpf_get_default_prec(); } \ 2770 }; \ 2771 \ 2772 template <class T> \ 2773 class __gmp_expr \ 2774 <mpq_t, __gmp_binary_expr<__gmp_expr<mpq_t, T>, mpz_class, eval_fun> > \ 2775 { \ 2776 private: \ 2777 typedef __gmp_expr<mpq_t, T> val1_type; \ 2778 typedef mpz_class val2_type; \ 2779 \ 2780 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \ 2781 public: \ 2782 __gmp_expr(const val1_type &val1, const val2_type &val2) \ 2783 : expr(val1, val2) { } \ 2784 void eval(mpq_ptr q) const \ 2785 { \ 2786 mpq_class temp(expr.val1); \ 2787 eval_fun::eval(q, temp.get_mpq_t(), expr.val2.get_mpz_t()); \ 2788 } \ 2789 const val1_type & get_val1() const { return expr.val1; } \ 2790 const val2_type & get_val2() const { return expr.val2; } \ 2791 unsigned long int get_prec() const { return mpf_get_default_prec(); } \ 2792 }; \ 2793 \ 2794 template <class T, class U> \ 2795 class __gmp_expr<mpq_t, __gmp_binary_expr \ 2796 <__gmp_expr<mpz_t, T>, __gmp_expr<mpq_t, U>, eval_fun> > \ 2797 { \ 2798 private: \ 2799 typedef __gmp_expr<mpz_t, T> val1_type; \ 2800 typedef __gmp_expr<mpq_t, U> val2_type; \ 2801 \ 2802 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \ 2803 public: \ 2804 __gmp_expr(const val1_type &val1, const val2_type &val2) \ 2805 : expr(val1, val2) { } \ 2806 void eval(mpq_ptr q) const \ 2807 { \ 2808 mpz_class temp1(expr.val1); \ 2809 mpq_class temp2(expr.val2); \ 2810 eval_fun::eval(q, temp1.get_mpz_t(), temp2.get_mpq_t()); \ 2811 } \ 2812 const val1_type & get_val1() const { return expr.val1; } \ 2813 const val2_type & get_val2() const { return expr.val2; } \ 2814 unsigned long int get_prec() const { return mpf_get_default_prec(); } \ 2815 }; \ 2816 \ 2817 template <class T, class U> \ 2818 class __gmp_expr<mpq_t, __gmp_binary_expr \ 2819 <__gmp_expr<mpq_t, T>, __gmp_expr<mpz_t, U>, eval_fun> > \ 2820 { \ 2821 private: \ 2822 typedef __gmp_expr<mpq_t, T> val1_type; \ 2823 typedef __gmp_expr<mpz_t, U> val2_type; \ 2824 \ 2825 __gmp_binary_expr<val1_type, val2_type, eval_fun> expr; \ 2826 public: \ 2827 __gmp_expr(const val1_type &val1, const val2_type &val2) \ 2828 : expr(val1, val2) { } \ 2829 void eval(mpq_ptr q) const \ 2830 { \ 2831 mpq_class temp1(expr.val1); \ 2832 mpz_class temp2(expr.val2); \ 2833 eval_fun::eval(q, temp1.get_mpq_t(), temp2.get_mpz_t()); \ 2834 } \ 2835 const val1_type & get_val1() const { return expr.val1; } \ 2836 const val2_type & get_val2() const { return expr.val2; } \ 2837 unsigned long int get_prec() const { return mpf_get_default_prec(); } \ 2838 }; 2839 2840 2841 __GMPZQ_DEFINE_EXPR(__gmp_binary_plus) 2842 __GMPZQ_DEFINE_EXPR(__gmp_binary_minus) 2843 2844 /**************** Macros for defining functions ****************/ 2845 /* Results of operators and functions are instances of __gmp_expr<T, U>. 2846 T determines the numerical type of the expression: it can be either 2847 mpz_t, mpq_t, or mpf_t. When the arguments of a binary 2848 expression have different numerical types, __gmp_resolve_expr is used 2849 to determine the "larger" type. 2850 U is either __gmp_unary_expr<V, Op> or __gmp_binary_expr<V, W, Op>, 2851 where V and W are the arguments' types -- they can in turn be 2852 expressions, thus allowing to build compound expressions to any 2853 degree of complexity. 2854 Op is a function object that must have an eval() method accepting 2855 appropriate arguments. 2856 Actual evaluation of a __gmp_expr<T, U> object is done when it gets 2857 assigned to an mp*_class ("lazy" evaluation): this is done by calling 2858 its eval() method. */ 2859 2860 2861 // non-member unary operators and functions 2862 2863 #define __GMP_DEFINE_UNARY_FUNCTION(fun, eval_fun) \ 2864 \ 2865 template <class T, class U> \ 2866 inline __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> > \ 2867 fun(const __gmp_expr<T, U> &expr) \ 2868 { \ 2869 return __gmp_expr<T, __gmp_unary_expr<__gmp_expr<T, U>, eval_fun> >(expr); \ 2870 } 2871 2872 #define __GMP_DEFINE_UNARY_TYPE_FUNCTION(type, fun, eval_fun) \ 2873 \ 2874 template <class T, class U> \ 2875 inline type fun(const __gmp_expr<T, U> &expr) \ 2876 { \ 2877 typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr); \ 2878 return eval_fun::eval(temp.__get_mp()); \ 2879 } 2880 2881 2882 // non-member binary operators and functions 2883 2884 #define __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \ 2885 \ 2886 template <class T, class U, class V, class W> \ 2887 inline __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \ 2888 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \ 2889 fun(const __gmp_expr<T, U> &expr1, const __gmp_expr<V, W> &expr2) \ 2890 { \ 2891 return __gmp_expr<typename __gmp_resolve_expr<T, V>::value_type, \ 2892 __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, eval_fun> > \ 2893 (expr1, expr2); \ 2894 } 2895 2896 #define __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, bigtype) \ 2897 \ 2898 template <class T, class U> \ 2899 inline __gmp_expr \ 2900 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> > \ 2901 fun(const __gmp_expr<T, U> &expr, type t) \ 2902 { \ 2903 return __gmp_expr \ 2904 <T, __gmp_binary_expr<__gmp_expr<T, U>, bigtype, eval_fun> >(expr, t); \ 2905 } \ 2906 \ 2907 template <class T, class U> \ 2908 inline __gmp_expr \ 2909 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> > \ 2910 fun(type t, const __gmp_expr<T, U> &expr) \ 2911 { \ 2912 return __gmp_expr \ 2913 <T, __gmp_binary_expr<bigtype, __gmp_expr<T, U>, eval_fun> >(t, expr); \ 2914 } 2915 2916 #define __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \ 2917 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, signed long int) 2918 2919 #define __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \ 2920 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, unsigned long int) 2921 2922 #define __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \ 2923 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, double) 2924 2925 #define __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, type) \ 2926 __GMPNN_DEFINE_BINARY_FUNCTION(fun, eval_fun, type, long double) 2927 2928 #define __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) \ 2929 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed char) \ 2930 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned char) \ 2931 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed int) \ 2932 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned int) \ 2933 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed short int) \ 2934 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned short int) \ 2935 __GMPNS_DEFINE_BINARY_FUNCTION(fun, eval_fun, signed long int) \ 2936 __GMPNU_DEFINE_BINARY_FUNCTION(fun, eval_fun, unsigned long int) \ 2937 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, float) \ 2938 __GMPND_DEFINE_BINARY_FUNCTION(fun, eval_fun, double) \ 2939 __GMPNLD_DEFINE_BINARY_FUNCTION(fun, eval_fun, long double) 2940 2941 #define __GMP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \ 2942 __GMPP_DEFINE_BINARY_FUNCTION(fun, eval_fun) \ 2943 __GMPN_DEFINE_BINARY_FUNCTION(fun, eval_fun) 2944 2945 2946 #define __GMP_DEFINE_BINARY_FUNCTION_UI(fun, eval_fun) \ 2947 \ 2948 template <class T, class U> \ 2949 inline __gmp_expr \ 2950 <T, __gmp_binary_expr<__gmp_expr<T, U>, unsigned long int, eval_fun> > \ 2951 fun(const __gmp_expr<T, U> &expr, unsigned long int l) \ 2952 { \ 2953 return __gmp_expr<T, __gmp_binary_expr \ 2954 <__gmp_expr<T, U>, unsigned long int, eval_fun> >(expr, l); \ 2955 } 2956 2957 2958 #define __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \ 2959 \ 2960 template <class T, class U, class V, class W> \ 2961 inline type fun(const __gmp_expr<T, U> &expr1, \ 2962 const __gmp_expr<V, W> &expr2) \ 2963 { \ 2964 typedef typename __gmp_resolve_expr<T, V>::value_type eval_type; \ 2965 typename __gmp_resolve_temp<eval_type, T, U>::temp_type temp1(expr1); \ 2966 typename __gmp_resolve_temp<eval_type, V, W>::temp_type temp2(expr2); \ 2967 return eval_fun::eval(temp1.__get_mp(), temp2.__get_mp()); \ 2968 } 2969 2970 #define __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \ 2971 type2, bigtype) \ 2972 \ 2973 template <class T, class U> \ 2974 inline type fun(const __gmp_expr<T, U> &expr, type2 t) \ 2975 { \ 2976 typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr); \ 2977 return eval_fun::eval(temp.__get_mp(), static_cast<bigtype>(t)); \ 2978 } \ 2979 \ 2980 template <class T, class U> \ 2981 inline type fun(type2 t, const __gmp_expr<T, U> &expr) \ 2982 { \ 2983 typename __gmp_resolve_temp<T, T, U>::temp_type temp(expr); \ 2984 return eval_fun::eval(static_cast<bigtype>(t), temp.__get_mp()); \ 2985 } 2986 2987 #define __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \ 2988 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \ 2989 type2, signed long int) 2990 2991 #define __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \ 2992 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, \ 2993 type2, unsigned long int) 2994 2995 #define __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \ 2996 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, double) 2997 2998 #define __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2) \ 2999 __GMPNN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, type2, long double) 3000 3001 #define __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \ 3002 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed char) \ 3003 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned char) \ 3004 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed int) \ 3005 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned int) \ 3006 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed short int) \ 3007 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned short int) \ 3008 __GMPNS_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, signed long int) \ 3009 __GMPNU_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, unsigned long int) \ 3010 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, float) \ 3011 __GMPND_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, double) \ 3012 __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun, long double) 3013 3014 #define __GMP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \ 3015 __GMPP_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) \ 3016 __GMPN_DEFINE_BINARY_TYPE_FUNCTION(type, fun, eval_fun) 3017 3018 3019 // member operators 3020 3021 #define __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \ 3022 \ 3023 template <class T, class U> \ 3024 inline type##_class & type##_class::fun(const __gmp_expr<T, U> &expr) \ 3025 { \ 3026 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \ 3027 <type##_class, __gmp_expr<T, U>, eval_fun> >(*this, expr)); \ 3028 return *this; \ 3029 } 3030 3031 #define __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \ 3032 type2, bigtype) \ 3033 \ 3034 inline type##_class & type##_class::fun(type2 t) \ 3035 { \ 3036 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \ 3037 <type##_class, bigtype, eval_fun> >(*this, t)); \ 3038 return *this; \ 3039 } 3040 3041 #define __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \ 3042 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \ 3043 type2, signed long int) 3044 3045 #define __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \ 3046 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, \ 3047 type2, unsigned long int) 3048 3049 #define __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \ 3050 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, double) 3051 3052 #define __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2) \ 3053 __GMPNN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, type2, long double) 3054 3055 #define __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \ 3056 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed char) \ 3057 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned char) \ 3058 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed int) \ 3059 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned int) \ 3060 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed short int) \ 3061 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned short int) \ 3062 __GMPNS_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, signed long int) \ 3063 __GMPNU_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, unsigned long int) \ 3064 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, float) \ 3065 __GMPND_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, double) \ 3066 /* __GMPNLD_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun, long double) */ 3067 3068 #define __GMP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \ 3069 __GMPP_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) \ 3070 __GMPN_DEFINE_COMPOUND_OPERATOR(type, fun, eval_fun) 3071 3072 #define __GMPZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \ 3073 __GMP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun) 3074 3075 #define __GMPZZ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \ 3076 __GMPP_DEFINE_COMPOUND_OPERATOR(mpz, fun, eval_fun) 3077 3078 #define __GMPQ_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \ 3079 __GMP_DEFINE_COMPOUND_OPERATOR(mpq, fun, eval_fun) 3080 3081 #define __GMPF_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \ 3082 __GMP_DEFINE_COMPOUND_OPERATOR(mpf, fun, eval_fun) 3083 3084 3085 3086 #define __GMP_DEFINE_COMPOUND_OPERATOR_UI(type, fun, eval_fun) \ 3087 \ 3088 inline type##_class & type##_class::fun(unsigned long int l) \ 3089 { \ 3090 __gmp_set_expr(mp, __gmp_expr<type##_t, __gmp_binary_expr \ 3091 <type##_class, unsigned long int, eval_fun> >(*this, l)); \ 3092 return *this; \ 3093 } 3094 3095 #define __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \ 3096 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpz, fun, eval_fun) 3097 3098 #define __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \ 3099 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpq, fun, eval_fun) 3100 3101 #define __GMPF_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \ 3102 __GMP_DEFINE_COMPOUND_OPERATOR_UI(mpf, fun, eval_fun) 3103 3104 3105 3106 #define __GMP_DEFINE_INCREMENT_OPERATOR(type, fun, eval_fun) \ 3107 \ 3108 inline type##_class & type##_class::fun() \ 3109 { \ 3110 eval_fun::eval(mp); \ 3111 return *this; \ 3112 } \ 3113 \ 3114 inline type##_class type##_class::fun(int) \ 3115 { \ 3116 type##_class temp(*this); \ 3117 eval_fun::eval(mp); \ 3118 return temp; \ 3119 } 3120 3121 #define __GMPZ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \ 3122 __GMP_DEFINE_INCREMENT_OPERATOR(mpz, fun, eval_fun) 3123 3124 #define __GMPQ_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \ 3125 __GMP_DEFINE_INCREMENT_OPERATOR(mpq, fun, eval_fun) 3126 3127 #define __GMPF_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \ 3128 __GMP_DEFINE_INCREMENT_OPERATOR(mpf, fun, eval_fun) 3129 3130 3131 3132 /**************** Arithmetic operators and functions ****************/ 3133 3134 // non-member operators and functions 3135 3136 __GMP_DEFINE_UNARY_FUNCTION(operator+, __gmp_unary_plus) 3137 __GMP_DEFINE_UNARY_FUNCTION(operator-, __gmp_unary_minus) 3138 __GMP_DEFINE_UNARY_FUNCTION(operator~, __gmp_unary_com) 3139 3140 __GMP_DEFINE_BINARY_FUNCTION(operator+, __gmp_binary_plus) 3141 __GMP_DEFINE_BINARY_FUNCTION(operator-, __gmp_binary_minus) 3142 __GMP_DEFINE_BINARY_FUNCTION(operator*, __gmp_binary_multiplies) 3143 __GMP_DEFINE_BINARY_FUNCTION(operator/, __gmp_binary_divides) 3144 __GMP_DEFINE_BINARY_FUNCTION(operator%, __gmp_binary_modulus) 3145 __GMP_DEFINE_BINARY_FUNCTION(operator&, __gmp_binary_and) 3146 __GMP_DEFINE_BINARY_FUNCTION(operator|, __gmp_binary_ior) 3147 __GMP_DEFINE_BINARY_FUNCTION(operator^, __gmp_binary_xor) 3148 3149 __GMP_DEFINE_BINARY_FUNCTION_UI(operator<<, __gmp_binary_lshift) 3150 __GMP_DEFINE_BINARY_FUNCTION_UI(operator>>, __gmp_binary_rshift) 3151 3152 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator==, __gmp_binary_equal) 3153 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator!=, __gmp_binary_not_equal) 3154 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<, __gmp_binary_less) 3155 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator<=, __gmp_binary_less_equal) 3156 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>, __gmp_binary_greater) 3157 __GMP_DEFINE_BINARY_TYPE_FUNCTION(bool, operator>=, \ 3158 __gmp_binary_greater_equal) 3159 3160 __GMP_DEFINE_UNARY_FUNCTION(abs, __gmp_abs_function) 3161 __GMP_DEFINE_UNARY_FUNCTION(trunc, __gmp_trunc_function) 3162 __GMP_DEFINE_UNARY_FUNCTION(floor, __gmp_floor_function) 3163 __GMP_DEFINE_UNARY_FUNCTION(ceil, __gmp_ceil_function) 3164 __GMP_DEFINE_UNARY_FUNCTION(sqrt, __gmp_sqrt_function) 3165 __GMP_DEFINE_BINARY_FUNCTION(hypot, __gmp_hypot_function) 3166 3167 __GMP_DEFINE_UNARY_TYPE_FUNCTION(int, sgn, __gmp_sgn_function) 3168 __GMP_DEFINE_BINARY_TYPE_FUNCTION(int, cmp, __gmp_cmp_function) 3169 3170 // member operators for mpz_class 3171 3172 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus) 3173 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus) 3174 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies) 3175 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides) 3176 __GMPZ_DEFINE_COMPOUND_OPERATOR(operator%=, __gmp_binary_modulus) 3177 3178 __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator&=, __gmp_binary_and) 3179 __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator|=, __gmp_binary_ior) 3180 __GMPZZ_DEFINE_COMPOUND_OPERATOR(operator^=, __gmp_binary_xor) 3181 3182 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift) 3183 __GMPZ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift) 3184 3185 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment) 3186 __GMPZ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement) 3187 3188 // member operators for mpq_class 3189 3190 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus) 3191 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus) 3192 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies) 3193 __GMPQ_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides) 3194 3195 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift) 3196 __GMPQ_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift) 3197 3198 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment) 3199 __GMPQ_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement) 3200 3201 // member operators for mpf_class 3202 3203 __GMPF_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus) 3204 __GMPF_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus) 3205 __GMPF_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies) 3206 __GMPF_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides) 3207 3208 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift) 3209 __GMPF_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift) 3210 3211 __GMPF_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment) 3212 __GMPF_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement) 3213 3214 3215 3216 /**************** Class wrapper for gmp_randstate_t ****************/ 3217 3218 class __gmp_urandomb_value { }; 3219 class __gmp_urandomm_value { }; 3220 3221 template <> 3222 class __gmp_expr<mpz_t, __gmp_urandomb_value> 3223 { 3224 private: 3225 __gmp_randstate_struct *state; 3226 unsigned long int bits; 3227 public: 3228 __gmp_expr(gmp_randstate_t s, unsigned long int l) : state(s), bits(l) { } 3229 void eval(mpz_ptr z) const { __gmp_rand_function::eval(z, state, bits); } 3230 unsigned long int get_prec() const { return mpf_get_default_prec(); } 3231 }; 3232 3233 template <> 3234 class __gmp_expr<mpz_t, __gmp_urandomm_value> 3235 { 3236 private: 3237 __gmp_randstate_struct *state; 3238 mpz_class range; 3239 public: 3240 __gmp_expr(gmp_randstate_t s, const mpz_class &z) : state(s), range(z) { } 3241 void eval(mpz_ptr z) const 3242 { __gmp_rand_function::eval(z, state, range.get_mpz_t()); } 3243 unsigned long int get_prec() const { return mpf_get_default_prec(); } 3244 }; 3245 3246 template <> 3247 class __gmp_expr<mpf_t, __gmp_urandomb_value> 3248 { 3249 private: 3250 __gmp_randstate_struct *state; 3251 unsigned long int bits; 3252 public: 3253 __gmp_expr(gmp_randstate_t s, unsigned long int l) : state(s), bits(l) { } 3254 void eval(mpf_ptr f, mp_bitcnt_t prec) const 3255 { __gmp_rand_function::eval(f, state, (bits>0) ? get_prec() : prec); } 3256 unsigned long int get_prec() const 3257 { 3258 if (bits == 0) 3259 return mpf_get_default_prec(); 3260 else 3261 return bits; 3262 } 3263 }; 3264 3265 extern "C" { 3266 typedef void __gmp_randinit_default_t (gmp_randstate_t); 3267 typedef void __gmp_randinit_lc_2exp_t (gmp_randstate_t, mpz_srcptr, unsigned long int, mp_bitcnt_t); 3268 typedef int __gmp_randinit_lc_2exp_size_t (gmp_randstate_t, mp_bitcnt_t); 3269 } 3270 3271 class gmp_randclass 3272 { 3273 private: 3274 gmp_randstate_t state; 3275 3276 // copy construction and assignment not allowed 3277 gmp_randclass(const gmp_randclass &); 3278 void operator=(const gmp_randclass &); 3279 public: 3280 // constructors and destructor 3281 gmp_randclass(gmp_randalg_t alg, unsigned long int size) 3282 { 3283 switch (alg) 3284 { 3285 case GMP_RAND_ALG_LC: // no other cases for now 3286 default: 3287 gmp_randinit_lc_2exp_size(state, size); 3288 break; 3289 } 3290 } 3291 3292 // gmp_randinit_default 3293 gmp_randclass(__gmp_randinit_default_t* f) { f(state); } 3294 3295 // gmp_randinit_lc_2exp 3296 gmp_randclass(__gmp_randinit_lc_2exp_t* f, 3297 mpz_class z, unsigned long int l1, unsigned long int l2) 3298 { f(state, z.get_mpz_t(), l1, l2); } 3299 3300 // gmp_randinit_lc_2exp_size 3301 gmp_randclass(__gmp_randinit_lc_2exp_size_t* f, 3302 unsigned long int size) 3303 { 3304 if (f (state, size) == 0) 3305 throw std::length_error ("gmp_randinit_lc_2exp_size"); 3306 } 3307 3308 ~gmp_randclass() { gmp_randclear(state); } 3309 3310 // initialize 3311 void seed(); // choose a random seed some way (?) 3312 void seed(unsigned long int s) { gmp_randseed_ui(state, s); } 3313 void seed(const mpz_class &z) { gmp_randseed(state, z.get_mpz_t()); } 3314 3315 // get random number 3316 __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(unsigned long int l) 3317 { return __gmp_expr<mpz_t, __gmp_urandomb_value>(state, l); } 3318 __gmp_expr<mpz_t, __gmp_urandomb_value> get_z_bits(const mpz_class &z) 3319 { return get_z_bits(z.get_ui()); } 3320 3321 __gmp_expr<mpz_t, __gmp_urandomm_value> get_z_range(const mpz_class &z) 3322 { return __gmp_expr<mpz_t, __gmp_urandomm_value>(state, z); } 3323 3324 __gmp_expr<mpf_t, __gmp_urandomb_value> get_f(unsigned long int prec = 0) 3325 { return __gmp_expr<mpf_t, __gmp_urandomb_value>(state, prec); } 3326 }; 3327 3328 3329 /**************** #undef all private macros ****************/ 3330 3331 #undef __GMPP_DECLARE_COMPOUND_OPERATOR 3332 #undef __GMPN_DECLARE_COMPOUND_OPERATOR 3333 #undef __GMP_DECLARE_COMPOUND_OPERATOR 3334 #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI 3335 #undef __GMP_DECLARE_INCREMENT_OPERATOR 3336 3337 #undef __GMPZQ_DEFINE_EXPR 3338 #undef __GMP_DEFINE_TERNARY_EXPR 3339 3340 #undef __GMP_DEFINE_UNARY_FUNCTION 3341 #undef __GMP_DEFINE_UNARY_TYPE_FUNCTION 3342 3343 #undef __GMPP_DEFINE_BINARY_FUNCTION 3344 #undef __GMPNN_DEFINE_BINARY_FUNCTION 3345 #undef __GMPNS_DEFINE_BINARY_FUNCTION 3346 #undef __GMPNU_DEFINE_BINARY_FUNCTION 3347 #undef __GMPND_DEFINE_BINARY_FUNCTION 3348 #undef __GMPNLD_DEFINE_BINARY_FUNCTION 3349 #undef __GMPN_DEFINE_BINARY_FUNCTION 3350 #undef __GMP_DEFINE_BINARY_FUNCTION 3351 3352 #undef __GMP_DEFINE_BINARY_FUNCTION_UI 3353 3354 #undef __GMPP_DEFINE_BINARY_TYPE_FUNCTION 3355 #undef __GMPNN_DEFINE_BINARY_TYPE_FUNCTION 3356 #undef __GMPNS_DEFINE_BINARY_TYPE_FUNCTION 3357 #undef __GMPNU_DEFINE_BINARY_TYPE_FUNCTION 3358 #undef __GMPND_DEFINE_BINARY_TYPE_FUNCTION 3359 #undef __GMPNLD_DEFINE_BINARY_TYPE_FUNCTION 3360 #undef __GMPN_DEFINE_BINARY_TYPE_FUNCTION 3361 #undef __GMP_DEFINE_BINARY_TYPE_FUNCTION 3362 3363 #undef __GMPP_DECLARE_COMPOUND_OPERATOR 3364 #undef __GMPN_DECLARE_COMPOUND_OPERATOR 3365 #undef __GMP_DECLARE_COMPOUND_OPERATOR 3366 3367 #undef __GMP_DECLARE_COMPOUND_OPERATOR_UI 3368 #undef __GMP_DECLARE_INCREMENT_OPERATOR 3369 3370 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR 3371 #undef __GMPZZ_DEFINE_COMPOUND_OPERATOR 3372 #undef __GMPZN_DEFINE_COMPOUND_OPERATOR 3373 #undef __GMPZNN_DEFINE_COMPOUND_OPERATOR 3374 #undef __GMPZNS_DEFINE_COMPOUND_OPERATOR 3375 #undef __GMPZNU_DEFINE_COMPOUND_OPERATOR 3376 #undef __GMPZND_DEFINE_COMPOUND_OPERATOR 3377 #undef __GMPZNLD_DEFINE_COMPOUND_OPERATOR 3378 3379 #undef __GMPP_DEFINE_COMPOUND_OPERATOR 3380 #undef __GMPNN_DEFINE_COMPOUND_OPERATOR 3381 #undef __GMPNS_DEFINE_COMPOUND_OPERATOR 3382 #undef __GMPNU_DEFINE_COMPOUND_OPERATOR 3383 #undef __GMPND_DEFINE_COMPOUND_OPERATOR 3384 #undef __GMPNLD_DEFINE_COMPOUND_OPERATOR 3385 #undef __GMPN_DEFINE_COMPOUND_OPERATOR 3386 #undef __GMP_DEFINE_COMPOUND_OPERATOR 3387 3388 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR 3389 #undef __GMPZZ_DEFINE_COMPOUND_OPERATOR 3390 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR 3391 #undef __GMPF_DEFINE_COMPOUND_OPERATOR 3392 3393 #undef __GMP_DEFINE_COMPOUND_OPERATOR_UI 3394 #undef __GMPZ_DEFINE_COMPOUND_OPERATOR_UI 3395 #undef __GMPQ_DEFINE_COMPOUND_OPERATOR_UI 3396 #undef __GMPF_DEFINE_COMPOUND_OPERATOR_UI 3397 3398 #undef __GMP_DEFINE_INCREMENT_OPERATOR 3399 #undef __GMPZ_DEFINE_INCREMENT_OPERATOR 3400 #undef __GMPQ_DEFINE_INCREMENT_OPERATOR 3401 #undef __GMPF_DEFINE_INCREMENT_OPERATOR 3402 3403 #endif /* __GMP_PLUSPLUS__ */ 3404