• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SRI-CSL / yices2 / 12367760548

17 Dec 2024 06:41AM UTC coverage: 65.285% (-0.6%) from 65.92%
12367760548

push

github

web-flow
Fixes GitHub coverage issue (#544)

* Update action.yml

* Update action.yml

81020 of 124102 relevant lines covered (65.29%)

1509382.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.1
/src/terms/rationals.c
1
/*
2
 * This file is part of the Yices SMT Solver.
3
 * Copyright (C) 2017 SRI International.
4
 *
5
 * Yices is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * Yices is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with Yices.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18

19

20
/*
21
 * Operations on rational numbers
22
 * - rationals are represented as pairs of 32 bit integers
23
 *   or if they are too large as a pointer to a gmp rational.
24
 */
25

26
#include <stdlib.h>
27
#include <stdio.h>
28
#include <stdint.h>
29
#include <stdbool.h>
30
#include <inttypes.h>
31
#include <assert.h>
32
#include <string.h>
33

34
#include <gmp.h>
35

36
#include "mt/yices_locks.h"
37
#include "mt/thread_macros.h"
38
#include "terms/rationals.h"
39
#include "terms/mpq_stores.h"
40
#include "utils/gcd.h"
41

42

43

44
static mpq_store_t  mpq_store;
45

46

47
/*
48
 *  String buffer for parsing.
49
 */
50
#ifdef THREAD_SAFE
51
static yices_lock_t string_buffer_lock;
52
#endif
53
static char* string_buffer = NULL;
54
static uint32_t string_buffer_length = 0;
55

56
/*
57
 * Print an error then abort on division by zero
58
 */
59
static void division_by_zero(void) {
×
60
  fprintf(stderr, "\nRationals: division by zero\n");
×
61
  abort();
×
62
}
63

64

65
/*
66
 * Initialize everything including the string lock
67
 * if we're in thread-safe mode.
68
 */
69
void init_rationals(void){
1,685✔
70
  init_mpq_aux();
1,685✔
71
  init_mpqstore(&mpq_store);
1,685✔
72
#ifdef THREAD_SAFE
73
  create_yices_lock(&string_buffer_lock);
74
#endif
75
  string_buffer = NULL;
1,685✔
76
  string_buffer_length = 0;
1,685✔
77
}
1,685✔
78

79

80
/*
81
 * Cleanup: free memory
82
 */
83
void cleanup_rationals(void){
1,685✔
84
  cleanup_mpq_aux();
1,685✔
85
  delete_mpqstore(&mpq_store);
1,685✔
86
#ifdef THREAD_SAFE
87
  destroy_yices_lock(&string_buffer_lock);
88
#endif
89
  safe_free(string_buffer);
1,685✔
90
}
1,685✔
91

92

93
/*************************
94
 *  MPQ ALLOCATION/FREE  *
95
 ************************/
96

97
/*
98
 * Allocates a new mpq object.
99
 */
100
static inline mpq_ptr new_mpq(void){
6,461,797✔
101
  return mpqstore_alloc(&mpq_store);
6,461,797✔
102
}
103

104

105
/*
106
 * Deallocates a new mpq object
107
 */
108
static void release_mpq(rational_t *r){
6,365,667✔
109
  assert(is_ratgmp(r));
110
  mpqstore_free(&mpq_store, get_gmp(r));
6,365,667✔
111
}
6,365,667✔
112

113

114
/*
115
 * Free mpq number attached to r if any, then set r to 0/1.
116
 * Must be called before r is deleted to prevent memory leaks.
117
 */
118
void q_clear(rational_t *r) {
228,423,895✔
119
  if (is_ratgmp(r)) {
228,423,895✔
120
    release_mpq(r);
6,190,032✔
121
  }
122
  r->s.num = 0;
228,423,895✔
123
  r->s.den = ONE_DEN;
228,423,895✔
124
}
228,423,895✔
125

126

127

128
/*******************
129
 *  NORMALIZATION  *
130
 ******************/
131

132
/*
133
 * Bounds on numerator and denominators.
134
 *
135
 * a/b can be safely stored as a pair (int32_t/uint32_t)
136
 * if MIN_NUMERATOR <= a <= MAX_NUMERATOR
137
 * and 1 <= b <= MAX_DENOMINATOR
138
 *
139
 * otherwise a/b must be stored as a gmp rational.
140
 *
141
 * The bounds are such that
142
 * - (a/1)+(b/1), (a/1) - (b/1) can be computed using
143
 *   32bit arithmetic without overflow.
144
 * - a/b stored as a pair implies -a/b and b/a can be stored
145
 *   as pairs too.
146
 */
147
#define MAX_NUMERATOR (INT32_MAX>>1)
148
#define MIN_NUMERATOR (-MAX_NUMERATOR)
149
#define MAX_DENOMINATOR MAX_NUMERATOR
150

151

152
/*
153
 * Store num/den in r
154
 */
155
static inline void set_rat32(rational_t *r, int32_t num, uint32_t den) {
158,823,627✔
156
  assert(MIN_NUMERATOR <= num && num <= MAX_NUMERATOR && den <= MAX_DENOMINATOR);
157
  r->s.den = den << 1;
158,823,627✔
158
  r->s.num = num;
158,823,627✔
159
}
158,823,627✔
160

161

162
/*
163
 * Normalization: construct rational a/b when
164
 * a and b are two 64bit numbers.
165
 * - b must be non-zero
166
 */
167
void q_set_int64(rational_t *r, int64_t a, uint64_t b) {
156,121,508✔
168
  uint64_t abs_a;
169
  mpq_ptr q;
170
  bool a_positive;
171

172
  assert(b > 0);
173

174
  if (a == 0 || (b == 1 && MIN_NUMERATOR <= a && a <= MAX_NUMERATOR)) {
156,121,508✔
175
    if (is_ratgmp(r)) {
32,246,840✔
176
      release_mpq(r);
×
177
    }
178
    set_rat32(r, a, 1);
32,246,840✔
179
    return;
32,246,840✔
180
  }
181

182
  // absolute value and sign of a.
183
  if (a >= 0) {
123,874,668✔
184
    abs_a = (uint64_t) a;
61,942,580✔
185
    a_positive = true;
61,942,580✔
186
  } else {
187
    abs_a = (uint64_t) - a; // Note: this works even when a = -2^63
61,932,088✔
188
    a_positive = false;
61,932,088✔
189
  }
190

191
  // abs_a and b are positive. remove powers of 2
192
  while (((abs_a | b) & 15) == 0) {
124,975,916✔
193
    abs_a >>= 4;
1,101,248✔
194
    b >>= 4;
1,101,248✔
195
  }
196
  switch ((abs_a | b) & 7) {
123,874,668✔
197
  case 0: abs_a >>= 3; b >>= 3; break;
1,106,443✔
198
  case 1: break;
2,509,801✔
199
  case 2: abs_a >>= 1; b >>= 1; break;
13,316,019✔
200
  case 3: break;
25,296,728✔
201
  case 4: abs_a >>= 2; b >>= 2; break;
10,104,823✔
202
  case 5: break;
5,720,621✔
203
  case 6: abs_a >>= 1; b >>= 1; break;
18,902,468✔
204
  case 7: break;
46,917,765✔
205
  }
206

207
  // abs_a and b are positive, and at least one of them is odd.
208
  // if abs_a <= 2 or b <= 2 then gcd = 1.
209
  if (abs_a > 2 && b > 2) {
123,874,668✔
210
    uint64_t a_1 = abs_a;
45,058,807✔
211
    uint64_t b_1 = b;
45,058,807✔
212

213
    // compute gcd of abs_a and b
214
    // loop invariant: abs_a is odd or b is odd (or both)
215
    for (;;) {
216
      if ((a_1 & 1) == 0) {
301,952,637✔
217
        a_1 >>= 1;
76,777,220✔
218
      } else if ((b_1 & 1) == 0) {
225,175,417✔
219
        b_1 >>= 1;
55,220,046✔
220
      } else if (a_1 >= b_1) {
169,955,371✔
221
        a_1 = (a_1 - b_1) >> 1;
109,721,523✔
222
        if (a_1 == 0) break;
109,721,523✔
223
      } else {
224
        b_1 = (b_1 - a_1) >> 1;
60,233,848✔
225
      }
226
    }
227

228
    // b_1 is gcd(abs_a, b)
229
    if (b_1 != 1) {
45,058,807✔
230
      abs_a /= b_1;
25,296,821✔
231
      b /= b_1;
25,296,821✔
232
    }
233
  }
234

235
  // abs_a and b are mutually prime and positive
236

237
  // restore a
238
  a = a_positive ? ((int64_t) abs_a) : - ((int64_t) abs_a);
123,874,668✔
239

240
  // assign to r
241
  if (abs_a <= MAX_NUMERATOR && b <= MAX_DENOMINATOR) {
123,874,668✔
242
    if (is_ratgmp(r)) {
123,871,406✔
243
      release_mpq(r);
×
244
    }
245
    set_rat32(r, (int32_t) a, (uint32_t) b);
123,871,406✔
246
  } else {
247
    if (is_ratgmp(r)) {
3,262✔
248
      q = get_gmp(r);
×
249
    } else {
250
      q = new_mpq();
3,262✔
251
      set_ratgmp(r, q);
3,262✔
252
    }
253
    mpq_set_int64(q, a, b);
3,262✔
254
  }
255
}
256

257

258

259
/*
260
 * Normalization: construct a/b when a and b are 32 bits
261
 */
262
void q_set_int32(rational_t *r, int32_t a, uint32_t b) {
60✔
263
  uint32_t abs_a;
264
  mpq_ptr q;
265
  bool a_positive;
266

267
  assert(b > 0);
268

269
  if (a == 0 || (b == 1 && MIN_NUMERATOR <= a && a <= MAX_NUMERATOR)) {
60✔
270
    if (is_ratgmp(r)) {
3✔
271
      release_mpq(r);
×
272
    }
273
    set_rat32(r, a, 1);
3✔
274
    return;
3✔
275
  }
276

277
  // absolute value and sign of a.
278
  if (a >= 0) {
57✔
279
    abs_a = (uint32_t) a;
57✔
280
    a_positive = true;
57✔
281
  } else {
282
    abs_a = (uint32_t) - a; // Note: this works even when a = -2^31
×
283
    a_positive = false;
×
284
  }
285

286
  // abs_a and b are positive. remove powers of 2
287
  while (((abs_a | b) & 15) == 0) {
57✔
288
    abs_a >>= 4;
×
289
    b >>= 4;
×
290
  }
291
  switch ((abs_a | b) & 7) {
57✔
292
  case 0: abs_a >>= 3; b >>= 3; break;
×
293
  case 1: break;
×
294
  case 2: abs_a >>= 1; b >>= 1; break;
×
295
  case 3: break;
2✔
296
  case 4: abs_a >>= 2; b >>= 2; break;
×
297
  case 5: break;
55✔
298
  case 6: abs_a >>= 1; b >>= 1; break;
×
299
  case 7: break;
×
300
  }
301

302
  // abs_a and b are positive, and at least one of them is odd.
303
  // if abs_a <= 2 or b <= 2 then gcd = 1.
304
  if (abs_a > 2 && b > 2) {
57✔
305
    uint32_t a_1 = abs_a;
×
306
    uint32_t b_1 = b;
×
307

308
    // compute gcd of abs_a and b
309
    // loop invariant: abs_a is odd or b is odd (or both)
310
    for (;;) {
311
      if ((a_1 & 1) == 0) {
×
312
        a_1 >>= 1;
×
313
      } else if ((b_1 & 1) == 0) {
×
314
        b_1 >>= 1;
×
315
      } else if (a_1 >= b_1) {
×
316
        a_1 = (a_1 - b_1) >> 1;
×
317
        if (a_1 == 0) break;
×
318

319
      } else {
320
        b_1 = (b_1 - a_1) >> 1;
×
321
      }
322
    }
323

324
    // b_1 is gcd(abs_a, b)
325
    if (b_1 != 1) {
×
326
      abs_a /= b_1;
×
327
      b /= b_1;
×
328
    }
329
  }
330

331
  // abs_a and b are mutually prime and positive
332

333
  // restore a
334
  a = a_positive ? ((int32_t) abs_a) : - ((int32_t) abs_a);
57✔
335

336
  // assign to r
337
  if (abs_a <= MAX_NUMERATOR && b <= MAX_DENOMINATOR) {
57✔
338
    if (is_ratgmp(r)) {
57✔
339
      release_mpq(r);
2✔
340
    }
341
    set_rat32(r, (int32_t) a, (uint32_t) b);
57✔
342
  } else {
343
    if (is_ratgmp(r)) {
×
344
      q = get_gmp(r);
×
345
    } else {
346
      q = new_mpq();
×
347
      set_ratgmp(r, q);
×
348
    }
349
    mpq_set_int32(q, a, b);
×
350
  }
351
}
352

353

354
/*
355
 * Construct r = a/1
356
 */
357
void q_set64(rational_t *r, int64_t a) {
×
358
  mpq_ptr q;
359

360
  if (MIN_NUMERATOR <= a && a <= MAX_NUMERATOR) {
×
361
    if (is_ratgmp(r)){ release_mpq(r); }
×
362
    set_rat32(r, (int32_t) a, 1);
×
363
  } else {
364
    if (!is_ratgmp(r)) {
×
365
      q = new_mpq();
×
366
      set_ratgmp(r, q);
×
367
    } else {
368
      q = get_gmp(r);
×
369
    }
370
    mpq_set_int64(q, a, 1);
×
371
  }
372
}
×
373

374
void q_set32(rational_t *r, int32_t a) {
345,427✔
375
  mpq_ptr q;
376

377
  if (MIN_NUMERATOR <= a && a <= MAX_NUMERATOR) {
345,427✔
378
    if (is_ratgmp(r)) { release_mpq(r); }
345,427✔
379
    set_rat32(r, a, 1);
345,427✔
380
  } else {
381
    if (!is_ratgmp(r)) {
×
382
      q = new_mpq();
×
383
      set_ratgmp(r, q);
×
384
    } else {
385
      q = get_gmp(r);
×
386
    }
387
    mpq_set_int32(q, a, 1);
×
388
  }
389
}
345,427✔
390

391

392

393
/*
394
 * Convert r to a gmp number.
395
 * r->num and r->den must have no common factor
396
 * and r->den must be non-zero.
397
 */
398
static void convert_to_gmp(rational_t *r) {
1,092,781✔
399
  mpq_ptr q;
400

401
  assert(!is_ratgmp(r));
402

403
  q = new_mpq();
1,092,781✔
404
  mpq_set_int32(q, get_num(r), get_den(r));
1,092,781✔
405
  set_ratgmp(r, q);
1,092,781✔
406
}
1,092,781✔
407

408

409
/*
410
 * Set r to a gmp with value = a.
411
 */
412
static void set_to_gmp64(rational_t *r, int64_t a) {
1,955✔
413
  mpq_ptr q;
414

415
  assert(!is_ratgmp(r));
416

417
  q = new_mpq();
1,955✔
418
  mpq_set_int64(q, a, 1);
1,955✔
419
  set_ratgmp(r, q);
1,955✔
420
}
1,955✔
421

422

423
/*****************
424
 *  ASSIGNMENTS  *
425
 ****************/
426

427

428
/*
429
 * Convert mpq to a pair of integers if possible.
430
 */
431
void q_normalize(rational_t *r) {
203,033✔
432
  mpq_ptr q;
433
  unsigned long den;
434
  long num;
435

436
  if (is_ratgmp(r)) {
203,033✔
437
    q = get_gmp(r);
107,241✔
438
    if (mpz_fits_ulong_p(mpq_denref(q)) && mpz_fits_slong_p(mpq_numref(q))) {
107,241✔
439
      num = mpz_get_si(mpq_numref(q));
105,348✔
440
      den = mpz_get_ui(mpq_denref(q));
105,348✔
441
      if (MIN_NUMERATOR <= num && num <= MAX_NUMERATOR && den <= MAX_DENOMINATOR) {
105,348✔
442
              mpqstore_free(&mpq_store, q);
96,075✔
443
        set_rat32(r, (int32_t) num, (uint32_t) den);
96,075✔
444
      }
445
    }
446
  }
447
}
203,033✔
448

449
static void q_denormalize(rational_t *r) {
486✔
450
  mpq_ptr q;
451

452
  if (is_rat32(r)) {
486✔
453
    q = new_mpq();
486✔
454
    mpq_set_si(q, get_num(r), get_den(r));
486✔
455
    set_ratgmp(r, q);
486✔
456
  }
457
  assert(is_ratgmp(r));
458
}
486✔
459

460
/*
461
 * Prepare to assign an mpq number to r
462
 * - if r is not a mpq number, allocate it
463
 */
464
static inline void q_prepare(rational_t *r) {
6,459,603✔
465
  if (!is_ratgmp(r)) {
6,459,603✔
466
    set_ratgmp(r, new_mpq());
5,363,304✔
467
  }
468
}
6,459,603✔
469

470
/*
471
 * assign r:= z/1
472
 */
473
void q_set_mpz(rational_t *r, const mpz_t z) {
17,334✔
474
  mpq_ptr q;
475

476
  q_prepare(r);
17,334✔
477
  q = get_gmp(r);
17,334✔
478
  mpq_set_z(q, z);
17,334✔
479
  q_normalize(r);
17,334✔
480
}
17,334✔
481

482
/*
483
 * Copy q into r
484
 */
485
void q_set_mpq(rational_t *r, const mpq_t q) {
41✔
486
  mpq_ptr qt;
487

488
  q_prepare(r);
41✔
489
  qt = get_gmp(r);
41✔
490
  mpq_set(qt, q);
41✔
491
  q_normalize(r);
41✔
492
}
41✔
493

494
/*
495
 * Copy r2 into r1
496
 */
497
void q_set(rational_t *r1, const rational_t *r2) {
166,507,057✔
498
  mpq_ptr q1, q2;
499

500
  if (is_ratgmp(r2)) {
166,507,057✔
501
    q_prepare(r1);
5,627,760✔
502
    q1 = get_gmp(r1);
5,627,760✔
503
    q2 = get_gmp(r2);
5,627,760✔
504
    mpq_set(q1, q2);
5,627,760✔
505
  } else {
506
    if (is_ratgmp(r1)) {
160,879,297✔
507
      release_mpq(r1);
133,464✔
508
    }
509
    r1->s.num = r2->s.num;
160,879,297✔
510
    r1->s.den = r2->s.den;
160,879,297✔
511
  }
512
}
166,507,057✔
513

514
/*
515
 * Copy opposite of r2 into r1
516
 */
517
void q_set_neg(rational_t *r1, const rational_t *r2) {
47,981,473✔
518
  mpq_ptr q1, q2;
519

520
  if (is_ratgmp(r2)) {
47,981,473✔
521
    q_prepare(r1);
780,620✔
522
    q1 = get_gmp(r1);
780,620✔
523
    q2 = get_gmp(r2);
780,620✔
524
    mpq_neg(q1, q2);
780,620✔
525
  } else {
526
    if (is_ratgmp(r1)) {
47,200,853✔
527
      release_mpq(r1);
7,556✔
528
    }
529
    r1->s.num = - r2->s.num;
47,200,853✔
530
    r1->s.den = r2->s.den;
47,200,853✔
531
  }
532
}
47,981,473✔
533

534
/*
535
 * Copy the absolute value of r2 into r1
536
 */
537
void q_set_abs(rational_t *r1, const rational_t *r2) {
192,206✔
538
  if (is_ratgmp(r2)) {
192,206✔
539
    mpq_ptr q1;
540
    mpq_ptr q2;
541
    q_prepare(r1);
167✔
542
    q1 = get_gmp(r1);
167✔
543
    q2 = get_gmp(r2);
167✔
544
    mpq_abs(q1, q2);
167✔
545
  } else {
546
    if (is_ratgmp(r1)) {
192,039✔
547
      release_mpq(r1);
×
548
    }
549
    r1->s.den = r2->s.den;
192,039✔
550
    if (r2->s.num < 0) {
192,039✔
551
      r1->s.num = - r2->s.num;
178,616✔
552
    } else {
553
      r1->s.num = r2->s.num;
13,423✔
554
    }
555
  }
556
}
192,206✔
557

558
/*
559
 * Copy the numerator of r2 into r1
560
 * - r1 must be initialized
561
 * - r2 and r1 must be different objects
562
 */
563
void q_get_num(rational_t *r1, const rational_t *r2) {
195,088✔
564
  mpq_ptr q1, q2;
565
  long num;
566

567
  if (is_ratgmp(r2)) {
195,088✔
568
    q2 = get_gmp(r2);
40,261✔
569
    if (mpz_fits_slong_p(mpq_numref(q2))) {
40,261✔
570
      num = mpz_get_si(mpq_numref(q2));
40,094✔
571
      if (MIN_NUMERATOR <= num && num <= MAX_NUMERATOR) {
40,094✔
572
        if (is_ratgmp(r1)){ release_mpq(r1); }
37,513✔
573
        set_rat32(r1, num, 1);
37,513✔
574
        return;
37,513✔
575
      }
576
    }
577
    q_prepare(r1);
2,748✔
578
    q1 = get_gmp(r1);
2,748✔
579
    mpq_set_z(q1,  mpq_numref(q2));
2,748✔
580
  } else {
581
    if (is_ratgmp(r1)){ release_mpq(r1); }
154,827✔
582
    set_rat32(r1, get_num(r2), 1);
154,827✔
583
  }
584
}
585

586

587
/*
588
 * Copy the denominator of r2 into r1
589
 * - r1 must be initialized
590
 * - r1 and r2 must be different objects
591
 */
592
void q_get_den(rational_t *r1, const rational_t *r2) {
1,049,594✔
593
  mpq_ptr q1, q2;
594
  unsigned long den;
595

596
  if (is_ratgmp(r2)) {
1,049,594✔
597
    q2 = get_gmp(r2);
443,944✔
598
    if (mpz_fits_ulong_p(mpq_denref(q2))) {
443,944✔
599
      den = mpz_get_ui(mpq_denref(q2));
443,813✔
600
      if (den <= MAX_DENOMINATOR) {
443,813✔
601
        if (is_ratgmp(r1)){ release_mpq(r1); }
416,615✔
602
        r1->s.num = den;
416,615✔
603
        r1->s.den = ONE_DEN;
416,615✔
604
        return;
416,615✔
605
      }
606
    }
607
    q_prepare(r1);
27,329✔
608
    q1 = get_gmp(r1);
27,329✔
609
    mpq_set_z(q1, mpq_denref(q2));
27,329✔
610

611
  } else {
612
    if (is_ratgmp(r1)){ release_mpq(r1); }
605,650✔
613
    r1->s.num = get_den(r2);
605,650✔
614
    r1->s.den = ONE_DEN;
605,650✔
615
  }
616
}
617

618

619
/*******************************************
620
 *  PARSING: CONVERT STRINGS TO RATIONALS  *
621
 ******************************************/
622

623
/*
624
 * Resize string_buffer if necessary
625
 */
626
static void resize_string_buffer(uint32_t new_size) {
10,402✔
627
  uint32_t n;
628

629
  if (string_buffer_length < new_size) {
10,402✔
630
    /*
631
     * try to make buffer 50% larger
632
     * in principle the n += n >> 1 could overflow but
633
     * then (n < new_size) will be true
634
     * so n will be fixed to new_size.
635
     *
636
     * all this is very unlikely to happen in practice
637
     * (this would require extremely large strings).
638
     */
639
    n = string_buffer_length + 1;
1,145✔
640
    n += n >> 1;
1,145✔
641
    if (n < new_size) n = new_size;
1,145✔
642

643
    string_buffer = (char *) safe_realloc(string_buffer, n);
1,145✔
644
    string_buffer_length = n;
1,145✔
645
  }
646
}
10,402✔
647

648

649
/*
650
 * Assign q0 to r and try to convert to a pair of integers.
651
 * - q0 must be canonicalized
652
 * - return 0.
653
 */
654
static int q_set_q0(rational_t *r, mpq_t *q0) {
321,623✔
655
  mpq_ptr q;
656
  unsigned long den;
657
  long num;
658

659
  // try to store q0 as a pair num/den
660
  if (mpz_fits_ulong_p(mpq_denref(*q0)) && mpz_fits_slong_p(mpq_numref(*q0))) {
321,623✔
661
    num = mpz_get_si(mpq_numref(*q0));
319,797✔
662
    den = mpz_get_ui(mpq_denref(*q0));
319,797✔
663
    if (MIN_NUMERATOR <= num && num <= MAX_NUMERATOR && den <= MAX_DENOMINATOR) {
319,797✔
664
      if (is_ratgmp(r)){ release_mpq(r); }
318,019✔
665
      set_rat32(r, (int32_t) num, (uint32_t) den);
318,019✔
666
      return 0;
318,019✔
667
    }
668
  }
669

670
  // copy q0
671
  if (!is_ratgmp(r)) {
3,604✔
672
    q_prepare(r);
3,604✔
673
  }
674
  q = get_gmp(r);
3,604✔
675
  mpq_set(q, *q0);
3,604✔
676
  return 0;
3,604✔
677
}
678

679
/*
680
 * Conversion from a string in format supported by gmp:
681
 *   <+/->numerator/denominator or <+/->numerator
682
 * with numerator and denominator in base 10.
683
 * - returns -1 and leaves r unchanged if s is not in that format
684
 * - returns -2 and leaves r unchanged if the denominator is zero
685
 * - returns 0 otherwise
686
 */
687
int q_set_from_string(rational_t *r, const char *s) {
311,221✔
688
  int retval;
689
  mpq_t q0;
690

691
  mpq_init2(q0, 64);
311,221✔
692
  // GMP rejects an initial '+' so skip it
693
  if (*s == '+') s ++;
311,221✔
694
  if (mpq_set_str(q0, s, 10) < 0){
311,221✔
695
    retval = -1;
×
696
    goto clean_up;
×
697
  }
698
  if (mpz_sgn(mpq_denref(q0)) == 0){
311,221✔
699
    retval = -2; // the denominator is zero
×
700
    goto clean_up;
×
701
  }
702
  mpq_canonicalize(q0);
311,221✔
703
  retval = q_set_q0(r, &q0);
311,221✔
704

705
 clean_up:
311,221✔
706
  mpq_clear(q0);
311,221✔
707
  return retval;
311,221✔
708
}
709

710
/*
711
 * Conversion from a string using the given base.
712
 * Base is interpreted as in gmp: either 0 or an integer from 2 to 36.
713
 * If base = 0, then the base is determined independently for the
714
 * numerator and denominator from the first characters.
715
 * Prefixes  0x or 0b or 0 indicate base 16, 2, or 8,
716
 * otherwise, the base is 10.
717
 */
718
int q_set_from_string_base(rational_t *r, const char *s, int32_t base) {
×
719
  int retval;
720
  mpq_t q0;
721

722
  mpq_init2(q0, 64);
×
723

724

725
  // GMP rejects an initial '+' so skip it
726
  if (*s == '+') s ++;
×
727
  assert(0 == base || (2 <= base && base <= 36));
728
  if (mpq_set_str(q0, s, base) < 0){
×
729
    retval = -1;
×
730
    goto clean_up;
×
731
  }
732
  if (mpz_sgn(mpq_denref(q0)) == 0){
×
733
    retval = -2; // the denominator is zero
×
734
    goto clean_up;
×
735
  }
736
  mpq_canonicalize(q0);
×
737
  retval = q_set_q0(r, &q0);
×
738

739
 clean_up:
×
740

741
  mpq_clear(q0);
×
742
  return retval;
×
743

744
}
745

746

747
/*
748
 * Portable replacement for strtol that we use below to parse an exponent.
749
 * The input string must have a non-empty prefix of the form
750
 *     <optional sign> <digits>
751
 * without space.
752
 *
753
 * Portability issues with strtol
754
 * On some systems strtol("xxx", ..., 10) sets errno to EINVAL
755
 * On other systems strtol("xxx", ..., 10) returns 0 and doesn't set errno.
756
 */
757
static bool parse_exponent(const char *s, long *result) {
×
758
  unsigned long x, y;
759
  int digit;;
760
  char c;
761
  bool ok, positive;
762

763
  positive = true;
×
764
  ok = false;
×
765

766
  c = *s ++;
×
767
  if (c == '-') {
×
768
    positive = false;
×
769
    c = *s ++;
×
770
  } else if (c == '+') {
×
771
    c = *s ++;
×
772
  }
773

774
  x = 0;
×
775
  while ('0' <= c && c <= '9') {
×
776
    ok = true;
×
777
    digit = c - '0';
×
778
    y = 10*x + digit;
×
779
    if (y < x) {
×
780
      // overflow
781
      ok = false;
×
782
      break;
×
783
    }
784
    x = y;
×
785
    c = *s ++;
×
786
  }
787

788
  if (ok) {
×
789
    if (positive && x <= (unsigned long) LONG_MAX) {
×
790
      *result = (long) x;
×
791
      return true;
×
792
    }
793
    if (!positive && x <= (unsigned long) LONG_MIN) {
×
794
      *result = (long) (- x);
×
795
      return true;
×
796
    }
797
  }
798

799
  return false;
×
800
}
801

802

803
/*
804
 * Conversion from a string in a floating point format
805
 * The expected format is one of
806
 *   <optional sign> <integer part> . <fractional part>
807
 *   <optional sign> <integer part> <exp> <optional sign> <integer>
808
 *   <optional sign> <integer part> . <fractional part> <exp> <optional sign> <integer>
809
 *
810
 * Where <optional sign> is + or - and <exp> is either 'e' or 'E'
811
 *
812
 * - returns -1 and leaves r unchanged if the string is not in that format
813
 * - returns 0 otherwise
814
 */
815
static int _o_q_set_from_float_string(rational_t *r, const char *s) {
10,402✔
816
  size_t len;
817
  int frac_len, sign;
818
  long int exponent;
819
  char *b, c;
820
  int retval;
821
  mpz_t z0;
822
  mpq_t q0;
823

824
  mpz_init2(z0, 64);
10,402✔
825
  mpq_init2(q0, 64);
10,402✔
826

827
  len = strlen(s);
10,402✔
828
  if (len >= (size_t) UINT32_MAX) {
10,402✔
829
    // just to be safe if s is really long
830
    out_of_memory();
×
831
  }
832
  resize_string_buffer(len + 1);
10,402✔
833
  c = *s ++;
10,402✔
834

835
  // get sign
836
  sign = 1;
10,402✔
837
  if (c == '-') {
10,402✔
838
    sign = -1;
×
839
    c = * s++;
×
840
  } else if (c == '+') {
10,402✔
841
    c = * s ++;
×
842
  }
843

844
  // copy integer part into buffer.
845
  b = string_buffer;
10,402✔
846
  while ('0' <= c && c <= '9') {
34,415✔
847
    *b ++ = c;
24,013✔
848
    c = * s ++;
24,013✔
849
  }
850

851
  // copy fractional part and count its length
852
  frac_len = 0;
10,402✔
853
  if (c == '.') {
10,402✔
854
    c = *s ++;
10,402✔
855
    while ('0' <= c && c <= '9') {
21,317✔
856
      frac_len ++;
10,915✔
857
      *b ++ = c;
10,915✔
858
      c = * s ++;
10,915✔
859
    }
860
  }
861
  *b = '\0'; // end of buffer
10,402✔
862

863
  // check and read exponent
864
  exponent = 0;
10,402✔
865
  if (c == 'e' || c == 'E') {
10,402✔
866
    if (!parse_exponent(s, &exponent)) {
×
867
      retval =  -1;
×
868
      goto clean_up;
×
869
    }
870
  }
871

872
#if 0
873
  printf("--> Float conversion\n");
874
  printf("--> sign = %d\n", sign);
875
  printf("--> mantissa = %s\n", string_buffer);
876
  printf("--> frac_len = %d\n", frac_len);
877
  printf("--> exponent = %ld\n", exponent);
878
#endif
879

880
  mpq_set_ui(q0, 0, 1);
10,402✔
881

882
  // set numerator
883
  if (mpz_set_str(mpq_numref(q0), string_buffer, 10) < 0) {
10,402✔
884
    retval =  -1;
×
885
    goto clean_up;
×
886
  }
887
  if (sign < 0) {
10,402✔
888
    mpq_neg(q0, q0);
×
889
  }
890

891
  // multiply by 10^exponent
892
  exponent -= frac_len;
10,402✔
893
  if (exponent > 0) {
10,402✔
894
    mpz_ui_pow_ui(z0, 10, exponent);
×
895
    mpz_mul(mpq_numref(q0), mpq_numref(q0), z0);
×
896
  } else if (exponent < 0) {
10,402✔
897
    // this works even if exponent == LONG_MIN.
898
    mpz_ui_pow_ui(mpq_denref(q0), 10UL, (unsigned long) (- exponent));
10,402✔
899
    mpq_canonicalize(q0);
10,402✔
900
  }
901

902
  retval = q_set_q0(r, &q0);
10,402✔
903

904
 clean_up:
10,402✔
905

906
  mpz_clear(z0);
10,402✔
907
  mpq_clear(q0);
10,402✔
908

909
  return retval;
10,402✔
910

911
}
912

913
int q_set_from_float_string(rational_t *r, const char *s) {
10,402✔
914
  MT_PROTECT(int, string_buffer_lock, _o_q_set_from_float_string(r, s));
10,402✔
915
}
916

917

918
/****************
919
 *  ARITHMETIC  *
920
 ***************/
921

922
/*
923
 * Add r2 to r1
924
 */
925
void q_add(rational_t *r1, const rational_t *r2) {
33,072,199✔
926
  uint64_t den;
927
  int64_t num;
928
  mpq_ptr q1, q2;
929

930
  if (r1->s.den == ONE_DEN && r2->s.den == ONE_DEN) {
33,072,199✔
931
    assert(is_rat32(r2) && is_rat32(r1));
932
    r1->s.num += r2->s.num;
24,093,305✔
933
    if (r1->s.num < MIN_NUMERATOR || r1->s.num > MAX_NUMERATOR) {
24,093,305✔
934
      convert_to_gmp(r1);
×
935
    }
936
    return;
24,093,305✔
937
  }
938

939
  if (is_ratgmp(r2)) {
8,978,894✔
940
    if (!is_ratgmp(r1)) convert_to_gmp(r1) ;
1,307,439✔
941
    q1 = get_gmp(r1);
1,307,439✔
942
    q2 = get_gmp(r2);
1,307,439✔
943
    mpq_add(q1, q1, q2);
1,307,439✔
944
  } else if (is_ratgmp(r1)) {
7,671,455✔
945
    q1 = get_gmp(r1);
90,208✔
946
    mpq_add_si(q1, get_num(r2), get_den(r2));
90,208✔
947
  } else {
948
    den = get_den(r1) * ((uint64_t) get_den(r2));
7,581,247✔
949
    num = get_den(r1) * ((int64_t) get_num(r2)) + get_den(r2) * ((int64_t) get_num(r1));
7,581,247✔
950
    q_set_int64(r1, num, den);
7,581,247✔
951
  }
952
}
953

954
/*
955
 * Subtract r2 from r1
956
 */
957
void q_sub(rational_t *r1, const rational_t *r2) {
95,560,346✔
958
  uint64_t den;
959
  int64_t num;
960
  mpq_ptr q1, q2;
961

962
  if (r1->s.den == ONE_DEN && r2->s.den == ONE_DEN) {
95,560,346✔
963
    assert(is_rat32(r1)  &&  is_rat32(r2));
964
    r1->s.num -= r2->s.num;
37,471,909✔
965
    if (r1->s.num < MIN_NUMERATOR || r1->s.num > MAX_NUMERATOR) {
37,471,909✔
966
      convert_to_gmp(r1);
×
967
    }
968
    return;
37,471,909✔
969
  }
970

971
  if (is_ratgmp(r2)) {
58,088,437✔
972
    if (!is_ratgmp(r1)) convert_to_gmp(r1);
4,453,178✔
973
    q1 = get_gmp(r1);
4,453,178✔
974
    q2 = get_gmp(r2);
4,453,178✔
975
    mpq_sub(q1, q1, q2);
4,453,178✔
976
  } else if (is_ratgmp(r1)) {
53,635,259✔
977
    q1 = get_gmp(r1);
30,891✔
978
    mpq_sub_si(q1, get_num(r2), get_den(r2));
30,891✔
979
  } else {
980
    den = get_den(r1) * ((uint64_t) get_den(r2));
53,604,368✔
981
    num = get_den(r2) * ((int64_t) get_num(r1)) - get_den(r1) * ((int64_t)get_num(r2));
53,604,368✔
982
    q_set_int64(r1, num, den);
53,604,368✔
983
  }
984
}
985

986
/*
987
 * Negate r
988
 */
989
void q_neg(rational_t *r) {
9,944,523✔
990
  if (is_ratgmp(r)){
9,944,523✔
991
    mpq_ptr q = get_gmp(r);
228,541✔
992
    mpq_neg(q, q);
228,541✔
993
  } else {
994
    r->s.num = - r->s.num;
9,715,982✔
995
  }
996
}
9,944,523✔
997

998
/*
999
 * Invert r
1000
 */
1001
void q_inv(rational_t *r) {
314,375✔
1002
  uint32_t abs_num;
1003

1004
  if (is_ratgmp(r)) {
314,375✔
1005
    mpq_ptr q = get_gmp(r);
5,211✔
1006
    mpq_inv(q, q);
5,211✔
1007
  } else if (r->s.num < 0) {
309,164✔
1008
    abs_num = (uint32_t) - r->s.num;
185,261✔
1009
    set_rat32(r, - get_den(r), abs_num);
185,261✔
1010
  } else if (r->s.num > 0) {
123,903✔
1011
    abs_num = (uint32_t) r->s.num;
123,903✔
1012
    set_rat32(r, get_den(r), abs_num);
123,903✔
1013
  } else {
1014
    division_by_zero();
×
1015
  }
1016
}
314,375✔
1017

1018
/*
1019
 * Invert r mod m
1020
 */
1021
void q_inv_mod(rational_t *r, const rational_t *mod) {
243✔
1022
  assert(q_is_integer(r) && q_is_integer(mod) && q_is_pos(mod));
1023

1024
  rational_t tmp, *mm;
1025
  if (is_rat32(mod)) {
243✔
1026
    tmp = *mod; mm = &tmp;
243✔
1027
    q_denormalize(mm);
243✔
1028
  } else {
1029
    mm = (rational_t*)mod;
×
1030
  }
1031

1032
  q_denormalize(r);
243✔
1033
  assert(is_ratgmp(r) && is_ratgmp(mm));
1034
  mpz_ptr z = get_gmp_num(r);
243✔
1035
  mpz_ptr m = get_gmp_num(mm);
243✔
1036
  mpz_invert(z, z, m);
243✔
1037
  q_normalize(r);
243✔
1038

1039
  if (mm != mod)
243✔
1040
    q_clear(mm);
243✔
1041
}
243✔
1042

1043
/*
1044
 * Multiply r1 by r2
1045
 */
1046
void q_mul(rational_t *r1, const rational_t *r2) {
104,069,336✔
1047
  uint64_t den;
1048
  int64_t num;
1049
  mpq_ptr q1, q2;
1050

1051
  if (r1->s.den == ONE_DEN && r2->s.den == ONE_DEN) {
104,069,336✔
1052
    assert(is_rat32(r1) && is_rat32(r2));
1053
    num = r1->s.num * ((int64_t) r2->s.num);
10,540,590✔
1054
    if (MIN_NUMERATOR <= num && num <= MAX_NUMERATOR) {
10,540,590✔
1055
      r1->s.num = (int32_t) num;
10,540,315✔
1056
    } else {
1057
      set_to_gmp64(r1, num);
275✔
1058
    }
1059
    return;
10,540,590✔
1060
  }
1061

1062
  if (is_ratgmp(r2)) {
93,528,746✔
1063
    if (is_rat32(r1)) {
5,552,584✔
1064
      convert_to_gmp(r1);
784,375✔
1065
    }
1066
    q1 = get_gmp(r1);
5,552,584✔
1067
    q2 = get_gmp(r2);
5,552,584✔
1068
    mpq_mul(q1, q1, q2);
5,552,584✔
1069
  } else if (is_ratgmp(r1)){
87,976,162✔
1070
    q1 = get_gmp(r1);
306,677✔
1071
    mpq_mul_si(q1, get_num(r2), get_den(r2));
306,677✔
1072
  } else {
1073
    den = get_den(r1) * ((uint64_t) get_den(r2));
87,669,485✔
1074
    num = get_num(r1) * ((int64_t) get_num(r2));
87,669,485✔
1075
    q_set_int64(r1, num, den);
87,669,485✔
1076
  }
1077
}
1078

1079
/*
1080
 * Divide r1 by r2
1081
 */
1082
void q_div(rational_t *r1, const rational_t *r2) {
7,997,971✔
1083
  uint64_t den;
1084
  int64_t num;
1085
  mpq_ptr q1, q2;
1086

1087
  if (is_ratgmp(r2)) {
7,997,971✔
1088
    if (is_rat32(r1)) convert_to_gmp(r1);
646,790✔
1089
    q1 = get_gmp(r1);
646,790✔
1090
    q2 = get_gmp(r2);
646,790✔
1091
    mpq_div(q1, q1, q2);
646,790✔
1092
  } else if (is_ratgmp(r1)){
7,351,181✔
1093
    if (get_num(r2) == 0) {
84,773✔
1094
      division_by_zero();
×
1095
    } else {
1096
      q1 = get_gmp(r1);
84,773✔
1097
      mpq_div_si(q1, get_num(r2), get_den(r2));
84,773✔
1098
    }
1099

1100
  } else if (get_num(r2) > 0) {
7,266,408✔
1101
    den = get_den(r1) * ((uint64_t) get_num(r2));
6,031,171✔
1102
    num = get_num(r1) * ((int64_t) get_den(r2));
6,031,171✔
1103
    q_set_int64(r1, num, den);
6,031,171✔
1104

1105
  } else if (get_num(r2) < 0) {
1,235,237✔
1106
    den = get_den(r1) * ((uint64_t) (- get_num(r2)));
1,235,237✔
1107
    num = get_num(r1) * ( - ((int64_t) get_den(r2)));
1,235,237✔
1108
    q_set_int64(r1, num, den);
1,235,237✔
1109

1110
  } else {
1111
    division_by_zero();
×
1112
  }
1113
}
7,997,971✔
1114

1115
/*
1116
 * Add r2 * r3 to  r1
1117
 */
1118
void q_addmul(rational_t *r1, const rational_t *r2, const rational_t *r3) {
6,945,879✔
1119
  int64_t num;
1120
  rational_t tmp;
1121

1122
  if (r1->s.den == ONE_DEN && r2->s.den == ONE_DEN && r3->s.den == ONE_DEN) {
6,945,879✔
1123
    assert(is_rat32(r1) && is_rat32(r2) &&  is_rat32(r3));
1124

1125
    num = get_num(r1) + get_num(r2) * ((int64_t) get_num(r3));
5,783,726✔
1126
    if (MIN_NUMERATOR <= num && num <= MAX_NUMERATOR) {
5,783,726✔
1127
      r1->s.num = (int32_t) num;
5,782,424✔
1128
    } else {
1129
      set_to_gmp64(r1, num);
1,302✔
1130
    }
1131
    return;
5,783,726✔
1132
  }
1133

1134
  q_init(&tmp);
1,162,153✔
1135
  q_set(&tmp, r2);
1,162,153✔
1136
  q_mul(&tmp, r3);
1,162,153✔
1137
  q_add(r1, &tmp);
1,162,153✔
1138
  q_clear(&tmp);
1,162,153✔
1139
}
1140

1141

1142
/*
1143
 * Subtract r2 * r3 from r1
1144
 */
1145
void q_submul(rational_t *r1, const rational_t *r2, const rational_t *r3) {
116,617,672✔
1146
  int64_t num;
1147
  rational_t tmp;
1148

1149
  if (r1->s.den == ONE_DEN && r2->s.den == ONE_DEN && r3->s.den == ONE_DEN) {
116,617,672✔
1150
    assert(is_rat32(r1) && is_rat32(r2) &&  is_rat32(r3));
1151

1152
    num = get_num(r1) - get_num(r2) * ((int64_t) get_num(r3));
45,387,015✔
1153
    if (MIN_NUMERATOR <= num && num <= MAX_NUMERATOR) {
45,387,015✔
1154
      r1->s.num = (int32_t) num;
45,386,911✔
1155
    } else {
1156
      set_to_gmp64(r1, num);
104✔
1157
    }
1158
    return;
45,387,015✔
1159
  }
1160

1161
  q_init(&tmp);
71,230,657✔
1162
  q_set(&tmp, r2);
71,230,657✔
1163
  q_mul(&tmp, r3);
71,230,657✔
1164
  q_sub(r1, &tmp);
71,230,657✔
1165
  q_clear(&tmp);
71,230,657✔
1166
}
1167

1168
/*
1169
 * Increment: add one to r1
1170
 */
1171
void q_add_one(rational_t *r1) {
354,649✔
1172
  mpq_ptr q;
1173

1174
  if (is_ratgmp(r1)) {
354,649✔
1175
    q = get_gmp(r1);
142✔
1176
    mpz_add(mpq_numref(q), mpq_numref(q), mpq_denref(q));
142✔
1177
  } else {
1178
    r1->s.num += get_den(r1);
354,507✔
1179
    if (r1->s.num > MAX_NUMERATOR) {
354,507✔
1180
      convert_to_gmp(r1);
×
1181
    }
1182
  }
1183
}
354,649✔
1184

1185
/*
1186
 * Decrement: subtract one from r1
1187
 */
1188
void q_sub_one(rational_t *r1) {
626,813✔
1189
  mpq_ptr q;
1190

1191
  if (is_ratgmp(r1)) {
626,813✔
1192
    q = get_gmp(r1);
1,662✔
1193
    mpz_sub(mpq_numref(q), mpq_numref(q), mpq_denref(q));
1,662✔
1194
  } else {
1195
    r1->s.num -= get_den(r1);
625,151✔
1196
    if (r1->s.num < MIN_NUMERATOR) {
625,151✔
1197
      convert_to_gmp(r1);
×
1198
    }
1199
  }
1200
}
626,813✔
1201

1202

1203

1204
/***********************
1205
 *  CEILING AND FLOOR  *
1206
 **********************/
1207

1208

1209
// set r to floor(r);
1210
void q_floor(rational_t *r) {
196,530✔
1211
  int32_t n;
1212

1213
  if (q_is_integer(r)) return;
196,530✔
1214

1215
  if (is_ratgmp(r)) {
149,873✔
1216
    mpq_ptr q = get_gmp(r);
115,545✔
1217
    mpz_fdiv_q(mpq_numref(q), mpq_numref(q), mpq_denref(q));
115,545✔
1218
    mpz_set_ui(mpq_denref(q), 1UL);
115,545✔
1219
  } else {
1220
    n = r->s.num / (int32_t) get_den(r);
34,328✔
1221
    if (r->s.num < 0) n --;
34,328✔
1222
    set_rat32(r, n, 1);
34,328✔
1223
  }
1224
}
1225

1226
// set r to ceil(r)
1227
void q_ceil(rational_t *r) {
14,981✔
1228
  int32_t n;
1229

1230
  if (q_is_integer(r)) return;
14,981✔
1231

1232
  if (is_ratgmp(r)) {
9,686✔
1233
    mpq_ptr q = get_gmp(r);
4,347✔
1234
    mpz_cdiv_q(mpq_numref(q), mpq_numref(q), mpq_denref(q));
4,347✔
1235
    mpz_set_ui(mpq_denref(q), 1UL);
4,347✔
1236
  } else {
1237
    n = r->s.num / (int32_t) get_den(r);
5,339✔
1238
    if (r->s.num > 0) n ++;
5,339✔
1239
    set_rat32(r, n, 1);
5,339✔
1240
  }
1241
}
1242

1243

1244

1245
/*******************
1246
 *  EXPONENTATION  *
1247
 ******************/
1248

1249
/*
1250
 * Store r1 * (r2 ^ n) into r1
1251
 */
1252
void q_mulexp(rational_t *r1, const rational_t *r2, uint32_t n) {
664✔
1253
  rational_t aux;
1254

1255
  if (n <= 3) {
664✔
1256
    // small exponent:
1257
    switch (n) {
629✔
1258
    case 3: q_mul(r1, r2);
29✔
1259
    case 2: q_mul(r1, r2);
219✔
1260
    case 1: q_mul(r1, r2);
629✔
1261
    case 0: break; // do nothing
629✔
1262
    }
1263

1264
  } else {
1265
    q_init(&aux);
35✔
1266
    q_set(&aux, r2);
35✔
1267

1268
    // compute r1 * aux^n
1269
    for (;;) {
1270
      assert(n > 0);
84✔
1271
      if ((n & 1) != 0) {
119✔
1272
        q_mul(r1, &aux);
54✔
1273
      }
1274
      n >>= 1;
119✔
1275
      if (n == 0) break;
119✔
1276
      q_mul(&aux, &aux); // this should work
84✔
1277
    }
1278

1279
    q_clear(&aux);
35✔
1280
  }
1281
}
664✔
1282

1283
/*****************
1284
 *  LCM and GCD  *
1285
 ****************/
1286

1287
/*
1288
 * Get the absolute value of x (converted to uint32_t)
1289
 */
1290
static inline uint32_t abs32(int32_t x) {
2,948,877✔
1291
  return (x >= 0) ? x : -x;
2,948,877✔
1292
}
1293

1294
/*
1295
 * Store lcm(r1, r2) into r1
1296
 * - r1 and r2 must be integer
1297
 * - the result is always positive
1298
 */
1299
void q_lcm(rational_t *r1, const rational_t *r2) {
1,183,126✔
1300
  uint32_t a, b;
1301
  uint64_t d;
1302
  mpq_ptr q1, q2;
1303

1304
  if (is_rat32(r2)) {
1,183,126✔
1305
    if (is_rat32(r1)) {
1,157,024✔
1306
      // both r1 and r2 are 32bit integers
1307
      a = abs32(r1->s.num);
1,140,201✔
1308
      b = abs32(r2->s.num);
1,140,201✔
1309
      d = ((uint64_t) a) * ((uint64_t) (b/gcd32(a, b)));
1,140,201✔
1310
      if (d <= MAX_NUMERATOR) {
1,140,201✔
1311
        set_rat32(r1, d, 1);
1,139,927✔
1312
      } else {
1313
        set_to_gmp64(r1, d);
274✔
1314
      }
1315
    } else {
1316
      // r2 is 32bits, r1 is gmp
1317
      b = abs32(r2->s.num);
16,823✔
1318
      q1 = get_gmp(r1);
16,823✔
1319
      mpz_lcm_ui(mpq_numref(q1), mpq_numref(q1), b);
16,823✔
1320
    }
1321
  } else {
1322
    // r2 is a gmp rational
1323
    if (is_rat32(r1)) convert_to_gmp(r1);
26,102✔
1324
    q1 = get_gmp(r1);
26,102✔
1325
    q2 = get_gmp(r2);
26,102✔
1326
    mpz_lcm(mpq_numref(q1), mpq_numref(q1), mpq_numref(q2));
26,102✔
1327
  }
1328

1329
  assert(q_is_pos(r1));
1330
}
1,183,126✔
1331

1332

1333
/*
1334
 * Store gcd(r1, r2) into r1
1335
 * - r1 and r2 must be integer and non-zero
1336
 * - the result is positive
1337
 */
1338
void q_gcd(rational_t *r1, const rational_t *r2) {
265,341✔
1339
  uint32_t a, b, d;
1340
  mpq_ptr q1, q2;
1341

1342
  if (is_rat32(r2)) {
265,341✔
1343
    if (is_rat32(r1)) {
263,732✔
1344
      // r1 and r2 are small integers
1345
      a = abs32(r1->s.num);
263,306✔
1346
      b = abs32(r2->s.num);
263,306✔
1347
      d = gcd32(a, b);
263,306✔
1348
    } else {
1349
      // r1 is gmp, r2 is a small integer
1350
      b = abs32(r2->s.num);
426✔
1351
      q1 = get_gmp(r1);
426✔
1352
      d = mpz_gcd_ui(NULL, mpq_numref(q1), b);
426✔
1353
      release_mpq(r1);
426✔
1354
    }
1355
    assert(d <= MAX_NUMERATOR);
1356
    set_rat32(r1, d, 1);
263,732✔
1357
  } else {
1358
    if (is_rat32(r1)) {
1,609✔
1359
      // r1 is a small integer, r2 is a gmp number
1360
      a = abs32(r1->s.num);
970✔
1361
      q2 = get_gmp(r2);
970✔
1362
      d = mpz_gcd_ui(NULL, mpq_numref(q2), a);
970✔
1363
      assert(d <= MAX_NUMERATOR);
1364
      set_rat32(r1, d, 1);
970✔
1365
    } else {
1366
      // both are gmp numbers
1367
      q1 = get_gmp(r1);
639✔
1368
      q2 = get_gmp(r2);
639✔
1369
      mpz_gcd(mpq_numref(q1), mpq_numref(q1), mpq_numref(q2));
639✔
1370
    }
1371
  }
1372
}
265,341✔
1373

1374

1375

1376

1377

1378
/************************
1379
 *  EUCLIDEAN DIVISION  *
1380
 ***********************/
1381

1382
/*
1383
 * Quotient/remainder in Euclidean division
1384
 * - r1 and r2 must be integer
1385
 * - r2 must be positive
1386
 */
1387
void q_integer_div(rational_t *r1, const rational_t *r2) {
×
1388
  int32_t n;
1389
  mpq_ptr q1, q2;
1390

1391
  if (is_rat32(r2)) {
×
1392
    assert(r2->s.den == ONE_DEN && r2->s.num > 0);
1393
    if (is_rat32(r1)) {
×
1394
      // both r1 and r2 are small integers
1395
      n = r1->s.num % r2->s.num;  // remainder: n has the same sign as r1 (or n == 0)
×
1396
      r1->s.num /= r2->s.num;     // quotient: same sign as r1, rounded towards 0
×
1397
      if (n < 0) {
×
1398
        r1->s.num --;
×
1399
      }
1400
    } else {
1401
      // r1 is gmp, r2 is a small integer
1402
      q1 = get_gmp(r1);
×
1403
      mpz_fdiv_q_ui(mpq_numref(q1), mpq_numref(q1), r2->s.num);
×
1404
      assert(mpq_is_integer(q1));
1405
    }
1406
  } else {
1407
    q2 = get_gmp(r2);
×
1408
    assert(mpq_is_integer(q2) && mpq_sgn(q2) > 0);
1409
    if (is_rat32(r1)) {
×
1410
      /*
1411
       * r1 is a small integer, r2 is a gmp rational
1412
       * since r2 is normalized and positive, we have r2 > abs(r1)
1413
       * so r1 div r2 = 0 if r1 >= 0 or -1 if r1 < 0
1414
       */
1415
      assert(r1->s.den == ONE_DEN);
1416
      if (r1->s.num >= 0) {
×
1417
        r1->s.num = 0;
×
1418
      } else {
1419
        r1->s.num = -1;
×
1420
      }
1421
    } else {
1422
      // both r1 and r2 are gmp rationals
1423
      q1 = get_gmp(r1);
×
1424
      mpz_fdiv_q(mpq_numref(q1), mpq_numref(q1), mpq_numref(q2));
×
1425
      assert(mpq_is_integer(q1));
1426
    }
1427
  }
1428
}
×
1429

1430

1431
/*
1432
 * Assign the remainder of r1 divided by r2 to r1
1433
 * - both r1 and r2 must be integer
1434
 * - r2 must be positive
1435
 */
1436
void q_integer_rem(rational_t *r1, const rational_t *r2) {
12,391✔
1437
  int32_t n;
1438
  mpq_ptr q1, q2;
1439

1440
  if (is_rat32(r2)){
12,391✔
1441
    assert(r2->s.den == ONE_DEN && r2->s.num > 0);
1442
    if (is_rat32(r1)) {
12,354✔
1443
      /*
1444
       * both r1 and r2 are small integers
1445
       * Note: the result of (r1->num % r2->num) has the same sign as r1->num
1446
       */
1447
      n = r1->s.num % r2->s.num;
12,354✔
1448
      if (n < 0) {
12,354✔
1449
        n += r2->s.num;
2,096✔
1450
      }
1451
      assert(0 <= n && n < r2->s.num);
1452
      r1->s.num = n;
12,354✔
1453
    } else {
1454
      // r1 is gmp, r2 is a small integer
1455
      q1 = get_gmp(r1);
×
1456
      n = mpz_fdiv_ui(mpq_numref(q1), r2->s.num);
×
1457
      assert(0 <= n && n <= MAX_NUMERATOR);
1458
      release_mpq(r1);
×
1459
      set_rat32(r1, n, 1);
×
1460
    }
1461
  } else {
1462
    q2 = get_gmp(r2);
37✔
1463

1464
    assert(mpq_is_integer(q2) && mpq_sgn(q2) > 0);
1465
    if (is_rat32(r1)) {
37✔
1466
      /*
1467
       * r1 is a small integer, r2 is a gmp rational
1468
       * since r2 is normalized and positive, we have r2 > abs(r1)
1469
       * so r1 mod r2 = r1 if r1 >= 0
1470
       * or r1 mod r2 = (r2 + r1) if r1 < 0
1471
       */
1472
      assert(r1->s.den == ONE_DEN);
1473
      if (r1->s.num < 0) {
30✔
1474
        mpq_ptr q = new_mpq();
9✔
1475
        mpq_set_si(q, r1->s.num, 1UL);
9✔
1476
        mpz_add(mpq_numref(q), mpq_numref(q), mpq_numref(q2));
9✔
1477
        set_ratgmp(r1, q);
9✔
1478
        assert(mpq_is_integer(q) && mpq_sgn(q) > 0);
1479
      }
1480

1481
    } else {
1482
      // both r1 and r2 are gmp rationals
1483
      q1 = get_gmp(r1);
7✔
1484
      mpz_fdiv_r(mpq_numref(q1), mpq_numref(q1), mpq_numref(q2));
7✔
1485
      assert(mpq_is_integer(q1));
1486
    }
1487
  }
1488
}
12,391✔
1489

1490
/*
1491
 * Check whether r1 divides r2
1492
 *
1493
 * Both r1 and r2 must be integers and r1 must be non-zero
1494
 */
1495
bool q_integer_divides(rational_t *r1, const rational_t *r2) {
62,176✔
1496
  uint32_t aux;
1497
  mpq_ptr q1, q2;
1498

1499
  q_normalize(r1);
62,176✔
1500

1501
  if (is_ratgmp(r1)) {
62,176✔
1502
    if (is_ratgmp(r2)) {
×
1503
      q1 = get_gmp(r1);
×
1504
      q2 = get_gmp(r2);
×
1505
      return mpz_divisible_p(mpq_numref(q2), mpq_numref(q1));
×
1506
    } else {
1507
      return false;  // abs(r1) > abs(r2) so r1 can't divide r2
×
1508
    }
1509

1510
  } else {
1511
    assert(r1->s.den == ONE_DEN);
1512
    aux = abs32(r1->s.num);
62,176✔
1513
    if (is_ratgmp(r2)) {
62,176✔
1514
      q2 = get_gmp(r2);
708✔
1515
      return mpz_divisible_ui_p(mpq_numref(q2), aux);
708✔
1516
    } else {
1517
      return abs32(r2->s.num) % aux == 0;
61,468✔
1518
    }
1519
  }
1520
}
1521

1522
/*
1523
 * Check whether r2/r1 is an integer
1524
 * - r1 must be non-zero
1525
 */
1526
bool q_divides(const rational_t *r1, const rational_t *r2) {
346,318✔
1527
  rational_t aux;
1528
  bool divides;
1529

1530
  if (r1->s.den == ONE_DEN && (r1->s.num == 1 || r1->s.num == -1)) {
346,318✔
1531
    assert(is_rat32(r1));
1532
    // r1 is +1 or -1
1533
    return true;
11,252✔
1534
  }
1535

1536
  q_init(&aux);
335,066✔
1537
  q_set(&aux, r2);
335,066✔
1538
  q_div(&aux, r1);
335,066✔
1539
  divides = q_is_integer(&aux);
335,066✔
1540
  q_clear(&aux);
335,066✔
1541

1542
  return divides;
335,066✔
1543
}
1544

1545

1546
/***********************************
1547
 *  SMT2 version of (divides x y)  *
1548
 **********************************/
1549

1550
/*
1551
 * (divides r1 r2) is (exist (n::int) r2 = n * r1)
1552
 *
1553
 * This is the same as q_divides(r1, r2) except that the
1554
 * definition allows r1 to be zero. In this case,
1555
 *  (divides 0 r2) is (r2 == 0)
1556
 */
1557
bool q_smt2_divides(const rational_t *r1, const rational_t *r2) {
×
1558
  if (q_is_zero(r1)) {
×
1559
    return q_is_zero(r2);
×
1560
  } else {
1561
    return q_divides(r1, r2);
×
1562
  }
1563
}
1564

1565

1566

1567

1568

1569
/**********************
1570
 *  GENERALIZED LCM   *
1571
 *********************/
1572

1573
/*
1574
 * This computes the LCM of r1 and r2 for arbitrary rationals:
1575
 * - if r1 is (a1/b1) and r2 is (a2/b2) then the result is
1576
 *    lcm(a1, a2)/gcd(b1, b2).
1577
 * - the result is stored in r1
1578
 */
1579
void q_generalized_lcm(rational_t *r1, const rational_t *r2) {
307,730✔
1580
  rational_t a1, b1;
1581
  rational_t a2, b2;
1582

1583
  if (q_is_integer(r1) && q_is_integer(r2)) {
307,730✔
1584
    q_lcm(r1, r2);
268,008✔
1585
  } else {
1586
    q_init(&a1);
39,722✔
1587
    q_get_num(&a1, r1);
39,722✔
1588
    q_init(&b1);
39,722✔
1589
    q_get_den(&b1, r1);
39,722✔
1590

1591
    q_init(&a2);
39,722✔
1592
    q_get_num(&a2, r2);
39,722✔
1593
    q_init(&b2);
39,722✔
1594
    q_get_den(&b2, r2);
39,722✔
1595

1596
    q_lcm(&a1, &a2); // a1 := lcm(a1, a2)
39,722✔
1597
    q_gcd(&b1, &b2); // b1 := gcd(b1, b2)
39,722✔
1598

1599
    // copy the result in r1
1600
    q_set(r1, &a1);
39,722✔
1601
    q_div(r1, &b1);
39,722✔
1602

1603
    q_clear(&a1);
39,722✔
1604
    q_clear(&b1);
39,722✔
1605
    q_clear(&a2);
39,722✔
1606
    q_clear(&b2);
39,722✔
1607
  }
1608
}
307,730✔
1609

1610

1611
/*
1612
 * This computes the GCD of r1 and r2 for arbitrary non-zero rationals:
1613
 * - if r1 is (a1/b1) and r2 is (a2/b2) then the result is
1614
 *    gcd(a1, a2)/lcm(b1, b2).
1615
 * - the result is stored in r1
1616
 */
1617
void q_generalized_gcd(rational_t *r1, const rational_t *r2) {
×
1618
  rational_t a1, b1;
1619
  rational_t a2, b2;
1620

1621
  if (q_is_integer(r1) && q_is_integer(r2)) {
×
1622
    q_lcm(r1, r2);
×
1623
  } else {
1624
    q_init(&a1);
×
1625
    q_get_num(&a1, r1);
×
1626
    q_init(&b1);
×
1627
    q_get_den(&b1, r1);
×
1628

1629
    q_init(&a2);
×
1630
    q_get_num(&a2, r2);
×
1631
    q_init(&b2);
×
1632
    q_get_den(&b2, r2);
×
1633

1634
    q_gcd(&a1, &a2); // a1 := gcd(a1, a2)
×
1635
    q_lcm(&b1, &b2); // b1 := lcm(b1, b2)
×
1636

1637
    // copy the result in r1
1638
    q_set(r1, &a1);
×
1639
    q_div(r1, &b1);
×
1640

1641
    q_clear(&a1);
×
1642
    q_clear(&b1);
×
1643
    q_clear(&a2);
×
1644
    q_clear(&b2);
×
1645
  }
1646
}
×
1647

1648
/**********************
1649
 *  SMT2 DIV AND MOD  *
1650
 *********************/
1651

1652
/*
1653
 * SMT-LIB 2.0 definitions for div and mod:
1654
 * - if y > 0 then div(x, y) is floor(x/y)
1655
 * - if y < 0 then div(x, y) is ceil(x/y)
1656
 * - 0 <= mod(x, y) < y
1657
 * - x = y * div(x, y) + mod(x, y)
1658
 * These operations are defined for any x and non-zero y.
1659
 * The terms x and y are not required to be integers.
1660
 *
1661
 * - q_smt2_div(q, x, y) stores (div x y) in q
1662
 * - q_smt2_mod(q, x, y) stores (mod x y) in q
1663
 *
1664
 * For both functions, y must not be zero.
1665
 */
1666
void q_smt2_div(rational_t *q, const rational_t *x, const rational_t *y) {
72✔
1667
  assert(q_is_nonzero(y));
1668

1669
  q_set(q, x);
72✔
1670
  q_div(q, y); // q := x/y
72✔
1671
  if (q_is_pos(y)) {
72✔
1672
    q_floor(q);  // round down
72✔
1673
  } else {
1674
    q_ceil(q);  // round up
×
1675
  }
1676
}
72✔
1677

1678
/*
1679
 * For debugging: check that 0 <= r < abs(y)
1680
 */
1681
#ifndef NDEBUG
1682
static bool plausible_mod(const rational_t *r, const rational_t *y) {
1683
  rational_t aux;
1684
  bool ok;
1685

1686
  assert(q_is_nonzero(y));
1687

1688
  q_init(&aux);
1689
  if (q_is_pos(y)) {
1690
    q_set(&aux, y);
1691
  } else {
1692
    q_set_neg(&aux, y);
1693
  }
1694
  q_normalize(&aux);
1695

1696
  ok = q_is_nonneg(r) && q_lt(r, &aux);
1697

1698
  q_clear(&aux);
1699

1700
  return ok;
1701
}
1702
#endif
1703

1704

1705
void q_smt2_mod(rational_t *q, const rational_t *x, const rational_t *y) {
69✔
1706
  assert(q_is_nonzero(y));
1707

1708
  q_smt2_div(q, x, y); // q := (div x y)
69✔
1709
  q_mul(q, y);         // q := y * (div x y)
69✔
1710
  q_sub(q, x);         // q := - x + y * (div x y)
69✔
1711
  q_neg(q);            // q := x - y * (div x y) = (mod x y)
69✔
1712

1713
  assert(plausible_mod(q, y));
1714
}
69✔
1715

1716

1717
/*****************
1718
 *  COMPARISONS  *
1719
 ****************/
1720

1721
/*
1722
 * Compare r1 and r2
1723
 * - returns a negative number if r1 < r2
1724
 * - returns 0 if r1 = r2
1725
 * - returns a positive number if r1 > r2
1726
 */
1727
int q_cmp(const rational_t *r1, const rational_t *r2) {
134,681,841✔
1728
  int64_t num;
1729
  mpq_ptr q1, q2;
1730

1731
  if (r1->s.den == ONE_DEN && r2->s.den == ONE_DEN) {
134,681,841✔
1732
    assert(is_rat32(r1) && is_rat32(r2));
1733
    return r1->s.num - r2->s.num;
133,150,438✔
1734
  }
1735

1736
  if (is_ratgmp(r1)) {
1,531,403✔
1737
    if (is_ratgmp(r2)) {
331,380✔
1738
      q1 = get_gmp(r1);
135,294✔
1739
      q2 = get_gmp(r2);
135,294✔
1740
      return mpq_cmp(q1, q2);
135,294✔
1741
    } else {
1742
      q1 = get_gmp(r1);
196,086✔
1743
      return mpq_cmp_si(q1, get_num(r2), get_den(r2));
196,086✔
1744
    }
1745
  } else {
1746
    if (is_ratgmp(r2)) {
1,200,023✔
1747
      q2 = get_gmp(r2);
48,919✔
1748
      return - mpq_cmp_si(q2, get_num(r1), get_den(r1));
48,919✔
1749
    } else {
1750
      num = get_den(r2) * ((int64_t) get_num(r1)) - get_den(r1) * ((int64_t) get_num(r2));
1,151,104✔
1751
      return (num < 0 ? -1 : (num > 0));
1,151,104✔
1752
    }
1753
  }
1754
}
1755

1756
/*
1757
 * Compare r1 and num/den
1758
 */
1759
int q_cmp_int32(const rational_t *r1, int32_t num, uint32_t den) {
1,361✔
1760
  int64_t nn;
1761
  mpq_ptr q1;
1762

1763
  if (is_ratgmp(r1)) {
1,361✔
1764
    q1 = get_gmp(r1);
×
1765
    return mpq_cmp_si(q1, num, den);
×
1766
  } else {
1767
    nn = den * ((int64_t) r1->s.num) - get_den(r1) * ((int64_t) num);
1,361✔
1768
    return (nn < 0 ? -1 : (nn > 0));
1,361✔
1769
  }
1770
}
1771

1772
int q_cmp_int64(const rational_t *r1, int64_t num, uint64_t den) {
×
1773
  int retval;
1774
  mpq_ptr q1;
1775
  mpq_t q0;
1776

1777
  mpq_init2(q0, 64);
×
1778
  mpq_set_int64(q0, num, den);
×
1779
  mpq_canonicalize(q0);
×
1780
  if (is_ratgmp(r1)){
×
1781
    q1 = get_gmp(r1);
×
1782
    retval = mpq_cmp(q1, q0);
×
1783
  } else {
1784
    retval = - mpq_cmp_si(q0, r1->s.num, get_den(r1));
×
1785
  }
1786
  mpq_clear(q0);
×
1787
  return retval;
×
1788
}
1789

1790
/*
1791
 * Check whether r1 and r2 are opposite
1792
 */
1793
bool q_opposite(const rational_t *r1, const rational_t *r2) {
12,678✔
1794
  rational_t aux;
1795
  bool result;
1796

1797
  if (r1->s.den == ONE_DEN && r2->s.den == ONE_DEN) {
12,678✔
1798
    assert(is_rat32(r1) && is_rat32(r2));
1799
    return r1->s.num + r2->s.num == 0;
12,678✔
1800
  }
1801

1802
  q_init(&aux);
×
1803
  q_set(&aux, r1);
×
1804
  q_add(&aux, r2);
×
1805
  result = q_is_zero(&aux);
×
1806
  q_clear(&aux);
×
1807

1808
  return result;
×
1809
}
1810

1811

1812
/***********************************************
1813
 *  CONVERSIONS FROM RATIONALS TO OTHER TYPES  *
1814
 **********************************************/
1815

1816
/*
1817
 * Convert r to a 32bit signed integer
1818
 * - return false if r is not an integer or does not fit in 32 bits
1819
 */
1820
bool q_get32(rational_t *r, int32_t *v) {
359,371✔
1821
  uint32_t d;
1822
  mpq_ptr q;
1823

1824
  if (r->s.den == ONE_DEN) {
359,371✔
1825
    assert(is_rat32(r));
1826
    *v = r->s.num;
359,371✔
1827
    return true;
359,371✔
1828
  } else if (is_ratgmp(r)){
×
1829
    q = get_gmp(r);
×
1830
    if (mpq_fits_int32(q)) {
×
1831
      mpq_get_int32(q, v, &d);
×
1832
      return d == 1;
×
1833
    }
1834
  }
1835
  return false;
×
1836
}
1837

1838
/*
1839
 * Convert r to a 64bit signed integer v
1840
 * - return false if r is not an integer or does not fit in 64bits
1841
 */
1842
bool q_get64(rational_t *r, int64_t *v) {
2✔
1843
  uint64_t d;
1844
  mpq_ptr q;
1845

1846
  if (r->s.den == ONE_DEN) {
2✔
1847
    assert(is_rat32(r));
1848
    *v = r->s.num;
2✔
1849
    return true;
2✔
1850
  } else if (is_ratgmp(r)){
×
1851
    q = get_gmp(r);
×
1852
    if (mpq_fits_int64(q)) {
×
1853
      mpq_get_int64(q, v, &d);
×
1854
      return d == 1;
×
1855
    }
1856
  }
1857
  return false;
×
1858
}
1859

1860

1861
/*
1862
 * Convert r to a pair of 32 bit integers num/den
1863
 * - return false if the numerator or denominator doesn't fit in 32bits
1864
 */
1865
bool q_get_int32(rational_t *r, int32_t *num, uint32_t *den) {
×
1866
  mpq_ptr q;
1867

1868
  if (is_rat32(r)) {
×
1869
    *num = get_num(r);
×
1870
    *den = get_den(r);
×
1871
    return true;
×
1872
  } else {
1873
    q = get_gmp(r);
×
1874
    if (mpq_fits_int32(q)) {
×
1875
      mpq_get_int32(q, num, den);
×
1876
      return true;
×
1877
    }
1878
  }
1879
  return false;
×
1880
}
1881

1882

1883
/*
1884
 * Convert r to a pair of 64bit integers num/den
1885
 * - return false if the numerator or denominator doesn't fit in 64bits
1886
 */
1887
bool q_get_int64(rational_t *r, int64_t *num, uint64_t *den) {
×
1888
  mpq_ptr q;
1889

1890
  if (is_rat32(r)) {
×
1891
    *num = get_num(r);
×
1892
    *den = get_den(r);
×
1893
    return true;
×
1894
  } else {
1895
    q = get_gmp(r);
×
1896
    if (mpq_fits_int64(q)) {
×
1897
      mpq_get_int64(q, num, den);
×
1898
      return true;
×
1899
    }
1900
  }
1901
  return false;
×
1902
}
1903

1904

1905
/*
1906
 * Check whether r can be converted to a 32bit integer,
1907
 * a 64bit integer, or two a pair num/den of 32bit or 64bit integers.
1908
 */
1909

1910
bool q_is_int32(rational_t *r) {
37✔
1911
  return (is_rat32(r) && r->s.den == ONE_DEN) || (is_ratgmp(r) && mpq_is_int32(get_gmp(r)));
37✔
1912
}
1913

1914
bool q_is_int64(rational_t *r) {
×
1915
  return (is_rat32(r) && r->s.den == ONE_DEN) || (is_ratgmp(r) && mpq_is_int64(get_gmp(r)));
×
1916
}
1917

1918
bool q_fits_int32(rational_t *r) {
×
1919
  return is_rat32(r) || mpq_fits_int32(get_gmp(r));
×
1920
}
1921

1922
bool q_fits_int64(rational_t *r) {
×
1923
  return is_rat32(r) || mpq_fits_int64(get_gmp(r));
×
1924
}
1925

1926

1927
/*
1928
 * Size estimate
1929
 * - r must be an integer
1930
 * - this returns approximately the number of bits to represent r
1931
 */
1932
uint32_t q_size(rational_t *r) {
×
1933
  size_t n;
1934

1935
  n = 32;
×
1936
  if (is_ratgmp(r)) {
×
1937
    n = mpz_size(mpq_numref(get_gmp(r))) * mp_bits_per_limb;
×
1938
    if (n > (size_t) UINT32_MAX) {
×
1939
      n = UINT32_MAX;
×
1940
    }
1941
  }
1942
  return (uint32_t) n;
×
1943
}
1944

1945
/*
1946
 * Convert r to a GMP integer
1947
 * - return false if r is not an integer
1948
 */
1949
bool q_get_mpz(const rational_t *r, mpz_t z) {
1,621✔
1950
  if (r->s.den == ONE_DEN) {
1,621✔
1951
    assert(is_rat32(r));
1952
    mpz_set_si(z, r->s.num);
1,595✔
1953
    return true;
1,595✔
1954
  } else if (is_ratgmp(r)){
26✔
1955
    mpq_ptr q = get_gmp(r);
26✔
1956
    if (mpq_is_integer(q)) {
26✔
1957
      mpz_set(z, mpq_numref(q));
26✔
1958
      return true;
26✔
1959
    }
1960
  }
1961
  return false;
×
1962
}
1963

1964
/*
1965
 * Convert r to a GMP rational
1966
 */
1967
void q_get_mpq(const rational_t *r, mpq_t q) {
14,145,974✔
1968
  if (is_ratgmp(r)) {
14,145,974✔
1969
    mpq_set(q, get_gmp(r));
894✔
1970
  } else {
1971
    mpq_set_int32(q, r->s.num, get_den(r));
14,145,080✔
1972
  }
1973
}
14,145,974✔
1974

1975
/*
1976
 * Convert to a double
1977
 */
1978
double q_get_double(rational_t *r) {
×
1979
  double retval;
1980
  mpq_t q0;
1981

1982
  mpq_init2(q0, 64);
×
1983
  q_get_mpq(r, q0);
×
1984
  retval = mpq_get_d(q0);
×
1985
  mpq_clear(q0);
×
1986

1987
  return retval;
×
1988
}
1989

1990

1991
/**************
1992
 *  PRINTING  *
1993
 *************/
1994

1995
/*
1996
 * Print r
1997
 */
1998
void q_print(FILE *f, const rational_t *r) {
×
1999
  if (is_ratgmp(r)) {
×
2000
    mpq_out_str(f, 10, get_gmp(r));
×
2001
  } else if (r->s.den != ONE_DEN) {
×
2002
    fprintf(f, "%" PRId32 "/%" PRIu32, r->s.num, get_den(r));
×
2003
  } else {
2004
    fprintf(f, "%" PRId32, r->s.num);
×
2005
  }
2006
}
×
2007

2008
/*
2009
 * Print r's absolute value
2010
 */
2011
void q_print_abs(FILE *f, const rational_t *r) {
×
2012
  mpq_ptr q;
2013
  int32_t abs_num;
2014

2015
  if (is_ratgmp(r)) {
×
2016
    q = get_gmp(r);
×
2017
    if (mpq_sgn(q) < 0) {
×
2018
      mpq_neg(q, q);
×
2019
      mpq_out_str(f, 10, q);
×
2020
      mpq_neg(q, q);
×
2021
    } else {
2022
      mpq_out_str(f, 10, q);
×
2023
    }
2024
  } else {
2025
    abs_num = r->s.num;
×
2026
    if (abs_num < 0) abs_num = - abs_num;
×
2027

2028
    if (r->s.den != ONE_DEN) {
×
2029
      fprintf(f, "%" PRId32 "/%" PRIu32, abs_num, get_den(r));
×
2030
    } else {
2031
      fprintf(f, "%" PRId32, abs_num);
×
2032
    }
2033
  }
2034
}
×
2035

2036

2037
/****************
2038
 *  HASH CODES  *
2039
 ***************/
2040

2041
/* largest prime less than 2^32 */
2042
#define HASH_MODULUS 4294967291UL
2043

2044
/*
2045
 *  we have  HASH_MODULUS > - MIN_NUMERATOR
2046
 *   and HASH_MODULUS > MAX_NUMERATOR
2047
 *
2048
 * if MIN_NUMERATOR <= r->num <= MAX_NUMERATOR then
2049
 * 1) if r->num >= 0 then r_num mod HASH_MODULUS = r_nun
2050
 * 2) if r->num < 0 then r_num mod HASH_MODULUS = r_num + HASH_MODULUS
2051
 *  so  ((uint32_t) r->num) + HASH_MODULUS = (2^32 + r->num) + HASH_MODULUS
2052
 * gives the correct result.
2053
 */
2054
uint32_t q_hash_numerator(const rational_t *r) {
2,902✔
2055
  if (is_ratgmp(r)) {
2,902✔
2056
    return (uint32_t) mpz_fdiv_ui(mpq_numref(get_gmp(r)), HASH_MODULUS);
38✔
2057
  } else if (r->s.num >= 0) {
2,864✔
2058
    return (uint32_t) r->s.num;
2,864✔
2059
  } else {
2060
    return ((uint32_t) r->s.num) + ((uint32_t) HASH_MODULUS);
×
2061
  }
2062
}
2063

2064
uint32_t q_hash_denominator(const rational_t *r) {
×
2065
  if (is_ratgmp(r)) {
×
2066
    return (uint32_t) mpz_fdiv_ui(mpq_denref(get_gmp(r)), HASH_MODULUS);
×
2067
  }
2068
  return get_den(r);
×
2069
}
2070

2071
void q_hash_decompose(const rational_t *r, uint32_t *h_num, uint32_t *h_den) {
38,571,109✔
2072
  if (is_ratgmp(r)) {
38,571,109✔
2073
    mpq_ptr q = get_gmp(r);
49,147✔
2074
    *h_num = (uint32_t) mpz_fdiv_ui(mpq_numref(q), HASH_MODULUS);
49,147✔
2075
    *h_den = (uint32_t) mpz_fdiv_ui(mpq_denref(q), HASH_MODULUS);
49,147✔
2076
  } else if (r->s.num >= 0) {
38,521,962✔
2077
    *h_num = (uint32_t) r->s.num;
28,680,624✔
2078
    *h_den = get_den(r);
28,680,624✔
2079
  } else {
2080
    *h_num = ((uint32_t) r->s.num) + ((uint32_t) HASH_MODULUS);
9,841,338✔
2081
    *h_den = get_den(r);
9,841,338✔
2082
  }
2083
}
38,571,109✔
2084

2085
/***********************
2086
 *   RATIONAL ARRAYS   *
2087
 **********************/
2088

2089
/*
2090
 * Create and initialize an array of n rationals.
2091
 */
2092
rational_t *new_rational_array(uint32_t n) {
12,894✔
2093
  rational_t *a;
2094
  uint32_t i;
2095

2096
  if (n > MAX_RATIONAL_ARRAY_SIZE) {
12,894✔
2097
    out_of_memory();
×
2098
  }
2099

2100
  a = (rational_t *) safe_malloc(n * sizeof(rational_t));
12,894✔
2101
  for (i=0; i<n; i++) {
36,099✔
2102
    q_init(a + i);
23,205✔
2103
  }
2104

2105
  return a;
12,894✔
2106
}
2107

2108
/*
2109
 * Delete an array created by the previous function
2110
 */
2111
void free_rational_array(rational_t *a, uint32_t n) {
12,894✔
2112
  uint32_t i;
2113

2114
  for (i=0; i<n; i++) {
36,099✔
2115
    q_clear(a + i);
23,205✔
2116
  }
2117
  safe_free(a);
12,894✔
2118
}
12,894✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc