Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/lib/External/isl/imath/imrat.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
  Name:     imrat.c
3
  Purpose:  Arbitrary precision rational arithmetic routines.
4
  Author:   M. J. Fromberger <http://spinning-yarns.org/michael/>
5
6
  Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
7
8
  Permission is hereby granted, free of charge, to any person obtaining a copy
9
  of this software and associated documentation files (the "Software"), to deal
10
  in the Software without restriction, including without limitation the rights
11
  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
  copies of the Software, and to permit persons to whom the Software is
13
  furnished to do so, subject to the following conditions:
14
15
  The above copyright notice and this permission notice shall be included in
16
  all copies or substantial portions of the Software.
17
18
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
21
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
  SOFTWARE.
25
 */
26
27
#include "imrat.h"
28
#include <stdlib.h>
29
#include <string.h>
30
#include <ctype.h>
31
#include <assert.h>
32
33
682k
#define TEMP(K) (temp + (K))
34
170k
#define SETUP(E, C) \
35
170k
do{if((res = (E)) != MP_OK) 
goto CLEANUP0
; ++(C);}while(0)
36
37
/* Argument checking:
38
   Use CHECK() where a return value is required; NRCHECK() elsewhere */
39
#define CHECK(TEST)   assert(TEST)
40
178k
#define NRCHECK(TEST) assert(TEST)
41
42
/* Reduce the given rational, in place, to lowest terms and canonical form.
43
   Zero is represented as 0/1, one as 1/1.  Signs are adjusted so that the sign
44
   of the numerator is definitive. */
45
static mp_result s_rat_reduce(mp_rat r);
46
47
/* Common code for addition and subtraction operations on rationals. */
48
static mp_result s_rat_combine(mp_rat a, mp_rat b, mp_rat c,
49
             mp_result (*comb_f)(mp_int, mp_int, mp_int));
