001/*
002 * $Id: BigInteger.java 5680 2017-01-01 16:45:36Z kredel $
003 */
004
005package edu.jas.arith;
006
007
008import java.io.Reader;
009import java.util.ArrayList;
010import java.util.Iterator;
011import java.util.List;
012import java.util.Random;
013
014import edu.jas.kern.StringUtil;
015import edu.jas.structure.GcdRingElem;
016import edu.jas.structure.NotInvertibleException;
017import edu.jas.structure.RingFactory;
018
019
020/**
021 * BigInteger class to make java.math.BigInteger available with RingElem
022 * respectively the GcdRingElem interface. Objects of this class are immutable.
023 * The SAC2 static methods are also provided.
024 * @author Heinz Kredel
025 * @see java.math.BigInteger
026 */
027
028public final class BigInteger
029                implements GcdRingElem<BigInteger>, RingFactory<BigInteger>, Iterable<BigInteger>, Rational {
030
031
032    /**
033     * The data structure.
034     */
035    public final java.math.BigInteger val;
036
037
038    private final static Random random = new Random();
039
040
041    /**
042     * The constant 0.
043     */
044    public final static BigInteger ZERO = new BigInteger(java.math.BigInteger.ZERO);
045
046
047    /**
048     * The constant 1.
049     */
050    public final static BigInteger ONE = new BigInteger(java.math.BigInteger.ONE);
051
052
053    /**
054     * The constant 2.
055     */
056    public final static BigInteger TWO = new BigInteger(2);
057
058
059    /**
060     * Constructor for BigInteger from math.BigInteger.
061     * @param a java.math.BigInteger.
062     */
063    public BigInteger(java.math.BigInteger a) {
064        val = a;
065    }
066
067
068    /**
069     * Constructor for BigInteger from long.
070     * @param a long.
071     */
072    public BigInteger(long a) {
073        val = new java.math.BigInteger(String.valueOf(a));
074    }
075
076
077    /**
078     * Constructor for BigInteger from String.
079     * @param s String.
080     */
081    public BigInteger(String s) {
082        val = new java.math.BigInteger(s.trim());
083    }
084
085
086    /**
087     * Constructor for BigInteger without parameters.
088     */
089    public BigInteger() {
090        val = java.math.BigInteger.ZERO;
091    }
092
093
094    /**
095     * Get the value.
096     * @return val java.math.BigInteger.
097     */
098    public java.math.BigInteger getVal() {
099        return val;
100    }
101
102
103    /**
104     * Get the value as long.
105     * @return val as long.
106     */
107    public long longValue() {
108        return val.longValue();
109    }
110
111
112    /**
113     * Get the corresponding element factory.
114     * @return factory for this Element.
115     * @see edu.jas.structure.Element#factory()
116     */
117    public BigInteger factory() {
118        return this;
119    }
120
121
122    /**
123     * Get a list of the generating elements.
124     * @return list of generators for the algebraic structure.
125     * @see edu.jas.structure.ElemFactory#generators()
126     */
127    public List<BigInteger> generators() {
128        List<BigInteger> g = new ArrayList<BigInteger>(1);
129        g.add(getONE());
130        return g;
131    }
132
133
134    /**
135     * Is this structure finite or infinite.
136     * @return true if this structure is finite, else false.
137     * @see edu.jas.structure.ElemFactory#isFinite()
138     */
139    public boolean isFinite() {
140        return false;
141    }
142
143
144    /**
145     * Clone this.
146     * @see java.lang.Object#clone()
147     */
148    @Override
149    public BigInteger copy() {
150        return new BigInteger(val);
151    }
152
153
154    /**
155     * Copy BigInteger element c.
156     * @param c BigInteger.
157     * @return a copy of c.
158     */
159    public BigInteger copy(BigInteger c) {
160        return new BigInteger(c.val);
161    }
162
163
164    /**
165     * Get the zero element.
166     * @return 0.
167     */
168    public BigInteger getZERO() {
169        return ZERO;
170    }
171
172
173    /**
174     * Get the one element.
175     * @return 1.
176     */
177    public BigInteger getONE() {
178        return ONE;
179    }
180
181
182    /**
183     * Query if this ring is commutative.
184     * @return true.
185     */
186    public boolean isCommutative() {
187        return true;
188    }
189
190
191    /**
192     * Query if this ring is associative.
193     * @return true.
194     */
195    public boolean isAssociative() {
196        return true;
197    }
198
199
200    /**
201     * Query if this ring is a field.
202     * @return false.
203     */
204    public boolean isField() {
205        return false;
206    }
207
208
209    /**
210     * Characteristic of this ring.
211     * @return characteristic of this ring.
212     */
213    public java.math.BigInteger characteristic() {
214        return java.math.BigInteger.ZERO;
215    }
216
217
218    /**
219     * Get a BigInteger element from a math.BigInteger.
220     * @param a math.BigInteger.
221     * @return a as BigInteger.
222     */
223    public BigInteger fromInteger(java.math.BigInteger a) {
224        return new BigInteger(a);
225    }
226
227
228    /**
229     * Get a BigInteger element from a math.BigInteger.
230     * @param a math.BigInteger.
231     * @return a as BigInteger.
232     */
233    public static BigInteger valueOf(java.math.BigInteger a) {
234        return new BigInteger(a);
235    }
236
237
238    /**
239     * Get a BigInteger element from long.
240     * @param a long.
241     * @return a as BigInteger.
242     */
243    public BigInteger fromInteger(long a) {
244        return new BigInteger(a);
245    }
246
247
248    /**
249     * Get a BigInteger element from long.
250     * @param a long.
251     * @return a as BigInteger.
252     */
253    public static BigInteger valueOf(long a) {
254        return new BigInteger(a);
255    }
256
257
258    /**
259     * Is BigInteger number zero.
260     * @return If this is 0 then true is returned, else false.
261     * @see edu.jas.structure.RingElem#isZERO()
262     */
263    public boolean isZERO() {
264        return val.signum() == 0; //equals(java.math.BigInteger.ZERO);
265    }
266
267
268    /**
269     * Is BigInteger number one.
270     * @see edu.jas.structure.RingElem#isONE()
271     */
272    public boolean isONE() {
273        return val.equals(java.math.BigInteger.ONE);
274    }
275
276
277    /**
278     * Is BigInteger number unit.
279     * @see edu.jas.structure.RingElem#isUnit()
280     */
281    public boolean isUnit() {
282        return (this.isONE() || this.negate().isONE());
283    }
284
285
286    /**
287     * Get the String representation.
288     * @see java.lang.Object#toString()
289     */
290    @Override
291    public String toString() {
292        return val.toString();
293    }
294
295
296    /**
297     * Get a scripting compatible string representation.
298     * @return script compatible representation for this Element.
299     * @see edu.jas.structure.Element#toScript()
300     */
301    @Override
302    public String toScript() {
303        // Python case
304        return toString();
305    }
306
307
308    /**
309     * Get a scripting compatible string representation of the factory.
310     * @return script compatible representation for this ElemFactory.
311     * @see edu.jas.structure.Element#toScriptFactory()
312     */
313    @Override
314    public String toScriptFactory() {
315        // Python case
316        return "ZZ()";
317    }
318
319
320    /**
321     * Compare to BigInteger b.
322     * @param b BigInteger.
323     * @return 0 if this == b, 1 if this > b, -1 if this < b.
324     */
325    @Override
326    public int compareTo(BigInteger b) {
327        return val.compareTo(b.val);
328    }
329
330
331    /**
332     * Integer comparison.
333     * @param A BigInteger.
334     * @param B BigInteger.
335     * @return 0 if A == B, 1 if A > B, -1 if A < B.
336     */
337    public static int ICOMP(BigInteger A, BigInteger B) {
338        if (A == null)
339            return -B.signum();
340        return A.compareTo(B);
341    }
342
343
344    /**
345     * Comparison with any other object.
346     * @see java.lang.Object#equals(java.lang.Object)
347     */
348    @Override
349    public boolean equals(Object b) {
350        if (!(b instanceof BigInteger)) {
351            return false;
352        }
353        BigInteger bi = (BigInteger) b;
354        return val.equals(bi.val);
355    }
356
357
358    /**
359     * Hash code for this BigInteger.
360     * @see java.lang.Object#hashCode()
361     */
362    @Override
363    public int hashCode() {
364        return val.hashCode();
365    }
366
367
368    /**
369     * Absolute value of this.
370     * @see edu.jas.structure.RingElem#abs()
371     */
372    public BigInteger abs() {
373        return new BigInteger(val.abs());
374    }
375
376
377    /**
378     * Absolute value.
379     * @param A BigInteger.
380     * @return abs(A).
381     */
382    public static BigInteger IABS(BigInteger A) {
383        if (A == null) {
384            throw new IllegalArgumentException("null A not allowed");
385        }
386        return A.abs();
387    }
388
389
390    /* Negative value of this.
391     * @see edu.jas.structure.RingElem#negate()
392     */
393    public BigInteger negate() {
394        return new BigInteger(val.negate());
395    }
396
397
398    /**
399     * Negative value.
400     * @param A BigInteger.
401     * @return -A.
402     */
403    public static BigInteger INEG(BigInteger A) {
404        if (A == null) {
405            throw new IllegalArgumentException("null A not allowed");
406        }
407        return A.negate();
408    }
409
410
411    /**
412     * signum.
413     * @see edu.jas.structure.RingElem#signum()
414     */
415    public int signum() {
416        return val.signum();
417    }
418
419
420    /**
421     * Integer signum.
422     * @param A BigInteger.
423     * @return signum(A).
424     */
425    public static int ISIGN(BigInteger A) {
426        if (A == null)
427            return 0;
428        return A.signum();
429    }
430
431
432    /**
433     * BigInteger subtract.
434     * @param S BigInteger.
435     * @return this-S.
436     */
437    public BigInteger subtract(BigInteger S) {
438        return new BigInteger(val.subtract(S.val));
439    }
440
441
442    /**
443     * BigInteger subtract.
444     * @param A BigInteger.
445     * @param B BigInteger.
446     * @return A-B.
447     */
448    public static BigInteger IDIF(BigInteger A, BigInteger B) {
449        if (A == null)
450            return B.negate();
451        return A.subtract(B);
452    }
453
454
455    /**
456     * BigInteger divide.
457     * @param S BigInteger.
458     * @return this/S.
459     */
460    public BigInteger divide(BigInteger S) {
461        return new BigInteger(val.divide(S.val));
462    }
463
464
465    /**
466     * BigInteger divide.
467     * @param A BigInteger.
468     * @param B BigInteger.
469     * @return A/B.
470     */
471    public static BigInteger IQ(BigInteger A, BigInteger B) {
472        if (A == null) {
473            throw new IllegalArgumentException("null A not allowed");
474        }
475        return A.divide(B);
476    }
477
478
479    /**
480     * Integer inverse. R is a non-zero integer. S=1/R if defined else throws
481     * not invertible exception.
482     * @see edu.jas.structure.RingElem#inverse()
483     */
484    public BigInteger inverse() {
485        if (this.isONE() || this.negate().isONE()) {
486            return this;
487        }
488        //return ZERO;
489        throw new NotInvertibleException("element not invertible " + this + " :: BigInteger");
490    }
491
492
493    /**
494     * BigInteger remainder.
495     * @param S BigInteger.
496     * @return this - (this/S)*S.
497     */
498    public BigInteger remainder(BigInteger S) {
499        return new BigInteger(val.remainder(S.val));
500    }
501
502
503    /**
504     * BigInteger remainder.
505     * @param A BigInteger.
506     * @param B BigInteger.
507     * @return A - (A/B)*B.
508     */
509    public static BigInteger IREM(BigInteger A, BigInteger B) {
510        if (A == null) {
511            throw new IllegalArgumentException("null A not allowed");
512        }
513        return A.remainder(B);
514    }
515
516
517    /**
518     * BigInteger compute quotient and remainder. Throws an exception, if S ==
519     * 0.
520     * @param S BigInteger.
521     * @return BigInteger[] { q, r } with this = q S + r and 0 &le; r &lt; |S|.
522     */
523    //@Override
524    public BigInteger[] quotientRemainder(BigInteger S) {
525        BigInteger[] qr = new BigInteger[2];
526        java.math.BigInteger[] C = val.divideAndRemainder(S.val);
527        qr[0] = new BigInteger(C[0]);
528        qr[1] = new BigInteger(C[1]);
529        return qr;
530    }
531
532
533    /**
534     * Integer quotient and remainder. A and B are integers, B ne 0. Q is the
535     * quotient, integral part of A/B, and R is the remainder A-B*Q. Throws an
536     * exception, if B == 0.
537     * @param A BigInteger.
538     * @param B BigInteger.
539     * @return BigInteger[] { q, r } with A = q B + r and 0 &le; r &lt; |B|
540     */
541    public static BigInteger[] IQR(BigInteger A, BigInteger B) {
542        if (A == null) {
543            throw new IllegalArgumentException("null A not allowed");
544        }
545        return A.quotientRemainder(B);
546    }
547
548
549    /**
550     * BigInteger greatest common divisor.
551     * @param S BigInteger.
552     * @return gcd(this,S).
553     */
554    public BigInteger gcd(BigInteger S) {
555        return new BigInteger(val.gcd(S.val));
556    }
557
558
559    /**
560     * BigInteger extended greatest common divisor.
561     * @param S BigInteger.
562     * @return [ gcd(this,S), a, b ] with a*this + b*S = gcd(this,S).
563     */
564    public BigInteger[] egcd(BigInteger S) {
565        BigInteger[] ret = new BigInteger[3];
566        ret[0] = null;
567        ret[1] = null;
568        ret[2] = null;
569        if (S == null || S.isZERO()) {
570            ret[0] = this;
571            return ret;
572        }
573        if (this.isZERO()) {
574            ret[0] = S;
575            return ret;
576        }
577        //System.out.println("this = " + this + ", S = " + S);
578        BigInteger[] qr;
579        BigInteger q = this;
580        BigInteger r = S;
581        BigInteger c1 = ONE;
582        BigInteger d1 = ZERO;
583        BigInteger c2 = ZERO;
584        BigInteger d2 = ONE;
585        BigInteger x1;
586        BigInteger x2;
587        while (!r.isZERO()) {
588            qr = q.quotientRemainder(r);
589            q = qr[0];
590            x1 = c1.subtract(q.multiply(d1));
591            x2 = c2.subtract(q.multiply(d2));
592            c1 = d1;
593            c2 = d2;
594            d1 = x1;
595            d2 = x2;
596            q = r;
597            r = qr[1];
598        }
599        //System.out.println("q = " + q + "\n c1 = " + c1 + "\n c2 = " + c2);
600        if (q.signum() < 0) {
601            q = q.negate();
602            c1 = c1.negate();
603            c2 = c2.negate();
604        }
605        ret[0] = q;
606        ret[1] = c1;
607        ret[2] = c2;
608        return ret;
609    }
610
611
612    /**
613     * BigInteger greatest common divisor.
614     * @param A BigInteger.
615     * @param B BigInteger.
616     * @return gcd(A,B).
617     */
618    public static BigInteger IGCD(BigInteger A, BigInteger B) {
619        if (A == null) {
620            throw new IllegalArgumentException("null A not allowed");
621        }
622        return A.gcd(B);
623    }
624
625
626    /**
627     * BigInteger random.
628     * @param n such that 0 &le; r &le; (2<sup>n</sup>-1).
629     * @return r, a random BigInteger.
630     */
631    public BigInteger random(int n) {
632        return random(n, random);
633    }
634
635
636    /**
637     * BigInteger random.
638     * @param n such that 0 &le; r &le; (2<sup>n</sup>-1).
639     * @param rnd is a source for random bits.
640     * @return r, a random BigInteger.
641     */
642    public BigInteger random(int n, Random rnd) {
643        java.math.BigInteger r = new java.math.BigInteger(n, rnd);
644        if (rnd.nextBoolean()) {
645            r = r.negate();
646        }
647        return new BigInteger(r);
648    }
649
650
651    /**
652     * BigInteger random.
653     * @param NL such that 0 &le; r &le; (2<sup>n</sup>-1).
654     * @return r, a random BigInteger.
655     */
656    public static BigInteger IRAND(int NL) {
657        return ONE.random(NL, random);
658    }
659
660
661    /**
662     * BigInteger multiply.
663     * @param S BigInteger.
664     * @return this*S.
665     */
666    public BigInteger multiply(BigInteger S) {
667        return new BigInteger(val.multiply(S.val));
668    }
669
670
671    /**
672     * BigInteger shift left.
673     * @param n bits to shift.
674     * @return this &lt;&lt; n.
675     */
676    public BigInteger shiftLeft(int n) {
677        return new BigInteger(val.shiftLeft(n));
678    }
679
680
681    /**
682     * BigInteger multiply.
683     * @param A BigInteger.
684     * @param B BigInteger.
685     * @return A*B.
686     */
687    public static BigInteger IPROD(BigInteger A, BigInteger B) {
688        if (A == null) {
689            throw new IllegalArgumentException("null A not allowed");
690        }
691        return A.multiply(B);
692    }
693
694
695    /**
696     * BigInteger summation.
697     * @param S BigInteger.
698     * @return this+S.
699     */
700    public BigInteger sum(BigInteger S) {
701        return new BigInteger(val.add(S.val));
702    }
703
704
705    /**
706     * BigInteger addition.
707     * @param A BigInteger.
708     * @param B BigInteger.
709     * @return A+B.
710     */
711    public static BigInteger ISUM(BigInteger A, BigInteger B) {
712        if (A == null) {
713            throw new IllegalArgumentException("null A not allowed");
714        }
715        return A.sum(B);
716    }
717
718
719    /**
720     * BigInteger parse from String.
721     * @param s String.
722     * @return Biginteger from s.
723     */
724    public BigInteger parse(String s) {
725        return new BigInteger(s);
726    }
727
728
729    /**
730     * BigInteger parse from Reader.
731     * @param r Reader.
732     * @return next Biginteger from r.
733     */
734    public BigInteger parse(Reader r) {
735        return parse(StringUtil.nextString(r));
736    }
737
738
739    /**
740     * Return a BigRational approximation of this Element.
741     * @return a BigRational approximation of this.
742     */
743    public BigRational getRational() {
744        return new BigRational(val);
745    }
746
747
748    /**
749     * Returns the number of bits in the representation of this BigInteger,
750     * including a sign bit. For positive BigIntegers, this is equivalent to
751     * {@code (ceil(log2(this+1))+1)}.)
752     * @return number of bits in the representation of this BigInteger,
753     *         including a sign bit.
754     */
755    public long bitLength() {
756        long n = val.bitLength();
757        //System.out.println("sign(val) = " + val.signum());
758        if (val.signum() < 0) {
759            n++;
760        }
761        return ++n;
762    }
763
764
765    /**
766     * Returns the number of bits in the representation of a Long, including a
767     * sign bit.
768     * @param v value.
769     * @return number of bits in the representation of a Long, including a sign
770     *         bit.
771     */
772    public static long bitLength(long v) { // compare BigInteger.bitLengthForInt
773        long n = 64 - Long.numberOfLeadingZeros(v);
774        return ++n;
775    }
776
777
778    private boolean nonNegative = true;
779
780
781    /**
782     * Set the iteration algorithm to all elements.
783     */
784    public void setAllIterator() {
785        nonNegative = false;
786    }
787
788
789    /**
790     * Set the iteration algorithm to non-negative elements.
791     */
792    public void setNonNegativeIterator() {
793        nonNegative = true;
794    }
795
796
797    /**
798     * Get a BigInteger iterator.
799     * @return a iterator over all integers.
800     */
801    public Iterator<BigInteger> iterator() {
802        return new BigIntegerIterator(nonNegative);
803    }
804
805}
806
807
808/**
809 * Big integer iterator.
810 * @author Heinz Kredel
811 */
812class BigIntegerIterator implements Iterator<BigInteger> {
813
814
815    /**
816     * data structure.
817     */
818    java.math.BigInteger curr;
819
820
821    final boolean nonNegative;
822
823
824    /**
825     * BigInteger iterator constructor.
826     */
827    public BigIntegerIterator() {
828        this(false);
829    }
830
831
832    /**
833     * BigInteger iterator constructor.
834     * @param nn true for an iterator over non-negative longs, false for all
835     *            elements iterator.
836     */
837    public BigIntegerIterator(boolean nn) {
838        curr = java.math.BigInteger.ZERO;
839        nonNegative = nn;
840    }
841
842
843    /**
844     * Test for availability of a next element.
845     * @return true if the iteration has more elements, else false.
846     */
847    public boolean hasNext() {
848        return true;
849    }
850
851
852    /**
853     * Get next integer.
854     * @return next integer.
855     */
856    public synchronized BigInteger next() {
857        BigInteger i = new BigInteger(curr);
858        if (nonNegative) {
859            curr = curr.add(java.math.BigInteger.ONE);
860        } else if (curr.signum() > 0 && !nonNegative) {
861            curr = curr.negate();
862        } else {
863            curr = curr.negate().add(java.math.BigInteger.ONE);
864        }
865        return i;
866    }
867
868
869    /**
870     * Remove an element if allowed.
871     */
872    public void remove() {
873        throw new UnsupportedOperationException("cannnot remove elements");
874    }
875}