1 2 /*+-----------------------------------------------------------------** 3 ** OpenScop Library ** 4 **-----------------------------------------------------------------** 5 ** int.c ** 6 **-----------------------------------------------------------------** 7 ** First version: 18/07/2011 ** 8 **-----------------------------------------------------------------** 9 10 11 ***************************************************************************** 12 * OpenScop: Structures and formats for polyhedral tools to talk together * 13 ***************************************************************************** 14 * ,___,,_,__,,__,,__,,__,,_,__,,_,__,,__,,___,_,__,,_,__, * 15 * / / / // // // // / / / // // / / // / /|,_, * 16 * / / / // // // // / / / // // / / // / / / /\ * 17 * |~~~|~|~~~|~~~|~~~|~~~|~|~~~|~|~~~|~~~|~~~|~|~~~|~|~~~|/_/ \ * 18 * | G |C| P | = | L | P |=| = |C| = | = | = |=| = |=| C |\ \ /\ * 19 * | R |l| o | = | e | l |=| = |a| = | = | = |=| = |=| L | \# \ /\ * 20 * | A |a| l | = | t | u |=| = |n| = | = | = |=| = |=| o | |\# \ \ * 21 * | P |n| l | = | s | t |=| = |d| = | = | = | | |=| o | | \# \ \ * 22 * | H | | y | | e | o | | = |l| | | = | | | | G | | \ \ \ * 23 * | I | | | | e | | | | | | | | | | | | | \ \ \ * 24 * | T | | | | | | | | | | | | | | | | | \ \ \ * 25 * | E | | | | | | | | | | | | | | | | | \ \ \ * 26 * | * |*| * | * | * | * |*| * |*| * | * | * |*| * |*| * | / \* \ \ * 27 * | O |p| e | n | S | c |o| p |-| L | i | b |r| a |r| y |/ \ \ / * 28 * '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---' '--' * 29 * * 30 * Copyright (C) 2008 University Paris-Sud 11 and INRIA * 31 * * 32 * (3-clause BSD license) * 33 * Redistribution and use in source and binary forms, with or without * 34 * modification, are permitted provided that the following conditions * 35 * are met: * 36 * * 37 * 1. Redistributions of source code must retain the above copyright notice, * 38 * this list of conditions and the following disclaimer. * 39 * 2. Redistributions in binary form must reproduce the above copyright * 40 * notice, this list of conditions and the following disclaimer in the * 41 * documentation and/or other materials provided with the distribution. * 42 * 3. The name of the author may not be used to endorse or promote products * 43 * derived from this software without specific prior written permission. * 44 * * 45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * 46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * 47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * 48 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * 49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * 50 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * 51 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * 52 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * 53 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * 54 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 55 * * 56 * OpenScop Library, a library to manipulate OpenScop formats and data * 57 * structures. Written by: * 58 * Cedric Bastoul <Cedric.Bastoul@u-psud.fr> and * 59 * Louis-Noel Pouchet <Louis-Noel.pouchet@inria.fr> * 60 * * 61 *****************************************************************************/ 62 63#include <stdlib.h> 64#include <stdio.h> 65#ifdef OSL_GMP_IS_HERE 66# include <gmp.h> 67#endif 68 69#include <osl/macros.h> 70#include <osl/int.h> 71 72 73 74/*+*************************************************************************** 75 * Basic Functions * 76 *****************************************************************************/ 77 78 79/** 80 * osl_int_dump_precision function: 81 * this function prints in a human readable fashion the precision 82 * corresponding to the "precision" parameter. 83 * \param[in] file The file where to print the precision. 84 * \param[in] precision The precision to print. 85 */ 86void osl_int_dump_precision(FILE * file, int precision) { 87 88 switch (precision) { 89 case OSL_PRECISION_SP: 90 fprintf(file, "32 bits"); 91 break; 92 case OSL_PRECISION_DP: 93 fprintf(file, "64 bits"); 94 break; 95#ifdef OSL_GMP_IS_HERE 96 case OSL_PRECISION_MP: 97 fprintf(file, "GMP"); 98 break; 99#endif 100 default: 101 fprintf(file, "unknown precision %d", precision); 102 } 103} 104 105 106int osl_int_sizeof(int precision) { 107 switch (precision) { 108 case OSL_PRECISION_SP: 109 return sizeof(long int); 110 111 case OSL_PRECISION_DP: 112 return sizeof(long long int); 113 114#ifdef OSL_GMP_IS_HERE 115 case OSL_PRECISION_MP: 116 return sizeof(mpz_t); 117#endif 118 119 default: 120 OSL_error("unknown precision"); 121 } 122} 123 124 125void * osl_int_address(int precision, void * base, int offset) { 126 switch (precision) { 127 case OSL_PRECISION_SP: 128 return (long int *)base + offset; 129 130 case OSL_PRECISION_DP: 131 return (long long int *)base + offset; 132 133#ifdef OSL_GMP_IS_HERE 134 case OSL_PRECISION_MP: 135 return (mpz_t *)base + offset; 136#endif 137 138 default: 139 OSL_error("unknown precision"); 140 } 141} 142 143 144void osl_int_init(int precision, void * value_base, int value_offset) { 145 void * value = osl_int_address(precision, value_base, value_offset); 146 147 switch (precision) { 148 case OSL_PRECISION_SP: 149 *(long int *)value = 0; 150 break; 151 152 case OSL_PRECISION_DP: 153 *(long long int *)value = 0; 154 break; 155 156#ifdef OSL_GMP_IS_HERE 157 case OSL_PRECISION_MP: 158 mpz_init(*(mpz_t *)value); 159 break; 160#endif 161 162 default: 163 OSL_error("unknown precision"); 164 } 165} 166 167 168void * osl_int_malloc(int precision) { 169 void * value; 170 171 switch (precision) { 172 case OSL_PRECISION_SP: 173 value = malloc(sizeof(long int)); 174 break; 175 176 case OSL_PRECISION_DP: 177 value = malloc(sizeof(long long int)); 178 *(long long int *)value = 0; 179 break; 180 181#ifdef OSL_GMP_IS_HERE 182 case OSL_PRECISION_MP: 183 value = malloc(sizeof(mpz_t)); 184 break; 185#endif 186 187 default: 188 OSL_error("unknown precision"); 189 } 190 191 osl_int_init(precision, value, 0); 192 return value; 193} 194 195 196/** 197 * val1_base[val1_offset] = val2_base[val2_offset]; 198 */ 199void osl_int_assign(int precision, 200 void * val1_base, int val1_offset, 201 void * val2_base, int val2_offset) { 202 void * val1 = osl_int_address(precision, val1_base, val1_offset); 203 void * val2 = osl_int_address(precision, val2_base, val2_offset); 204 205 switch (precision) { 206 case OSL_PRECISION_SP: 207 *(long int *)val1 = *(long int *)val2; 208 break; 209 210 case OSL_PRECISION_DP: 211 *(long long int *)val1 = *(long long int *)val2; 212 break; 213 214#ifdef OSL_GMP_IS_HERE 215 case OSL_PRECISION_MP: 216 mpz_set(*(mpz_t *)val1, *(mpz_t *)val2); 217 break; 218#endif 219 220 default: 221 OSL_error("unknown precision"); 222 } 223} 224 225 226/** 227 * value_base[value_offset] = i; 228 */ 229void osl_int_set_si(int precision, void * value_base, int value_offset, 230 int i) { 231 void * value = osl_int_address(precision, value_base, value_offset); 232 233 switch (precision) { 234 case OSL_PRECISION_SP: 235 *(long int *)value = (long int)i; 236 break; 237 238 case OSL_PRECISION_DP: 239 *(long long int *)value = (long long int)i; 240 break; 241 242#ifdef OSL_GMP_IS_HERE 243 case OSL_PRECISION_MP: 244 mpz_set_si(*(mpz_t *)value, i); 245 break; 246#endif 247 248 default: 249 OSL_error("unknown precision"); 250 } 251} 252 253 254/** 255 * return value_base[value_offset]; 256 */ 257int osl_int_get_si(int precision, void * value_base, int value_offset) { 258 void * value = osl_int_address(precision, value_base, value_offset); 259 260 switch (precision) { 261 case OSL_PRECISION_SP: 262 return *(int *)value; 263 264 case OSL_PRECISION_DP: 265 return *(int *)value; 266 267#ifdef OSL_GMP_IS_HERE 268 case OSL_PRECISION_MP: 269 return mpz_get_si(*(mpz_t *)value); 270#endif 271 272 default: 273 OSL_error("unknown precision"); 274 } 275} 276 277 278/** 279 * value_base[value_offset] = i; // including initialization for GMP 280 */ 281void osl_int_init_set_si(int precision, 282 void * value_base, int value_offset, int i) { 283 void * value = osl_int_address(precision, value_base, value_offset); 284 285 switch (precision) { 286 case OSL_PRECISION_SP: 287 *(long int *)value = (long int)i; 288 break; 289 290 case OSL_PRECISION_DP: 291 *(long long int *)value = (long long int)i; 292 break; 293 294#ifdef OSL_GMP_IS_HERE 295 case OSL_PRECISION_MP: 296 mpz_init_set_si(*(mpz_t *)value, i); 297 break; 298#endif 299 300 default: 301 OSL_error("unknown precision"); 302 } 303} 304 305 306/** 307 * value_base[value_offset] = 0; // Including cleaning for GMP 308 */ 309void osl_int_clear(int precision, void * value_base, int value_offset) { 310 void * value = osl_int_address(precision, value_base, value_offset); 311 312 switch (precision) { 313 case OSL_PRECISION_SP: 314 *(long int *)value = 0; 315 break; 316 317 case OSL_PRECISION_DP: 318 *(long long int *)value = 0; 319 break; 320 321#ifdef OSL_GMP_IS_HERE 322 case OSL_PRECISION_MP: 323 mpz_clear(*(mpz_t *)value); 324 break; 325#endif 326 327 default: 328 OSL_error("unknown precision"); 329 } 330} 331 332 333void osl_int_free(int precision, void * value_base, int value_offset) { 334 void * value = osl_int_address(precision, value_base, value_offset); 335 336 osl_int_clear(precision, value_base, value_offset); 337 free(value); 338} 339 340 341/** 342 * osl_int_print function: 343 * this function displays an integer value into a file (file, possibly stdout). 344 * \param file The file where the integer has to be printed. 345 * \param precision The precision of the integer. 346 * \param value_base Address of the base integer value. 347 * \param value_offset Offset in number of values from the base integer value. 348 */ 349void osl_int_print(FILE * file, int precision, 350 void * value_base, int value_offset) { 351 char string[OSL_MAX_STRING]; 352 353 osl_int_sprint(string, precision, value_base, value_offset); 354 fprintf(file, "%s", string); 355} 356 357 358/** 359 * osl_int_sprint function: 360 * this function prints an integer value into a string, it uses the 361 * OpenScop Library formats OSL_FMT_* to format the printing. 362 * \param string The string where the integer has to be printed. 363 * \param precision The precision of the integer. 364 * \param value_base Address of the base integer value. 365 * \param value_offset Offset in number of values from the base integer value. 366 */ 367void osl_int_sprint(char * string, int precision, 368 void * value_base, int value_offset) { 369 void * value = osl_int_address(precision, value_base, value_offset); 370 371 switch (precision) { 372 case OSL_PRECISION_SP: 373 sprintf(string, OSL_FMT_SP, *(long int *)value); 374 break; 375 376 case OSL_PRECISION_DP: 377 sprintf(string, OSL_FMT_DP, *(long long int *)value); 378 break; 379 380#ifdef OSL_GMP_IS_HERE 381 case OSL_PRECISION_MP: { 382 char * str; 383 str = mpz_get_str(0, 10, *(mpz_t *)value); //TODO: 10 -> #define 384 sprintf(string, OSL_FMT_MP, str); 385 free(str); 386 break; 387 } 388#endif 389 390 default: 391 OSL_error("unknown precision"); 392 } 393} 394 395 396/** 397 * osl_int_sprint_txt function: 398 * this function is similar to osl_int_sprintf but it prints the value 399 * using OSL_TMT_TXT_* formats. 400 * \see osl_int_sprintf 401 */ 402void osl_int_sprint_txt(char * string, int precision, 403 void * value_base, int value_offset) { 404 void * value = osl_int_address(precision, value_base, value_offset); 405 406 switch (precision) { 407 case OSL_PRECISION_SP: 408 sprintf(string, OSL_FMT_TXT_SP, *(long int *)value); 409 break; 410 411 case OSL_PRECISION_DP: 412 sprintf(string, OSL_FMT_TXT_DP, *(long long int *)value); 413 break; 414 415#ifdef OSL_GMP_IS_HERE 416 case OSL_PRECISION_MP: { 417 char * str; 418 str = mpz_get_str(0, 10, *(mpz_t *)value); //TODO: 10 -> #define 419 sprintf(string, OSL_FMT_TXT_MP, str); 420 free(str); 421 break; 422 } 423#endif 424 425 default: 426 OSL_error("unknown precision"); 427 } 428} 429 430 431void osl_int_sread(char ** string, int precision, 432 void * value_base, int value_offset) { 433 void * value = osl_int_address(precision, value_base, value_offset); 434 int nb_read = 0; 435 436 switch (precision) { 437 case OSL_PRECISION_SP: 438 nb_read = sscanf(*string, OSL_FMT_TXT_SP, (long int *)value); 439 if (nb_read == 0) 440 OSL_error("failed to read an integer"); 441 break; 442 443 case OSL_PRECISION_DP: 444 nb_read = sscanf(*string, OSL_FMT_TXT_DP, (long long int *)value); 445 if (nb_read == 0) 446 OSL_error("failed to read an integer"); 447 break; 448 449#ifdef OSL_GMP_IS_HERE 450 case OSL_PRECISION_MP: { 451 long long int tmp; 452 nb_read = sscanf(*string, OSL_FMT_TXT_DP, &tmp); 453 if (nb_read == 0) 454 OSL_error("failed to read an integer"); 455 mpz_set_si(*(mpz_t *)value, tmp); 456 break; 457 } 458#endif 459 460 default: 461 OSL_error("unknown precision"); 462 } 463 464 // Update the position in the input string. 465 *string = *string + nb_read; 466} 467 468 469/*+*************************************************************************** 470 * Arithmetic Operations * 471 *****************************************************************************/ 472 473 474/** 475 * result_base[result_offset] = value_base[value_offset] + 1; 476 */ 477void osl_int_increment(int precision, 478 void * result_base, int result_offset, 479 void * value_base, int value_offset) { 480 void * result = osl_int_address(precision, result_base, result_offset); 481 void * value = osl_int_address(precision, value_base, value_offset); 482 483 switch (precision) { 484 case OSL_PRECISION_SP: 485 *(long int *)result = *(long int *)value + (long int)1; 486 break; 487 488 case OSL_PRECISION_DP: 489 *(long long int *)result = *(long long int *)value + (long long int)1; 490 break; 491 492#ifdef OSL_GMP_IS_HERE 493 case OSL_PRECISION_MP: 494 mpz_add_ui(*(mpz_t *)result, *(mpz_t *)value, 1); 495 break; 496#endif 497 498 default: 499 OSL_error("unknown precision"); 500 } 501} 502 503 504/** 505 * result_base[result_offset] = value_base[value_offset] - 1; 506 */ 507void osl_int_decrement(int precision, 508 void * result_base, int result_offset, 509 void * value_base, int value_offset) { 510 void * result = osl_int_address(precision, result_base, result_offset); 511 void * value = osl_int_address(precision, value_base, value_offset); 512 513 switch (precision) { 514 case OSL_PRECISION_SP: 515 *(long int *)result = *(long int *)value - (long int)1; 516 break; 517 518 case OSL_PRECISION_DP: 519 *(long long int *)result = *(long long int *)value - (long long int)1; 520 break; 521 522#ifdef OSL_GMP_IS_HERE 523 case OSL_PRECISION_MP: { 524 mpz_t one; 525 mpz_init_set_si(one, 1); 526 mpz_sub(*(mpz_t *)result, *(mpz_t *)value, one); 527 mpz_clear(one); 528 break; 529 } 530#endif 531 532 default: 533 OSL_error("unknown precision"); 534 } 535} 536 537 538/** 539 * result_base[result_offset] = val1_base[val1_offset]+val2_base[val2_offset]; 540 */ 541void osl_int_add(int precision, 542 void * result_base, int result_offset, 543 void * val1_base, int val1_offset, 544 void * val2_base, int val2_offset) { 545 void * result = osl_int_address(precision, result_base, result_offset); 546 void * val1 = osl_int_address(precision, val1_base, val1_offset); 547 void * val2 = osl_int_address(precision, val2_base, val2_offset); 548 549 switch (precision) { 550 case OSL_PRECISION_SP: 551 *(long int *)result = *(long int *)val1 + *(long int *)val2; 552 break; 553 554 case OSL_PRECISION_DP: 555 *(long long int *)result = *(long long int *)val1 + 556 *(long long int *)val2; 557 break; 558 559#ifdef OSL_GMP_IS_HERE 560 case OSL_PRECISION_MP: 561 mpz_add(*(mpz_t *)result, *(mpz_t *)val1, *(mpz_t *)val2); 562 break; 563#endif 564 565 default: 566 OSL_error("unknown precision"); 567 } 568} 569 570 571/** 572 * result_base[result_offset] = value_base[value_offset] + i; 573 */ 574void osl_int_add_si(int precision, 575 void * result_base, int result_offset, 576 void * value_base, int value_offset, int i) { 577 void * result = osl_int_address(precision, result_base, result_offset); 578 void * value = osl_int_address(precision, value_base, value_offset); 579 580 switch (precision) { 581 case OSL_PRECISION_SP: 582 *(long int *)result = *(long int *)value + (long int)i; 583 break; 584 585 case OSL_PRECISION_DP: 586 *(long long int *)result = *(long long int *)value + (long long int)i; 587 break; 588 589#ifdef OSL_GMP_IS_HERE 590 case OSL_PRECISION_MP: { 591 mpz_t si; 592 mpz_init_set_si(si, i); 593 mpz_add(*(mpz_t *)result, *(mpz_t *)value, si); 594 mpz_clear(si); 595 break; 596 } 597#endif 598 599 default: 600 OSL_error("unknown precision"); 601 } 602} 603 604 605/** 606 * result_base[result_offset] = val1_base[val1_offset]*val2_base[val2_offset]; 607 */ 608void osl_int_mul(int precision, 609 void * result_base, int result_offset, 610 void * val1_base, int val1_offset, 611 void * val2_base, int val2_offset) { 612 void * result = osl_int_address(precision, result_base, result_offset); 613 void * val1 = osl_int_address(precision, val1_base, val1_offset); 614 void * val2 = osl_int_address(precision, val2_base, val2_offset); 615 616 switch (precision) { 617 case OSL_PRECISION_SP: 618 *(long int *)result = *(long int *)val1 * *(long int *)val2; 619 break; 620 621 case OSL_PRECISION_DP: 622 *(long long int *)result = *(long long int *)val1 * 623 *(long long int *)val2; 624 break; 625 626#ifdef OSL_GMP_IS_HERE 627 case OSL_PRECISION_MP: 628 mpz_mul(*(mpz_t *)result, *(mpz_t *)val1, *(mpz_t *)val2); 629 break; 630#endif 631 632 default: 633 OSL_error("unknown precision"); 634 } 635} 636 637 638/** 639 * result_base[result_offset] = value_base[value_offset] * i; 640 */ 641void osl_int_mul_si(int precision, 642 void * result_base, int result_offset, 643 void * value_base, int value_offset, int i) { 644 void * result = osl_int_address(precision, result_base, result_offset); 645 void * value = osl_int_address(precision, value_base, value_offset); 646 647 switch (precision) { 648 case OSL_PRECISION_SP: 649 *(long int *)result = *(long int *)value * (long int)i; 650 break; 651 652 case OSL_PRECISION_DP: 653 *(long long int *)result = *(long long int *)value * (long long int)i; 654 break; 655 656#ifdef OSL_GMP_IS_HERE 657 case OSL_PRECISION_MP: 658 mpz_mul_si(*(mpz_t *)result, *(mpz_t *)value, i); 659 break; 660#endif 661 662 default: 663 OSL_error("unknown precision"); 664 } 665} 666 667 668/** 669 * result_base[result_offset] = val1_base[val1_offset]-val2_base[val2_offset]; 670 */ 671void osl_int_sub(int precision, 672 void * result_base, int result_offset, 673 void * val1_base, int val1_offset, 674 void * val2_base, int val2_offset) { 675 void * result = osl_int_address(precision, result_base, result_offset); 676 void * val1 = osl_int_address(precision, val1_base, val1_offset); 677 void * val2 = osl_int_address(precision, val2_base, val2_offset); 678 679 switch (precision) { 680 case OSL_PRECISION_SP: 681 *(long int *)result = *(long int *)val1 - *(long int *)val2; 682 break; 683 684 case OSL_PRECISION_DP: 685 *(long long int *)result = *(long long int *)val1 - 686 *(long long int *)val2; 687 break; 688 689#ifdef OSL_GMP_IS_HERE 690 case OSL_PRECISION_MP: 691 mpz_sub(*(mpz_t *)result, *(mpz_t *)val1, *(mpz_t *)val2); 692 break; 693#endif 694 695 default: 696 OSL_error("unknown precision"); 697 } 698} 699 700 701/** 702 * result_base[result_offset] = -value_base[value_offset]; 703 */ 704void osl_int_oppose(int precision, 705 void * result_base, int result_offset, 706 void * value_base, int value_offset) { 707 void * result = osl_int_address(precision, result_base, result_offset); 708 void * value = osl_int_address(precision, value_base, value_offset); 709 710 switch (precision) { 711 case OSL_PRECISION_SP: 712 *(long int *)result = -*(long int *)value; 713 break; 714 715 case OSL_PRECISION_DP: 716 *(long long int *)result = -*(long long int *)value; 717 break; 718 719#ifdef OSL_GMP_IS_HERE 720 case OSL_PRECISION_MP: 721 mpz_neg(*(mpz_t *)result, *(mpz_t *)value); 722 break; 723#endif 724 725 default: 726 OSL_error("unknown precision"); 727 } 728} 729 730 731/*+*************************************************************************** 732 * Conditional Operations * 733 *****************************************************************************/ 734 735 736/** 737 * (val1_base[val1_offset] == val2_base[val2_offset]) 738 */ 739int osl_int_eq(int precision, 740 void * val1_base, int val1_offset, 741 void * val2_base, int val2_offset) { 742 void * val1 = osl_int_address(precision, val1_base, val1_offset); 743 void * val2 = osl_int_address(precision, val2_base, val2_offset); 744 745 switch (precision) { 746 case OSL_PRECISION_SP: 747 return (*(long int *)val1 == *(long int *)val2); 748 749 case OSL_PRECISION_DP: 750 return (*(long long int *)val1 == *(long long int *)val2); 751 752#ifdef OSL_GMP_IS_HERE 753 case OSL_PRECISION_MP: 754 return (mpz_cmp(*(mpz_t *)val1, *(mpz_t *)val2) == 0); 755#endif 756 757 default: 758 OSL_error("unknown precision"); 759 } 760} 761 762 763/** 764 * (val1_base[val1_offset] != val2_base[val2_offset]) 765 */ 766int osl_int_ne(int precision, 767 void * val1_base, int val1_offset, 768 void * val2_base, int val2_offset) { 769 return !osl_int_eq(precision, 770 val1_base, val1_offset, 771 val2_base, val2_offset); 772} 773 774 775/** 776 * (value_base[value_offset] > 0) 777 */ 778int osl_int_pos(int precision, void * value_base, int value_offset) { 779 void * value = osl_int_address(precision, value_base, value_offset); 780 781 switch (precision) { 782 case OSL_PRECISION_SP: 783 return (*(long int *)value > 0); 784 785 case OSL_PRECISION_DP: 786 return (*(long long int *)value > 0); 787 788#ifdef OSL_GMP_IS_HERE 789 case OSL_PRECISION_MP: 790 return (mpz_sgn(*(mpz_t *)value) > 0); 791#endif 792 793 default: 794 OSL_error("unknown precision"); 795 } 796} 797 798 799/** 800 * (value_base[value_offset] < 0) 801 */ 802int osl_int_neg(int precision, void * value_base, int value_offset) { 803 void * value = osl_int_address(precision, value_base, value_offset); 804 805 switch (precision) { 806 case OSL_PRECISION_SP: 807 return (*(long int *)value < 0); 808 809 case OSL_PRECISION_DP: 810 return (*(long long int *)value < 0); 811 812#ifdef OSL_GMP_IS_HERE 813 case OSL_PRECISION_MP: 814 return (mpz_sgn(*(mpz_t *)value) < 0); 815#endif 816 817 default: 818 OSL_error("unknown precision"); 819 } 820} 821 822 823/** 824 * (value_base[value_offset] == 0) 825 */ 826int osl_int_zero(int precision, void * value_base, int value_offset) { 827 void * value = osl_int_address(precision, value_base, value_offset); 828 829 switch (precision) { 830 case OSL_PRECISION_SP: 831 return (*(long int *)value == 0); 832 833 case OSL_PRECISION_DP: 834 return (*(long long int *)value == 0); 835 836#ifdef OSL_GMP_IS_HERE 837 case OSL_PRECISION_MP: 838 return (mpz_sgn(*(mpz_t *)value) == 0); 839#endif 840 841 default: 842 OSL_error("unknown precision"); 843 } 844} 845 846 847/** 848 * (value_base[value_offset] == 1) 849 */ 850int osl_int_one(int precision, void * value_base, int value_offset) { 851 void * value = osl_int_address(precision, value_base, value_offset); 852 853 switch (precision) { 854 case OSL_PRECISION_SP: 855 return (*(long int *)value == (long int)1); 856 857 case OSL_PRECISION_DP: 858 return (*(long long int *)value == (long long int)1); 859 860#ifdef OSL_GMP_IS_HERE 861 case OSL_PRECISION_MP: 862 return (mpz_cmp_si(*(mpz_t *)value, 1) == 0); 863#endif 864 865 default: 866 OSL_error("unknown precision"); 867 } 868} 869 870 871/** 872 * (value_base[value_offset] == -1) 873 */ 874int osl_int_mone(int precision, void * value_base, int value_offset) { 875 void * value = osl_int_address(precision, value_base, value_offset); 876 877 switch (precision) { 878 case OSL_PRECISION_SP: 879 return (*(long int *)value == (long int)-1); 880 881 case OSL_PRECISION_DP: 882 return (*(long long int *)value == (long long int)-1); 883 884#ifdef OSL_GMP_IS_HERE 885 case OSL_PRECISION_MP: 886 return (mpz_cmp_si(*(mpz_t *)value, -1) == 0); 887#endif 888 889 default: 890 OSL_error("unknown precision"); 891 } 892} 893 894 895/** 896 * ((val1_base[val1_offset] % val2_base[val2_offset]) == 0) 897 */ 898int osl_int_divisible(int precision, 899 void * val1_base, int val1_offset, 900 void * val2_base, int val2_offset) { 901 void * val1 = osl_int_address(precision, val1_base, val1_offset); 902 void * val2 = osl_int_address(precision, val2_base, val2_offset); 903 904 switch (precision) { 905 case OSL_PRECISION_SP: 906 return ((*(long int *)val1 % *(long int *)val2) == 0); 907 908 case OSL_PRECISION_DP: 909 return ((*(long long int *)val1 % *(long long int *)val2) == 0); 910 911#ifdef OSL_GMP_IS_HERE 912 case OSL_PRECISION_MP: 913 return mpz_divisible_p(*(mpz_t *)val1, *(mpz_t *)val2); 914#endif 915 916 default: 917 OSL_error("unknown precision"); 918 } 919} 920