50
51
mp_result mp_rat_init(mp_rat r)
52
178k
{
53
178k
  mp_result res;
54
178k
55
178k
  if ((res = mp_int_init(MP_NUMER_P(r))) != MP_OK)
56
0
    return res;
57
178k
  if ((res = mp_int_init(MP_DENOM_P(r))) != MP_OK) {
58
0
    mp_int_clear(MP_NUMER_P(r));
59
0
    return res;
60
0
  }
61
178k
62
178k
  return mp_int_set_value(MP_DENOM_P(r), 1);
63
178k
}
64
65
mp_rat mp_rat_alloc(void)
66
178k
{
67
178k
  mp_rat out = malloc(sizeof(*out));
68
178k
69
178k
  if (out != NULL) {
70
178k
    if (mp_rat_init(out) != MP_OK) {
71
0
      free(out);
72
0
      return NULL;
73
0
    }
74
178k
  }
75
178k
76
178k
  return out;
77
178k
}
78
79
0
mp_result mp_rat_reduce(mp_rat r) {
80
0
  return s_rat_reduce(r);
81
0
}
82
83
mp_result mp_rat_init_size(mp_rat r, mp_size n_prec, mp_size d_prec)
84
0
{
85
0
  mp_result res;
86
0
87
0
  if ((res = mp_int_init_size(MP_NUMER_P(r), n_prec)) != MP_OK)
88
0
    return res;
89
0
  if ((res = mp_int_init_size(MP_DENOM_P(r), d_prec)) != MP_OK) {
90
0
    mp_int_clear(MP_NUMER_P(r));
91
0
    return res;
92
0
  }
93
0
  
94
0
  return mp_int_set_value(MP_DENOM_P(r), 1);
95
0
}
96
97
mp_result mp_rat_init_copy(mp_rat r, mp_rat old)
98
0
{
99
0
  mp_result res;
100
0
101
0
  if ((res = mp_int_init_copy(MP_NUMER_P(r), MP_NUMER_P(old))) != MP_OK)
102
0
    return res;
103
0
  if ((res = mp_int_init_copy(MP_DENOM_P(r), MP_DENOM_P(old))) != MP_OK) 
104
0
    mp_int_clear(MP_NUMER_P(r));
105
0
  
106
0
  return res;
107
0
}
108
109
mp_result mp_rat_set_value(mp_rat r, mp_small numer, mp_small denom)
110
0
{
111
0
  mp_result res;
112
0
113
0
  if (denom == 0)
114
0
    return MP_UNDEF;
115
0
116
0
  if ((res = mp_int_set_value(MP_NUMER_P(r), numer)) != MP_OK)
117
0
    return res;
118
0
  if ((res = mp_int_set_value(MP_DENOM_P(r), denom)) != MP_OK)
119
0
    return res;
120
0
121
0
  return s_rat_reduce(r);
122
0
}
123
124
mp_result mp_rat_set_uvalue(mp_rat r, mp_usmall numer, mp_usmall denom)
125
229k
{
126
229k
  mp_result res;
127
229k
128
229k
  if (denom == 0)
129
0
    return MP_UNDEF;
130
229k
131
229k
  if ((res = mp_int_set_uvalue(MP_NUMER_P(r), numer)) != MP_OK)
132
0
    return res;
133
229k
  if ((res = mp_int_set_uvalue(MP_DENOM_P(r), denom)) != MP_OK)
134
0
    return res;
135
229k
136
229k
  return s_rat_reduce(r);
137
229k
}
138
139
void      mp_rat_clear(mp_rat r)
140
178k
{
141
178k
  mp_int_clear(MP_NUMER_P(r));
142
178k
  mp_int_clear(MP_DENOM_P(r));
143
178k
144
178k
}
145
146
void      mp_rat_free(mp_rat r)
147
178k
{
148
178k
  NRCHECK(r != NULL);
149
178k
  
150
178k
  if (r->num.digits != NULL)
151
178k
    mp_rat_clear(r);
152
178k
153
178k
  free(r);
154
178k
}
155
156
mp_result mp_rat_numer(mp_rat r, mp_int z)
157
0
{
158
0
  return mp_int_copy(MP_NUMER_P(r), z);
159
0
}
160
161
mp_int mp_rat_numer_ref(mp_rat r)
162
591k
{
163
591k
  return MP_NUMER_P(r);
164
591k
}
165
166
167
mp_result mp_rat_denom(mp_rat r, mp_int z)
168
0
{
169
0
  return mp_int_copy(MP_DENOM_P(r), z);
170
0
}
171
172
mp_int    mp_rat_denom_ref(mp_rat r)
173
591k
{
174
591k
  return MP_DENOM_P(r);
175
591k
}
176
177
mp_sign   mp_rat_sign(mp_rat r)
178
0
{
179
0
  return MP_SIGN(MP_NUMER_P(r));
180
0
}
181
182
mp_result mp_rat_copy(mp_rat a, mp_rat c)
183
360k
{
184
360k
  mp_result res;
185
360k
186
360k
  if ((res = mp_int_copy(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK)
187
0
    return res;
188
360k
  
189
360k
  res = mp_int_copy(MP_DENOM_P(a), MP_DENOM_P(c));
190
360k
  return res;
191
360k
}
192
193
void      mp_rat_zero(mp_rat r)
194
0
{
195
0
  mp_int_zero(MP_NUMER_P(r));
196
0
  mp_int_set_value(MP_DENOM_P(r), 1);
197
0
  
198
0
}
199
200
mp_result mp_rat_abs(mp_rat a, mp_rat c)
201
0
{
202
0
  mp_result res;
203
0
204
0
  if ((res = mp_int_abs(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK)
205
0
    return res;
206
0
  
207
0
  res = mp_int_abs(MP_DENOM_P(a), MP_DENOM_P(c));
208
0
  return res;
209
0
}
210
211
mp_result mp_rat_neg(mp_rat a, mp_rat c)
212
0
{
213
0
  mp_result res;
214
0
215
0
  if ((res = mp_int_neg(MP_NUMER_P(a), MP_NUMER_P(c))) != MP_OK)
216
0
    return res;
217
0
218
0
  res = mp_int_copy(MP_DENOM_P(a), MP_DENOM_P(c));
219
0
  return res;
220
0
}
221
222
mp_result mp_rat_recip(mp_rat a, mp_rat c)
223
0
{
224
0
  mp_result res;
225
0
226
0
  if (mp_rat_compare_zero(a) == 0)
227
0
    return MP_UNDEF;
228
0
229
0
  if ((res = mp_rat_copy(a, c)) != MP_OK)
230
0
    return res;
231
0
232
0
  mp_int_swap(MP_NUMER_P(c), MP_DENOM_P(c));
233
0
234
0
  /* Restore the signs of the swapped elements */
235
0
  {
236
0
    mp_sign tmp = MP_SIGN(MP_NUMER_P(c));
237
0
238
0
    MP_SIGN(MP_NUMER_P(c)) = MP_SIGN(MP_DENOM_P(c));
239
0
    MP_SIGN(MP_DENOM_P(c)) = tmp;
240
0
  }
241
0
242
0
  return MP_OK;
243
0
}
244
245
mp_result mp_rat_add(mp_rat a, mp_rat b, mp_rat c)
246
0
{
247
0
  return s_rat_combine(a, b, c, mp_int_add);
248
0
249
0
}
250
251
mp_result mp_rat_sub(mp_rat a, mp_rat b, mp_rat c)
252
0
{
253
0
  return s_rat_combine(a, b, c, mp_int_sub);
254
0
255
0
}
256
257
mp_result mp_rat_mul(mp_rat a, mp_rat b, mp_rat c)
258
215k
{
259
215k
  mp_result res;
260
215k
261
215k
  if ((res = mp_int_mul(MP_NUMER_P(a), MP_NUMER_P(b), MP_NUMER_P(c))) != MP_OK)
262
0
    return res;
263
215k
264
215k
  if (mp_int_compare_zero(MP_NUMER_P(c)) != 0) {
265
215k
    if ((res = mp_int_mul(MP_DENOM_P(a), MP_DENOM_P(b), MP_DENOM_P(c))) != MP_OK)
266
0
      return res;
267
215k
  }
268
215k
269
215k
  return s_rat_reduce(c);
270
215k
}
271
272
mp_result mp_rat_div(mp_rat a, mp_rat b, mp_rat c)
273
0
{
274
0
  mp_result res = MP_OK;
275
0
276
0
  if (mp_rat_compare_zero(b) == 0)
277
0
    return MP_UNDEF;
278
0
279
0
  if (c == a || c == b) {
280
0
    mpz_t tmp;
281
0
282
0
    if ((res = mp_int_init(&tmp)) != MP_OK) return res;
283
0
    if ((res = mp_int_mul(MP_NUMER_P(a), MP_DENOM_P(b), &tmp)) != MP_OK) 
284
0
      goto CLEANUP;
285
0
    if ((res = mp_int_mul(MP_DENOM_P(a), MP_NUMER_P(b), MP_DENOM_P(c))) != MP_OK)
286
0
      goto CLEANUP;
287
0
    res = mp_int_copy(&tmp, MP_NUMER_P(c));
288
0
289
0
  CLEANUP:
290
0
    mp_int_clear(&tmp);
291
0
  }
292
0
  else {
293
0
    if ((res = mp_int_mul(MP_NUMER_P(a), MP_DENOM_P(b), MP_NUMER_P(c))) != MP_OK)
294
0
      return res;
295
0
    if ((res = mp_int_mul(MP_DENOM_P(a), MP_NUMER_P(b), MP_DENOM_P(c))) != MP_OK)
296
0
      return res;
297
0
  }
298
0
299
0
  if (res != MP_OK)
300
0
    return res;
301
0
  else
302
0
    return s_rat_reduce(c);
303
0
}
304
305
mp_result mp_rat_add_int(mp_rat a, mp_int b, mp_rat c)
306
0
{
307
0
  mpz_t tmp;
308
0
  mp_result res;
309
0
310
0
  if ((res = mp_int_init_copy(&tmp, b)) != MP_OK)
311
0
    return res;
312
0
313
0
  if ((res = mp_int_mul(&tmp, MP_DENOM_P(a), &tmp)) != MP_OK)
314
0
    goto CLEANUP;
315
0
316
0
  if ((res = mp_rat_copy(a, c)) != MP_OK)
317
0
    goto CLEANUP;
318
0
319
0
  if ((res = mp_int_add(MP_NUMER_P(c), &tmp, MP_NUMER_P(c))) != MP_OK)
320
0
    goto CLEANUP;
321
0
322
0
  res = s_rat_reduce(c);
323
0
324
0
 CLEANUP:
325
0
  mp_int_clear(&tmp);
326
0
  return res;
327
0
}
328
329
mp_result mp_rat_sub_int(mp_rat a, mp_int b, mp_rat c)
330
0
{
331
0
  mpz_t tmp;
332
0
  mp_result res;
333
0
334
0
  if ((res = mp_int_init_copy(&tmp, b)) != MP_OK)
335
0
    return res;
336
0
337
0
  if ((res = mp_int_mul(&tmp, MP_DENOM_P(a), &tmp)) != MP_OK)
338
0
    goto CLEANUP;
339
0
340
0
  if ((res = mp_rat_copy(a, c)) != MP_OK)
341
0
    goto CLEANUP;
342
0
343
0
  if ((res = mp_int_sub(MP_NUMER_P(c), &tmp, MP_NUMER_P(c))) != MP_OK)
344
0
    goto CLEANUP;
345
0
346
0
  res = s_rat_reduce(c);
347
0
348
0
 CLEANUP:
349
0
  mp_int_clear(&tmp);
350
0
  return res;
351
0
}
352
353
mp_result mp_rat_mul_int(mp_rat a, mp_int b, mp_rat c)
354
0
{
355
0
  mp_result res;
356
0
357
0
  if ((res = mp_rat_copy(a, c)) != MP_OK)
358
0
    return res;
359
0
360
0
  if ((res = mp_int_mul(MP_NUMER_P(c), b, MP_NUMER_P(c))) != MP_OK)
361
0
    return res;
362
0
363
0
  return s_rat_reduce(c);
364
0
}
365
366
mp_result mp_rat_div_int(mp_rat a, mp_int b, mp_rat c)
367
0
{
368
0
  mp_result res;
369
0
370
0
  if (mp_int_compare_zero(b) == 0)
371
0
    return MP_UNDEF;
372
0
373
0
  if ((res = mp_rat_copy(a, c)) != MP_OK)
374
0
    return res;
375
0
376
0
  if ((res = mp_int_mul(MP_DENOM_P(c), b, MP_DENOM_P(c))) != MP_OK)
377
0
    return res;
378
0
379
0
  return s_rat_reduce(c);
380
0
}
381
382
mp_result mp_rat_expt(mp_rat a, mp_small b, mp_rat c)
383
0
{
384
0
  mp_result  res;
385
0
386
0
  /* Special cases for easy powers. */
387
0
  if (b == 0)
388
0
    return mp_rat_set_value(c, 1, 1);
389
0
  else if(b == 1)
390
0
    return mp_rat_copy(a, c);
391
0
392
0
  /* Since rationals are always stored in lowest terms, it is not necessary to
393
0
     reduce again when raising to an integer power. */
394
0
  if ((res = mp_int_expt(MP_NUMER_P(a), b, MP_NUMER_P(c))) != MP_OK)
395
0
    return res;
396
0
397
0
  return mp_int_expt(MP_DENOM_P(a), b, MP_DENOM_P(c));
398
0
}
399
400
int       mp_rat_compare(mp_rat a, mp_rat b)
401
141k
{
402
141k
  /* Quick check for opposite signs.  Works because the sign of the numerator
403
141k
     is always definitive. */
404
141k
  if (MP_SIGN(MP_NUMER_P(a)) != MP_SIGN(MP_NUMER_P(b))) {
405
0
    if (MP_SIGN(MP_NUMER_P(a)) == MP_ZPOS)
406
0
      return 1;
407
0
    else
408
0
      return -1;
409
141k
  }
410
141k
  else {
411
141k
    /* Compare absolute magnitudes; if both are positive, the answer stands,
412
141k
       otherwise it needs to be reflected about zero. */
413
141k
    int cmp = mp_rat_compare_unsigned(a, b);
414
141k
415
141k
    if (MP_SIGN(MP_NUMER_P(a)) == MP_ZPOS)
416
141k
      return cmp;
417
0
    else
418
0
      return -cmp;
419
141k
  }
420
141k
}
421
422
int       mp_rat_compare_unsigned(mp_rat a, mp_rat b)
423
141k
{
424
141k
  /* If the denominators are equal, we can quickly compare numerators without
425
141k
     multiplying.  Otherwise, we actually have to do some work. */
426
141k
  if (mp_int_compare_unsigned(MP_DENOM_P(a), MP_DENOM_P(b)) == 0)
427
55.8k
    return mp_int_compare_unsigned(MP_NUMER_P(a), MP_NUMER_P(b));
428
85.3k
429
85.3k
  else {
430
85.3k
    mpz_t  temp[2];
431
85.3k
    mp_result res;
432
85.3k
    int  cmp = INT_MAX, last = 0;
433
85.3k
434
85.3k
    /* t0 = num(a) * den(b), t1 = num(b) * den(a) */
435
85.3k
    SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(a)), last);
436
85.3k
    SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(b)), last);
437
85.3k
438
85.3k
    if ((res = mp_int_mul(TEMP(0), MP_DENOM_P(b), TEMP(0))) != MP_OK ||
439
85.3k
  (res = mp_int_mul(TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK)
440
0
      goto CLEANUP;
441
85.3k
    
442
85.3k
    cmp = mp_int_compare_unsigned(TEMP(0), TEMP(1));
443
85.3k
    
444
85.3k
  CLEANUP:
445
256k
    while (--last >= 0)
446
170k
      mp_int_clear(TEMP(last));
447
85.3k
448
85.3k
    return cmp;
449
85.3k
  }
450
141k
}
451
452
int       mp_rat_compare_zero(mp_rat r)
453
0
{
454
0
  return mp_int_compare_zero(MP_NUMER_P(r));
455
0
}
456
457
int       mp_rat_compare_value(mp_rat r, mp_small n, mp_small d)
458
0
{
459
0
  mpq_t tmp;
460
0
  mp_result res;
461
0
  int  out = INT_MAX;
462
0
463
0
  if ((res = mp_rat_init(&tmp)) != MP_OK)
464
0
    return out;
465
0
  if ((res = mp_rat_set_value(&tmp, n, d)) != MP_OK)
466
0
    goto CLEANUP;
467
0
  
468
0
  out = mp_rat_compare(r, &tmp);
469
0
  
470
0
 CLEANUP:
471
0
  mp_rat_clear(&tmp);
472
0
  return out;
473
0
}
474
475
int       mp_rat_is_integer(mp_rat r)
476
0
{
477
0
  return (mp_int_compare_value(MP_DENOM_P(r), 1) == 0);
478
0
}
479
480
mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den)
481
0
{
482
0
  mp_result res;
483
0
484
0
  if ((res = mp_int_to_int(MP_NUMER_P(r), num)) != MP_OK)
485
0
    return res;
486
0
487
0
  res = mp_int_to_int(MP_DENOM_P(r), den);
488
0
  return res;
489
0
}
490
491
mp_result mp_rat_to_string(mp_rat r, mp_size radix, char *str, int limit)
492
0
{
493
0
  char *start;
494
0
  int   len;
495
0
  mp_result res;
496
0
497
0
  /* Write the numerator.  The sign of the rational number is written by the
498
0
     underlying integer implementation. */
499
0
  if ((res = mp_int_to_string(MP_NUMER_P(r), radix, str, limit)) != MP_OK)
500
0
    return res;
501
0
502
0
  /* If the value is zero, don't bother writing any denominator */
503
0
  if (mp_int_compare_zero(MP_NUMER_P(r)) == 0)
504
0
    return MP_OK;
505
0
  
506
0
  /* Locate the end of the numerator, and make sure we are not going to exceed
507
0
     the limit by writing a slash. */
508
0
  len = strlen(str);
509
0
  start = str + len;
510
0
  limit -= len;
511
0
  if(limit == 0)
512
0
    return MP_TRUNC;
513
0
514
0
  *start++ = '/';
515
0
  limit -= 1;
516
0
  
517
0
  res = mp_int_to_string(MP_DENOM_P(r), radix, start, limit);
518
0
  return res;
519
0
}
520
521
mp_result mp_rat_to_decimal(mp_rat r, mp_size radix, mp_size prec,
522
                            mp_round_mode round, char *str, int limit)
523
0
{
524
0
  mpz_t temp[3];
525
0
  mp_result res;
526
0
  char *start = str;
527
0
  int len, lead_0, left = limit, last = 0;
528
0
    
529
0
  SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(r)), last);
