Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it

563603 views
1
/* dumbmp mini GMP compatible library.
2
3
Copyright 2001, 2002, 2004 Free Software Foundation, Inc.
4
5
This file is part of the GNU MP Library.
6
7
The GNU MP Library is free software; you can redistribute it and/or modify
8
it under the terms of the GNU Lesser General Public License as published by
9
the Free Software Foundation; either version 2.1 of the License, or (at your
10
option) any later version.
11
12
The GNU MP Library is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15
License for more details.
16
17
You should have received a copy of the GNU Lesser General Public License
18
along with the GNU MP Library; see the file COPYING.LIB. If not, write to
19
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
MA 02110-1301, USA. */
21
22
23
/* The code here implements a subset (a very limited subset) of the main GMP
24
functions. It's designed for use in a few build-time calculations and
25
will be slow, but highly portable.
26
27
None of the normal GMP configure things are used, nor any of the normal
28
gmp.h or gmp-impl.h. To use this file in a program just #include
29
"dumbmp.c".
30
31
ANSI function definitions can be used here, since ansi2knr is run if
32
necessary. But other ANSI-isms like "const" should be avoided.
33
34
mp_limb_t here is an unsigned long, since that's a sensible type
35
everywhere we know of, with 8*sizeof(unsigned long) giving the number of
36
bits in the type (that not being true for instance with int or short on
37
Cray vector systems.)
38
39
Only the low half of each mp_limb_t is used, so as to make carry handling
40
and limb multiplies easy. GMP_LIMB_BITS is the number of bits used. */
41
42
#include <stdio.h>
43
#include <stdlib.h>
44
#include <string.h>
45
46
47
typedef unsigned long mp_limb_t;
48
49
typedef struct {
50
int _mp_alloc;
51
int _mp_size;
52
mp_limb_t *_mp_d;
53
} mpz_t[1];
54
55
#define GMP_LIMB_BITS (sizeof (mp_limb_t) * 8 / 2)
56
57
#define ABS(x) ((x) >= 0 ? (x) : -(x))
58
#define MIN(l,o) ((l) < (o) ? (l) : (o))
59
#define MAX(h,i) ((h) > (i) ? (h) : (i))
60
61
#define ALLOC(x) ((x)->_mp_alloc)
62
#define PTR(x) ((x)->_mp_d)
63
#define SIZ(x) ((x)->_mp_size)
64
#define ABSIZ(x) ABS (SIZ (x))
65
#define LOMASK ((1L << GMP_LIMB_BITS) - 1)
66
#define LO(x) ((x) & LOMASK)
67
#define HI(x) ((x) >> GMP_LIMB_BITS)
68
69
#define ASSERT(cond) \
70
do { \
71
if (! (cond)) \
72
{ \
73
fprintf (stderr, "Assertion failure\n"); \
74
abort (); \
75
} \
76
} while (0)
77
78
79
char *
80
xmalloc (int n)
81
{
82
char *p;
83
p = malloc (n);
84
if (p == NULL)
85
{
86
fprintf (stderr, "Out of memory (alloc %d bytes)\n", n);
87
abort ();
88
}
89
return p;
90
}
91
92
mp_limb_t *
93
xmalloc_limbs (int n)
94
{
95
return (mp_limb_t *) xmalloc (n * sizeof (mp_limb_t));
96
}
97
98
void
99
mem_copyi (char *dst, char *src, int size)
100
{
101
int i;
102
for (i = 0; i < size; i++)
103
dst[i] = src[i];
104
}
105
106
int
107
isprime (int n)
108
{
109
int i;
110
if (n < 2)
111
return 0;
112
for (i = 2; i < n; i++)
113
if ((n % i) == 0)
114
return 0;
115
return 1;
116
}
117
118
int
119
log2_ceil (int n)
120
{
121
int e;
122
ASSERT (n >= 1);
123
for (e = 0; ; e++)
124
if ((1 << e) >= n)
125
break;
126
return e;
127
}
128
129
void
130
mpz_realloc (mpz_t r, int n)
131
{
132
if (n <= ALLOC(r))
133
return;
134
135
ALLOC(r) = n;
136
PTR(r) = (mp_limb_t *) realloc (PTR(r), n * sizeof (mp_limb_t));
137
if (PTR(r) == NULL)
138
{
139
fprintf (stderr, "Out of memory (realloc to %d)\n", n);
140
abort ();
141
}
142
}
143
144
void
145
mpn_normalize (mp_limb_t *rp, int *rnp)
146
{
147
int rn = *rnp;
148
while (rn > 0 && rp[rn-1] == 0)
149
rn--;
150
*rnp = rn;
151
}
152
153
void
154
mpn_copyi (mp_limb_t *dst, mp_limb_t *src, int n)
155
{
156
int i;
157
for (i = 0; i < n; i++)
158
dst[i] = src[i];
159
}
160
161
void
162
mpn_zero (mp_limb_t *rp, int rn)
163
{
164
int i;
165
for (i = 0; i < rn; i++)
166
rp[i] = 0;
167
}
168
169
void
170
mpz_init (mpz_t r)
171
{
172
ALLOC(r) = 1;
173
PTR(r) = xmalloc_limbs (ALLOC(r));
174
PTR(r)[0] = 0;
175
SIZ(r) = 0;
176
}
177
178
void
179
mpz_clear (mpz_t r)
180
{
181
free (PTR (r));
182
ALLOC(r) = -1;
183
SIZ (r) = 0xbadcafeL;
184
PTR (r) = (mp_limb_t *) 0xdeadbeefL;
185
}
186
187
int
188
mpz_sgn (mpz_t a)
189
{
190
return (SIZ(a) > 0 ? 1 : SIZ(a) == 0 ? 0 : -1);
191
}
192
193
int
194
mpz_odd_p (mpz_t a)
195
{
196
if (SIZ(a) == 0)
197
return 0;
198
else
199
return (PTR(a)[0] & 1) != 0;
200
}
201
202
int
203
mpz_even_p (mpz_t a)
204
{
205
if (SIZ(a) == 0)
206
return 1;
207
else
208
return (PTR(a)[0] & 1) == 0;
209
}
210
211
size_t
212
mpz_sizeinbase (mpz_t a, int base)
213
{
214
int an = ABSIZ (a);
215
mp_limb_t *ap = PTR (a);
216
int cnt;
217
mp_limb_t hi;
218
219
if (base != 2)
220
abort ();
221
222
if (an == 0)
223
return 1;
224
225
cnt = 0;
226
for (hi = ap[an - 1]; hi != 0; hi >>= 1)
227
cnt += 1;
228
return (an - 1) * GMP_LIMB_BITS + cnt;
229
}
230
231
void
232
mpz_set (mpz_t r, mpz_t a)
233
{
234
mpz_realloc (r, ABSIZ (a));
235
SIZ(r) = SIZ(a);
236
mpn_copyi (PTR(r), PTR(a), ABSIZ (a));
237
}
238
239
void
240
mpz_init_set (mpz_t r, mpz_t a)
241
{
242
mpz_init (r);
243
mpz_set (r, a);
244
}
245
246
void
247
mpz_set_ui (mpz_t r, unsigned long ui)
248
{
249
int rn;
250
mpz_realloc (r, 2);
251
PTR(r)[0] = LO(ui);
252
PTR(r)[1] = HI(ui);
253
rn = 2;
254
mpn_normalize (PTR(r), &rn);
255
SIZ(r) = rn;
256
}
257
258
void
259
mpz_init_set_ui (mpz_t r, unsigned long ui)
260
{
261
mpz_init (r);
262
mpz_set_ui (r, ui);
263
}
264
265
void
266
mpz_setbit (mpz_t r, unsigned long bit)
267
{
268
int limb, rn, extend;
269
mp_limb_t *rp;
270
271
rn = SIZ(r);
272
if (rn < 0)
273
abort (); /* only r>=0 */
274
275
limb = bit / GMP_LIMB_BITS;
276
bit %= GMP_LIMB_BITS;
277
278
mpz_realloc (r, limb+1);
279
rp = PTR(r);
280
extend = (limb+1) - rn;
281
if (extend > 0)
282
mpn_zero (rp + rn, extend);
283
284
rp[limb] |= (mp_limb_t) 1 << bit;
285
SIZ(r) = MAX (rn, limb+1);
286
}
287
288
int
289
mpz_tstbit (mpz_t r, unsigned long bit)
290
{
291
int limb;
292
293
if (SIZ(r) < 0)
294
abort (); /* only r>=0 */
295
296
limb = bit / GMP_LIMB_BITS;
297
if (SIZ(r) <= limb)
298
return 0;
299
300
bit %= GMP_LIMB_BITS;
301
return (PTR(r)[limb] >> bit) & 1;
302
}
303
304
int
305
popc_limb (mp_limb_t a)
306
{
307
int ret = 0;
308
while (a != 0)
309
{
310
ret += (a & 1);
311
a >>= 1;
312
}
313
return ret;
314
}
315
316
unsigned long
317
mpz_popcount (mpz_t a)
318
{
319
unsigned long ret;
320
int i;
321
322
if (SIZ(a) < 0)
323
abort ();
324
325
ret = 0;
326
for (i = 0; i < SIZ(a); i++)
327
ret += popc_limb (PTR(a)[i]);
328
return ret;
329
}
330
331
void
332
mpz_add (mpz_t r, mpz_t a, mpz_t b)
333
{
334
int an = ABSIZ (a), bn = ABSIZ (b), rn;
335
mp_limb_t *rp, *ap, *bp;
336
int i;
337
mp_limb_t t, cy;
338
339
if ((SIZ (a) ^ SIZ (b)) < 0)
340
abort (); /* really subtraction */
341
if (SIZ (a) < 0)
342
abort ();
343
344
mpz_realloc (r, MAX (an, bn) + 1);
345
ap = PTR (a); bp = PTR (b); rp = PTR (r);
346
if (an < bn)
347
{
348
mp_limb_t *tp; int tn;
349
tn = an; an = bn; bn = tn;
350
tp = ap; ap = bp; bp = tp;
351
}
352
353
cy = 0;
354
for (i = 0; i < bn; i++)
355
{
356
t = ap[i] + bp[i] + cy;
357
rp[i] = LO (t);
358
cy = HI (t);
359
}
360
for (i = bn; i < an; i++)
361
{
362
t = ap[i] + cy;
363
rp[i] = LO (t);
364
cy = HI (t);
365
}
366
rp[an] = cy;
367
rn = an + 1;
368
369
mpn_normalize (rp, &rn);
370
SIZ (r) = rn;
371
}
372
373
void
374
mpz_add_ui (mpz_t r, mpz_t a, unsigned long int ui)
375
{
376
mpz_t b;
377
378
mpz_init (b);
379
mpz_set_ui (b, ui);
380
mpz_add (r, a, b);
381
mpz_clear (b);
382
}
383
384
void
385
mpz_sub (mpz_t r, mpz_t a, mpz_t b)
386
{
387
int an = ABSIZ (a), bn = ABSIZ (b), rn;
388
mp_limb_t *rp, *ap, *bp;
389
int i;
390
mp_limb_t t, cy;
391
392
if ((SIZ (a) ^ SIZ (b)) < 0)
393
abort (); /* really addition */
394
if (SIZ (a) < 0)
395
abort ();
396
397
mpz_realloc (r, MAX (an, bn) + 1);
398
ap = PTR (a); bp = PTR (b); rp = PTR (r);
399
if (an < bn)
400
{
401
mp_limb_t *tp; int tn;
402
tn = an; an = bn; bn = tn;
403
tp = ap; ap = bp; bp = tp;
404
}
405
406
cy = 0;
407
for (i = 0; i < bn; i++)
408
{
409
t = ap[i] - bp[i] - cy;
410
rp[i] = LO (t);
411
cy = LO (-HI (t));
412
}
413
for (i = bn; i < an; i++)
414
{
415
t = ap[i] - cy;
416
rp[i] = LO (t);
417
cy = LO (-HI (t));
418
}
419
rp[an] = cy;
420
rn = an + 1;
421
422
if (cy != 0)
423
{
424
cy = 0;
425
for (i = 0; i < rn; i++)
426
{
427
t = -rp[i] - cy;
428
rp[i] = LO (t);
429
cy = LO (-HI (t));
430
}
431
SIZ (r) = -rn;
432
return;
433
}
434
435
mpn_normalize (rp, &rn);
436
SIZ (r) = rn;
437
}
438
439
void
440
mpz_sub_ui (mpz_t r, mpz_t a, unsigned long int ui)
441
{
442
mpz_t b;
443
444
mpz_init (b);
445
mpz_set_ui (b, ui);
446
mpz_sub (r, a, b);
447
mpz_clear (b);
448
}
449
450
void
451
mpz_mul (mpz_t r, mpz_t a, mpz_t b)
452
{
453
int an = ABSIZ (a), bn = ABSIZ (b), rn;
454
mp_limb_t *scratch, *tmp, *ap = PTR (a), *bp = PTR (b);
455
int ai, bi;
456
mp_limb_t t, cy;
457
458
scratch = xmalloc_limbs (an + bn);
459
tmp = scratch;
460
461
for (bi = 0; bi < bn; bi++)
462
tmp[bi] = 0;
463
464
for (ai = 0; ai < an; ai++)
465
{
466
tmp = scratch + ai;
467
cy = 0;
468
for (bi = 0; bi < bn; bi++)
469
{
470
t = ap[ai] * bp[bi] + tmp[bi] + cy;
471
tmp[bi] = LO (t);
472
cy = HI (t);
473
}
474
tmp[bn] = cy;
475
}
476
477
rn = an + bn;
478
mpn_normalize (scratch, &rn);
479
free (PTR (r));
480
PTR (r) = scratch;
481
SIZ (r) = (SIZ (a) ^ SIZ (b)) >= 0 ? rn : -rn;
482
ALLOC (r) = an + bn;
483
}
484
485
void
486
mpz_mul_ui (mpz_t r, mpz_t a, unsigned long int ui)
487
{
488
mpz_t b;
489
490
mpz_init (b);
491
mpz_set_ui (b, ui);
492
mpz_mul (r, a, b);
493
mpz_clear (b);
494
}
495
496
void
497
mpz_mul_2exp (mpz_t r, mpz_t a, unsigned long int bcnt)
498
{
499
mpz_set (r, a);
500
while (bcnt)
501
{
502
mpz_add (r, r, r);
503
bcnt -= 1;
504
}
505
}
506
507
void
508
mpz_ui_pow_ui (mpz_t r, unsigned long b, unsigned long e)
509
{
510
unsigned long i;
511
mpz_t bz;
512
513
mpz_init (bz);
514
mpz_set_ui (bz, b);
515
516
mpz_set_ui (r, 1L);
517
for (i = 0; i < e; i++)
518
mpz_mul (r, r, bz);
519
520
mpz_clear (bz);
521
}
522
523
void
524
mpz_tdiv_q_2exp (mpz_t r, mpz_t a, unsigned long int bcnt)
525
{
526
int as, rn;
527
int cnt, tnc;
528
int lcnt;
529
mp_limb_t high_limb, low_limb;
530
int i;
531
532
as = SIZ (a);
533
lcnt = bcnt / GMP_LIMB_BITS;
534
rn = ABS (as) - lcnt;
535
if (rn <= 0)
536
SIZ (r) = 0;
537
else
538
{
539
mp_limb_t *rp, *ap;
540
541
mpz_realloc (r, rn);
542
543
rp = PTR (r);
544
ap = PTR (a);
545
546
cnt = bcnt % GMP_LIMB_BITS;
547
if (cnt != 0)
548
{
549
ap += lcnt;
550
tnc = GMP_LIMB_BITS - cnt;
551
high_limb = *ap++;
552
low_limb = high_limb >> cnt;
553
554
for (i = rn - 1; i != 0; i--)
555
{
556
high_limb = *ap++;
557
*rp++ = low_limb | LO (high_limb << tnc);
558
low_limb = high_limb >> cnt;
559
}
560
*rp = low_limb;
561
rn -= low_limb == 0;
562
}
563
else
564
{
565
ap += lcnt;
566
mpn_copyi (rp, ap, rn);
567
}
568
569
SIZ (r) = as >= 0 ? rn : -rn;
570
}
571
}
572
573
void
574
mpz_tdiv_r_2exp (mpz_t r, mpz_t a, unsigned long int bcnt)
575
{
576
int rn, bwhole;
577
578
mpz_set (r, a);
579
rn = ABSIZ(r);
580
581
bwhole = bcnt / GMP_LIMB_BITS;
582
bcnt %= GMP_LIMB_BITS;
583
if (rn > bwhole)
584
{
585
rn = bwhole+1;
586
PTR(r)[rn-1] &= ((mp_limb_t) 1 << bcnt) - 1;
587
mpn_normalize (PTR(r), &rn);
588
SIZ(r) = (SIZ(r) >= 0 ? rn : -rn);
589
}
590
}
591
592
int
593
mpz_cmp (mpz_t a, mpz_t b)
594
{
595
mp_limb_t *ap, *bp, al, bl;
596
int as = SIZ (a), bs = SIZ (b);
597
int i;
598
int sign;
599
600
if (as != bs)
601
return as > bs ? 1 : -1;
602
603
sign = as > 0 ? 1 : -1;
604
605
ap = PTR (a);
606
bp = PTR (b);
607
for (i = ABS (as) - 1; i >= 0; i--)
608
{
609
al = ap[i];
610
bl = bp[i];
611
if (al != bl)
612
return al > bl ? sign : -sign;
613
}
614
return 0;
615
}
616
617
int
618
mpz_cmp_ui (mpz_t a, unsigned long b)
619
{
620
mpz_t bz;
621
int ret;
622
mpz_init_set_ui (bz, b);
623
ret = mpz_cmp (a, bz);
624
mpz_clear (bz);
625
return ret;
626
}
627
628
void
629
mpz_tdiv_qr (mpz_t q, mpz_t r, mpz_t a, mpz_t b)
630
{
631
mpz_t tmpr, tmpb;
632
unsigned long cnt;
633
634
ASSERT (mpz_sgn(a) >= 0);
635
ASSERT (mpz_sgn(b) > 0);
636
637
mpz_init_set (tmpr, a);
638
mpz_init_set (tmpb, b);
639
mpz_set_ui (q, 0L);
640
641
if (mpz_cmp (tmpr, tmpb) > 0)
642
{
643
cnt = mpz_sizeinbase (tmpr, 2) - mpz_sizeinbase (tmpb, 2) + 1;
644
mpz_mul_2exp (tmpb, tmpb, cnt);
645
646
for ( ; cnt > 0; cnt--)
647
{
648
mpz_mul_2exp (q, q, 1);
649
mpz_tdiv_q_2exp (tmpb, tmpb, 1L);
650
if (mpz_cmp (tmpr, tmpb) >= 0)
651
{
652
mpz_sub (tmpr, tmpr, tmpb);
653
mpz_add_ui (q, q, 1L);
654
ASSERT (mpz_cmp (tmpr, tmpb) < 0);
655
}
656
}
657
}
658
659
mpz_set (r, tmpr);
660
mpz_clear (tmpr);
661
mpz_clear (tmpb);
662
}
663
664
void
665
mpz_tdiv_qr_ui (mpz_t q, mpz_t r, mpz_t a, unsigned long b)
666
{
667
mpz_t bz;
668
mpz_init_set_ui (bz, b);
669
mpz_tdiv_qr (q, r, a, bz);
670
mpz_clear (bz);
671
}
672
673
void
674
mpz_tdiv_q (mpz_t q, mpz_t a, mpz_t b)
675
{
676
mpz_t r;
677
678
mpz_init (r);
679
mpz_tdiv_qr (q, r, a, b);
680
mpz_clear (r);
681
}
682
683
void
684
mpz_tdiv_q_ui (mpz_t q, mpz_t n, unsigned long d)
685
{
686
mpz_t dz;
687
mpz_init_set_ui (dz, d);
688
mpz_tdiv_q (q, n, dz);
689
mpz_clear (dz);
690
}
691
692
/* Set inv to the inverse of d, in the style of invert_limb, ie. for
693
udiv_qrnnd_preinv. */
694
void
695
mpz_preinv_invert (mpz_t inv, mpz_t d, int numb_bits)
696
{
697
mpz_t t;
698
int norm;
699
ASSERT (SIZ(d) > 0);
700
701
norm = numb_bits - mpz_sizeinbase (d, 2);
702
ASSERT (norm >= 0);
703
mpz_init_set_ui (t, 1L);
704
mpz_mul_2exp (t, t, 2*numb_bits - norm);
705
mpz_tdiv_q (inv, t, d);
706
mpz_set_ui (t, 1L);
707
mpz_mul_2exp (t, t, numb_bits);
708
mpz_sub (inv, inv, t);
709
710
mpz_clear (t);
711
}
712
713
/* Remove leading '0' characters from the start of a string, by copying the
714
remainder down. */
715
void
716
strstrip_leading_zeros (char *s)
717
{
718
char c, *p;
719
720
p = s;
721
while (*s == '0')
722
s++;
723
724
do
725
{
726
c = *s++;
727
*p++ = c;
728
}
729
while (c != '\0');
730
}
731
732
char *
733
mpz_get_str (char *buf, int base, mpz_t a)
734
{
735
static char tohex[] = "0123456789abcdef";
736
737
mp_limb_t alimb, *ap;
738
int an, bn, i, j;
739
char *bp;
740
741
if (base != 16)
742
abort ();
743
if (SIZ (a) < 0)
744
abort ();
745
746
if (buf == 0)
747
buf = xmalloc (ABSIZ (a) * (GMP_LIMB_BITS / 4) + 3);
748
749
an = ABSIZ (a);
750
if (an == 0)
751
{
752
buf[0] = '0';
753
buf[1] = '\0';
754
return buf;
755
}
756
757
ap = PTR (a);
758
bn = an * (GMP_LIMB_BITS / 4);
759
bp = buf + bn;
760
761
for (i = 0; i < an; i++)
762
{
763
alimb = ap[i];
764
for (j = 0; j < GMP_LIMB_BITS / 4; j++)
765
{
766
bp--;
767
*bp = tohex [alimb & 0xF];
768
alimb >>= 4;
769
}
770
ASSERT (alimb == 0);
771
}
772
ASSERT (bp == buf);
773
774
buf[bn] = '\0';
775
776
strstrip_leading_zeros (buf);
777
return buf;
778
}
779
780
void
781
mpz_out_str (FILE *file, int base, mpz_t a)
782
{
783
char *str;
784
785
if (file == 0)
786
file = stdout;
787
788
str = mpz_get_str (0, 16, a);
789
fputs (str, file);
790
free (str);
791
}
792
793
/* Calculate r satisfying r*d == 1 mod 2^n. */
794
void
795
mpz_invert_2exp (mpz_t r, mpz_t a, unsigned long n)
796
{
797
unsigned long i;
798
mpz_t inv, prod;
799
800
ASSERT (mpz_odd_p (a));
801
802
mpz_init_set_ui (inv, 1L);
803
mpz_init (prod);
804
805
for (i = 1; i < n; i++)
806
{
807
mpz_mul (prod, inv, a);
808
if (mpz_tstbit (prod, i) != 0)
809
mpz_setbit (inv, i);
810
}
811
812
mpz_mul (prod, inv, a);
813
mpz_tdiv_r_2exp (prod, prod, n);
814
ASSERT (mpz_cmp_ui (prod, 1L) == 0);
815
816
mpz_set (r, inv);
817
818
mpz_clear (inv);
819
mpz_clear (prod);
820
}
821
822
/* Calculate inv satisfying r*a == 1 mod 2^n. */
823
void
824
mpz_invert_ui_2exp (mpz_t r, unsigned long a, unsigned long n)
825
{
826
mpz_t az;
827
mpz_init_set_ui (az, a);
828
mpz_invert_2exp (r, az, n);
829
mpz_clear (az);
830
}
831
832
/* x=y^z */
833
void
834
mpz_pow_ui (mpz_t x, mpz_t y, unsigned long z)
835
{
836
mpz_t t;
837
838
mpz_init_set_ui (t, 1);
839
for (; z != 0; z--)
840
mpz_mul (t, t, y);
841
mpz_set (x, t);
842
mpz_clear (t);
843
}
844
845
/* x=x+y*z */
846
void
847
mpz_addmul_ui (mpz_t x, mpz_t y, unsigned long z)
848
{
849
mpz_t t;
850
851
mpz_init (t);
852
mpz_mul_ui (t, y, z);
853
mpz_add (x, x, t);
854
mpz_clear (t);
855
}
856
857
/* x=floor(y^(1/z)) */
858
void
859
mpz_root (mpz_t x, mpz_t y, unsigned long z)
860
{
861
mpz_t t, u;
862
863
if (mpz_sgn (y) < 0)
864
{
865
fprintf (stderr, "mpz_root does not accept negative values\n");
866
abort ();
867
}
868
if (mpz_cmp_ui (y, 1) <= 0)
869
{
870
mpz_set (x, y);
871
return;
872
}
873
mpz_init (t);
874
mpz_init_set (u, y);
875
do
876
{
877
mpz_pow_ui (t, u, z - 1);
878
mpz_tdiv_q (t, y, t);
879
mpz_addmul_ui (t, u, z - 1);
880
mpz_tdiv_q_ui (t, t, z);
881
if (mpz_cmp (t, u) >= 0)
882
break;
883
mpz_set (u, t);
884
}
885
while (1);
886
mpz_set (x, u);
887
mpz_clear (t);
888
mpz_clear (u);
889
}
890
891