530
0
  SETUP(mp_int_init(TEMP(last)), last);
531
0
  SETUP(mp_int_init(TEMP(last)), last);
532
0
533
0
  /* Get the unsigned integer part by dividing denominator into the absolute
534
0
     value of the numerator. */
535
0
  mp_int_abs(TEMP(0), TEMP(0));
536
0
  if ((res = mp_int_div(TEMP(0), MP_DENOM_P(r), TEMP(0), TEMP(1))) != MP_OK)
537
0
    goto CLEANUP;
538
0
539
0
  /* Now:  T0 = integer portion, unsigned;
540
0
           T1 = remainder, from which fractional part is computed. */
541
0
542
0
  /* Count up leading zeroes after the radix point. */
543
0
  for (lead_0 = 0; lead_0 < prec && mp_int_compare(TEMP(1), MP_DENOM_P(r)) < 0; 
544
0
      ++lead_0) {
545
0
    if ((res = mp_int_mul_value(TEMP(1), radix, TEMP(1))) != MP_OK)
546
0
      goto CLEANUP;
547
0
  }
548
0
549
0
  /* Multiply remainder by a power of the radix sufficient to get the right
550
0
     number of significant figures. */
551
0
  if (prec > lead_0) {
552
0
    if ((res = mp_int_expt_value(radix, prec - lead_0, TEMP(2))) != MP_OK)
553
0
      goto CLEANUP;
554
0
    if ((res = mp_int_mul(TEMP(1), TEMP(2), TEMP(1))) != MP_OK)
555
0
      goto CLEANUP;
556
0
  }
557
0
  if ((res = mp_int_div(TEMP(1), MP_DENOM_P(r), TEMP(1), TEMP(2))) != MP_OK)
558
0
    goto CLEANUP;
559
0
560
0
  /* Now:  T1 = significant digits of fractional part;
561
0
           T2 = leftovers, to use for rounding. 
562
0
563
0
     At this point, what we do depends on the rounding mode.  The default is
564
0
     MP_ROUND_DOWN, for which everything is as it should be already.
565
0
  */
566
0
  switch (round) {
567
0
    int cmp;
568
0
569
0
  case MP_ROUND_UP:
570
0
    if (mp_int_compare_zero(TEMP(2)) != 0) {
571
0
      if (prec == 0)
572
0
  res = mp_int_add_value(TEMP(0), 1, TEMP(0));
573
0
      else
574
0
  res = mp_int_add_value(TEMP(1), 1, TEMP(1));
575
0
    }
576
0
    break;
577
0
578
0
  case MP_ROUND_HALF_UP:
579
0
  case MP_ROUND_HALF_DOWN:
580
0
    if ((res = mp_int_mul_pow2(TEMP(2), 1, TEMP(2))) != MP_OK)
581
0
      goto CLEANUP;
582
0
583
0
    cmp = mp_int_compare(TEMP(2), MP_DENOM_P(r));    
584
0
585
0
    if (round == MP_ROUND_HALF_UP)
586
0
      cmp += 1;
587
0
588
0
    if (cmp > 0) {
589
0
      if (prec == 0)
590
0
  res = mp_int_add_value(TEMP(0), 1, TEMP(0));
591
0
      else
592
0
  res = mp_int_add_value(TEMP(1), 1, TEMP(1));
593
0
    }
594
0
    break;
595
0
    
596
0
  case MP_ROUND_DOWN:
597
0
    break;  /* No action required */
598
0
599
0
  default: 
600
0
    return MP_BADARG; /* Invalid rounding specifier */
601
0
  }
602
0
603
0
  /* The sign of the output should be the sign of the numerator, but if all the
604
0
     displayed digits will be zero due to the precision, a negative shouldn't
605
0
     be shown. */
606
0
  if (MP_SIGN(MP_NUMER_P(r)) == MP_NEG &&
607
0
      (mp_int_compare_zero(TEMP(0)) != 0 ||
608
0
       mp_int_compare_zero(TEMP(1)) != 0)) {
609
0
    *start++ = '-';
610
0
    left -= 1;
611
0
  }
612
0
613
0
  if ((res = mp_int_to_string(TEMP(0), radix, start, left)) != MP_OK)
614
0
    goto CLEANUP;
615
0
  
616
0
  len = strlen(start);
617
0
  start += len;
618
0
  left -= len;
619
0
  
620
0
  if (prec == 0) 
621
0
    goto CLEANUP;
622
0
  
623
0
  *start++ = '.';
624
0
  left -= 1;
625
0
  
626
0
  if (left < prec + 1) {
627
0
    res = MP_TRUNC;
628
0
    goto CLEANUP;
629
0
  }
630
0
631
0
  memset(start, '0', lead_0 - 1);
632
0
  left -= lead_0;
633
0
  start += lead_0 - 1;
634
0
635
0
  res = mp_int_to_string(TEMP(1), radix, start, left);
636
0
637
0
 CLEANUP:
638
0
  while (--last >= 0)
639
0
    mp_int_clear(TEMP(last));
640
0
  
641
0
  return res;
642
0
}
643
644
mp_result mp_rat_string_len(mp_rat r, mp_size radix)
645
0
{
646
0
  mp_result n_len, d_len = 0;
647
0
648
0
  n_len = mp_int_string_len(MP_NUMER_P(r), radix);
649
0
650
0
  if (mp_int_compare_zero(MP_NUMER_P(r)) != 0)
651
0
    d_len = mp_int_string_len(MP_DENOM_P(r), radix);
652
0
653
0
  /* Though simplistic, this formula is correct.  Space for the sign flag is
654
0
     included in n_len, and the space for the NUL that is counted in n_len
655
0
     counts for the separator here.  The space for the NUL counted in d_len
656
0
     counts for the final terminator here. */
657
0
658
0
  return n_len + d_len;
659
0
660
0
}
661
662
mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec)
663
0
{
664
0
  int  z_len, f_len;
665
0
666
0
  z_len = mp_int_string_len(MP_NUMER_P(r), radix);
667
0
  
668
0
  if (prec == 0)
669
0
    f_len = 1; /* terminator only */
670
0
  else
671
0
    f_len = 1 + prec + 1; /* decimal point, digits, terminator */
672
0
  
673
0
  return z_len + f_len;
674
0
}
675
676
mp_result mp_rat_read_string(mp_rat r, mp_size radix, const char *str)
677
0
{
678
0
  return mp_rat_read_cstring(r, radix, str, NULL);
679
0
}
680
681
mp_result mp_rat_read_cstring(mp_rat r, mp_size radix, const char *str, 
682
            char **end)
683
0
{
684
0
  mp_result res;
685
0
  char *endp;
686
0
687
0
  if ((res = mp_int_read_cstring(MP_NUMER_P(r), radix, str, &endp)) != MP_OK &&
688
0
      (res != MP_TRUNC))
689
0
    return res;
690
0
691
0
  /* Skip whitespace between numerator and (possible) separator */
692
0
  while (isspace((unsigned char) *endp))
693
0
    ++endp;
694
0
  
695
0
  /* If there is no separator, we will stop reading at this point. */
696
0
  if (*endp != '/') {
697
0
    mp_int_set_value(MP_DENOM_P(r), 1);
698
0
    if (end != NULL)
699
0
      *end = endp;
700
0
    return res;
701
0
  }
702
0
  
703
0
  ++endp; /* skip separator */
704
0
  if ((res = mp_int_read_cstring(MP_DENOM_P(r), radix, endp, end)) != MP_OK)
705
0
    return res;
706
0
  
707
0
  /* Make sure the value is well-defined */
708
0
  if (mp_int_compare_zero(MP_DENOM_P(r)) == 0)
709
0
    return MP_UNDEF;
710
0
711
0
  /* Reduce to lowest terms */
712
0
  return s_rat_reduce(r);
713
0
}
714
715
/* Read a string and figure out what format it's in.  The radix may be supplied
716
   as zero to use "default" behaviour.
717
718
   This function will accept either a/b notation or decimal notation.
719
 */
720
mp_result mp_rat_read_ustring(mp_rat r, mp_size radix, const char *str, 
721
            char **end)
722
0
{
723
0
  char      *endp;
724
0
  mp_result  res;
725
0
726
0
  if (radix == 0)
727
0
    radix = 10;  /* default to decimal input */
728
0
729
0
  if ((res = mp_rat_read_cstring(r, radix, str, &endp)) != MP_OK) {
730
0
    if (res == MP_TRUNC) {
731
0
      if (*endp == '.')
732
0
  res = mp_rat_read_cdecimal(r, radix, str, &endp);
733
0
    }
734
0
    else
735
0
      return res;
736
0
  }
737
0
738
0
  if (end != NULL)
739
0
    *end = endp;
740
0
741
0
  return res;
742
0
}
743
744
mp_result mp_rat_read_decimal(mp_rat r, mp_size radix, const char *str)
745
0
{
746
0
  return mp_rat_read_cdecimal(r, radix, str, NULL);
747
0
}
748
749
mp_result mp_rat_read_cdecimal(mp_rat r, mp_size radix, const char *str, 
750
             char **end)
751
0
{
752
0
  mp_result res;
753
0
  mp_sign   osign;
754
0
  char *endp;
755
0
756
0
  while (isspace((unsigned char) *str))
757
0
    ++str;
758
0
  
759
0
  switch (*str) {
760
0
  case '-':
761
0
    osign = MP_NEG;
762
0
    break;
763
0
  default:
764
0
    osign = MP_ZPOS;
765
0
  }
766
0
  
767
0
  if ((res = mp_int_read_cstring(MP_NUMER_P(r), radix, str, &endp)) != MP_OK &&
768
0
     (res != MP_TRUNC))
769
0
    return res;
770
0
771
0
  /* This needs to be here. */
772
0
  (void) mp_int_set_value(MP_DENOM_P(r), 1);
773
0
774
0
  if (*endp != '.') {
775
0
    if (end != NULL)
776
0
      *end = endp;
777
0
    return res;
778
0
  }
779
0
780
0
  /* If the character following the decimal point is whitespace or a sign flag,
781
0
     we will consider this a truncated value.  This special case is because
782
0
     mp_int_read_string() will consider whitespace or sign flags to be valid
783
0
     starting characters for a value, and we do not want them following the
784
0
     decimal point.
785
0
786
0
     Once we have done this check, it is safe to read in the value of the
787
0
     fractional piece as a regular old integer.
788
0
  */
789
0
  ++endp;
790
0
  if (*endp == '\0') {
791
0
    if (end != NULL)
792
0
      *end = endp;
793
0
    return MP_OK;
794
0
  }
795
0
  else if(isspace((unsigned char) *endp) || *endp == '-' || *endp == '+') {
796
0
    return MP_TRUNC;
797
0
  }
798
0
  else {
799
0
    mpz_t  frac;
800
0
    mp_result save_res;
801
0
    char  *save = endp;
802
0
    int    num_lz = 0;
803
0
804
0
    /* Make a temporary to hold the part after the decimal point. */
805
0
    if ((res = mp_int_init(&frac)) != MP_OK)
806
0
      return res;
807
0
    
808
0
    if ((res = mp_int_read_cstring(&frac, radix, endp, &endp)) != MP_OK &&
809
0
       (res != MP_TRUNC))
810
0
      goto CLEANUP;
811
0
812
0
    /* Save this response for later. */
813
0
    save_res = res;
814
0
815
0
    if (mp_int_compare_zero(&frac) == 0)
816
0
      goto FINISHED;
817
0
818
0
    /* Discard trailing zeroes (somewhat inefficiently) */
819
0
    while (mp_int_divisible_value(&frac, radix))
820
0
      if ((res = mp_int_div_value(&frac, radix, &frac, NULL)) != MP_OK)
821
0
  goto CLEANUP;
822
0
    
823
0
    /* Count leading zeros after the decimal point */
824
0
    while (save[num_lz] == '0')
825
0
      ++num_lz;
826
0
827
0
    /* Find the least power of the radix that is at least as large as the
828
0
       significant value of the fractional part, ignoring leading zeroes.  */
829
0
    (void) mp_int_set_value(MP_DENOM_P(r), radix); 
830
0
    
831
0
    while (mp_int_compare(MP_DENOM_P(r), &frac) < 0) {
832
0
      if ((res = mp_int_mul_value(MP_DENOM_P(r), radix, MP_DENOM_P(r))) != MP_OK)
833
0
  goto CLEANUP;
834
0
    }
835
0
    
836
0
    /* Also shift by enough to account for leading zeroes */
837
0
    while (num_lz > 0) {
838
0
      if ((res = mp_int_mul_value(MP_DENOM_P(r), radix, MP_DENOM_P(r))) != MP_OK)
839
0
  goto CLEANUP;
840
0
841
0
      --num_lz;
842
0
    }
843
0
844
0
    /* Having found this power, shift the numerator leftward that many, digits,
845
0
       and add the nonzero significant digits of the fractional part to get the
846
0
       result. */
847
0
    if ((res = mp_int_mul(MP_NUMER_P(r), MP_DENOM_P(r), MP_NUMER_P(r))) != MP_OK)
848
0
      goto CLEANUP;
849
0
    
850
0
    { /* This addition needs to be unsigned. */
851
0
      MP_SIGN(MP_NUMER_P(r)) = MP_ZPOS;
852
0
      if ((res = mp_int_add(MP_NUMER_P(r), &frac, MP_NUMER_P(r))) != MP_OK)
853
0
  goto CLEANUP;
854
0
855
0
      MP_SIGN(MP_NUMER_P(r)) = osign;
856
0
    }
857
0
    if ((res = s_rat_reduce(r)) != MP_OK)
858
0
      goto CLEANUP;
859
0
860
0
    /* At this point, what we return depends on whether reading the fractional
861
0
       part was truncated or not.  That information is saved from when we
862
0
       called mp_int_read_string() above. */
863
0
  FINISHED:
864
0
    res = save_res;
865
0
    if (end != NULL)
866
0
      *end = endp;
867
0
868
0
  CLEANUP:
869
0
    mp_int_clear(&frac);
870
0
871
0
    return res;
872
0
  }
873
0
}
874
875
/* Private functions for internal use.  Make unchecked assumptions about format
876
   and validity of inputs. */
877
878
static mp_result s_rat_reduce(mp_rat r)
879
444k
{
880
444k
  mpz_t gcd;
881
444k
  mp_result res = MP_OK;
882
444k
883
444k
  if (mp_int_compare_zero(MP_NUMER_P(r)) == 0) {
884
126
    mp_int_set_value(MP_DENOM_P(r), 1);
885
126
    return MP_OK;
886
126
  }
887
444k
888
444k
  /* If the greatest common divisor of the numerator and denominator is greater
889
444k
     than 1, divide it out. */
890
444k
  if ((res = mp_int_init(&gcd)) != MP_OK)
891
0
    return res;
892
444k
893
444k
  if ((res = mp_int_gcd(MP_NUMER_P(r), MP_DENOM_P(r), &gcd)) != MP_OK)
894
0
    goto CLEANUP;
895
444k
896
444k
  if (mp_int_compare_value(&gcd, 1) != 0) {
897
107k
    if ((res = mp_int_div(MP_NUMER_P(r), &gcd, MP_NUMER_P(r), NULL)) != MP_OK)
898
0
      goto CLEANUP;
899
107k
    if ((res = mp_int_div(MP_DENOM_P(r), &gcd, MP_DENOM_P(r), NULL)) != MP_OK)
900
0
      goto CLEANUP;
901
444k
  }
902
444k
903
444k
  /* Fix up the signs of numerator and denominator */
904
444k
  if (MP_SIGN(MP_NUMER_P(r)) == MP_SIGN(MP_DENOM_P(r)))
905
444k
    MP_SIGN(MP_NUMER_P(r)) = MP_SIGN(MP_DENOM_P(r)) = MP_ZPOS;
906
0
  else {
907
0
    MP_SIGN(MP_NUMER_P(r)) = MP_NEG;
908
0
    MP_SIGN(MP_DENOM_P(r)) = MP_ZPOS;
909
0
  }
910
444k
911
444k
 CLEANUP:
912
444k
  mp_int_clear(&gcd);
913
444k
914
444k
  return res;
915
444k
}
916
917
static mp_result s_rat_combine(mp_rat a, mp_rat b, mp_rat c, 
918
             mp_result (*comb_f)(mp_int, mp_int, mp_int))
919
0
{
920
0
  mp_result res;
921
0
922
0
  /* Shortcut when denominators are already common */
923
0
  if (mp_int_compare(MP_DENOM_P(a), MP_DENOM_P(b)) == 0) {
924
0
    if ((res = (comb_f)(MP_NUMER_P(a), MP_NUMER_P(b), MP_NUMER_P(c))) != MP_OK)
925
0
      return res;
926
0
    if ((res = mp_int_copy(MP_DENOM_P(a), MP_DENOM_P(c))) != MP_OK)
927
0
      return res;
928
0
    
929
0
    return s_rat_reduce(c);
930
0
  }
931
0
  else {
932
0
    mpz_t  temp[2];
933
0
    int    last = 0;
934
0
935
0
    SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(a)), last);
936
0
    SETUP(mp_int_init_copy(TEMP(last), MP_NUMER_P(b)), last);
937
0
    
938
0
    if ((res = mp_int_mul(TEMP(0), MP_DENOM_P(b), TEMP(0))) != MP_OK)
939
0
      goto CLEANUP;
940
0
    if ((res = mp_int_mul(TEMP(1), MP_DENOM_P(a), TEMP(1))) != MP_OK)
941
0
      goto CLEANUP;
942
0
    if ((res = (comb_f)(TEMP(0), TEMP(1), MP_NUMER_P(c))) != MP_OK)
943
0
      goto CLEANUP;
944
0
945
0
    res = mp_int_mul(MP_DENOM_P(a), MP_DENOM_P(b), MP_DENOM_P(c));
946
0
947
0
  CLEANUP:
948
0
    while (--last >= 0) 
949
0
      mp_int_clear(TEMP(last));
950
0
951
0
    if (res == MP_OK)
952
0
      return s_rat_reduce(c);
953
0
    else
954
0
      return res;
955
0
  }
956
0
}
957
958
/* Here there be dragons */