Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/misc/FDBigInteger.java
38829 views
/*1* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package sun.misc;2526import java.math.BigInteger;27import java.util.Arrays;28//@ model import org.jmlspecs.models.JMLMath;2930/**31* A simple big integer package specifically for floating point base conversion.32*/33public /*@ spec_bigint_math @*/ class FDBigInteger {3435//36// This class contains many comments that start with "/*@" mark.37// They are behavourial specification in38// the Java Modelling Language (JML):39// http://www.eecs.ucf.edu/~leavens/JML//index.shtml40//4142/*@43@ public pure model static \bigint UNSIGNED(int v) {44@ return v >= 0 ? v : v + (((\bigint)1) << 32);45@ }46@47@ public pure model static \bigint UNSIGNED(long v) {48@ return v >= 0 ? v : v + (((\bigint)1) << 64);49@ }50@51@ public pure model static \bigint AP(int[] data, int len) {52@ return (\sum int i; 0 <= 0 && i < len; UNSIGNED(data[i]) << (i*32));53@ }54@55@ public pure model static \bigint pow52(int p5, int p2) {56@ ghost \bigint v = 1;57@ for (int i = 0; i < p5; i++) v *= 5;58@ return v << p2;59@ }60@61@ public pure model static \bigint pow10(int p10) {62@ return pow52(p10, p10);63@ }64@*/6566static final int[] SMALL_5_POW = {671,685,695 * 5,705 * 5 * 5,715 * 5 * 5 * 5,725 * 5 * 5 * 5 * 5,735 * 5 * 5 * 5 * 5 * 5,745 * 5 * 5 * 5 * 5 * 5 * 5,755 * 5 * 5 * 5 * 5 * 5 * 5 * 5,765 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,775 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,785 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,795 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,805 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 581};8283static final long[] LONG_5_POW = {841L,855L,865L * 5,875L * 5 * 5,885L * 5 * 5 * 5,895L * 5 * 5 * 5 * 5,905L * 5 * 5 * 5 * 5 * 5,915L * 5 * 5 * 5 * 5 * 5 * 5,925L * 5 * 5 * 5 * 5 * 5 * 5 * 5,935L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,945L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,955L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,965L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,975L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,985L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,995L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,1005L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,1015L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,1025L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,1035L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,1045L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,1055L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,1065L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,1075L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,1085L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,1095L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,1105L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,111};112113// Maximum size of cache of powers of 5 as FDBigIntegers.114private static final int MAX_FIVE_POW = 340;115116// Cache of big powers of 5 as FDBigIntegers.117private static final FDBigInteger POW_5_CACHE[];118119// Initialize FDBigInteger cache of powers of 5.120static {121POW_5_CACHE = new FDBigInteger[MAX_FIVE_POW];122int i = 0;123while (i < SMALL_5_POW.length) {124FDBigInteger pow5 = new FDBigInteger(new int[]{SMALL_5_POW[i]}, 0);125pow5.makeImmutable();126POW_5_CACHE[i] = pow5;127i++;128}129FDBigInteger prev = POW_5_CACHE[i - 1];130while (i < MAX_FIVE_POW) {131POW_5_CACHE[i] = prev = prev.mult(5);132prev.makeImmutable();133i++;134}135}136137// Zero as an FDBigInteger.138public static final FDBigInteger ZERO = new FDBigInteger(new int[0], 0);139140// Ensure ZERO is immutable.141static {142ZERO.makeImmutable();143}144145// Constant for casting an int to a long via bitwise AND.146private final static long LONG_MASK = 0xffffffffL;147148//@ spec_public non_null;149private int data[]; // value: data[0] is least significant150//@ spec_public;151private int offset; // number of least significant zero padding ints152//@ spec_public;153private int nWords; // data[nWords-1]!=0, all values above are zero154// if nWords==0 -> this FDBigInteger is zero155//@ spec_public;156private boolean isImmutable = false;157158/*@159@ public invariant 0 <= nWords && nWords <= data.length && offset >= 0;160@ public invariant nWords == 0 ==> offset == 0;161@ public invariant nWords > 0 ==> data[nWords - 1] != 0;162@ public invariant (\forall int i; nWords <= i && i < data.length; data[i] == 0);163@ public pure model \bigint value() {164@ return AP(data, nWords) << (offset*32);165@ }166@*/167168/**169* Constructs an <code>FDBigInteger</code> from data and padding. The170* <code>data</code> parameter has the least significant <code>int</code> at171* the zeroth index. The <code>offset</code> parameter gives the number of172* zero <code>int</code>s to be inferred below the least significant element173* of <code>data</code>.174*175* @param data An array containing all non-zero <code>int</code>s of the value.176* @param offset An offset indicating the number of zero <code>int</code>s to pad177* below the least significant element of <code>data</code>.178*/179/*@180@ requires data != null && offset >= 0;181@ ensures this.value() == \old(AP(data, data.length) << (offset*32));182@ ensures this.data == \old(data);183@*/184private FDBigInteger(int[] data, int offset) {185this.data = data;186this.offset = offset;187this.nWords = data.length;188trimLeadingZeros();189}190191/**192* Constructs an <code>FDBigInteger</code> from a starting value and some193* decimal digits.194*195* @param lValue The starting value.196* @param digits The decimal digits.197* @param kDigits The initial index into <code>digits</code>.198* @param nDigits The final index into <code>digits</code>.199*/200/*@201@ requires digits != null;202@ requires 0 <= kDigits && kDigits <= nDigits && nDigits <= digits.length;203@ requires (\forall int i; 0 <= i && i < nDigits; '0' <= digits[i] && digits[i] <= '9');204@ ensures this.value() == \old(lValue * pow10(nDigits - kDigits) + (\sum int i; kDigits <= i && i < nDigits; (digits[i] - '0') * pow10(nDigits - i - 1)));205@*/206public FDBigInteger(long lValue, char[] digits, int kDigits, int nDigits) {207int n = Math.max((nDigits + 8) / 9, 2); // estimate size needed.208data = new int[n]; // allocate enough space209data[0] = (int) lValue; // starting value210data[1] = (int) (lValue >>> 32);211offset = 0;212nWords = 2;213int i = kDigits;214int limit = nDigits - 5; // slurp digits 5 at a time.215int v;216while (i < limit) {217int ilim = i + 5;218v = (int) digits[i++] - (int) '0';219while (i < ilim) {220v = 10 * v + (int) digits[i++] - (int) '0';221}222multAddMe(100000, v); // ... where 100000 is 10^5.223}224int factor = 1;225v = 0;226while (i < nDigits) {227v = 10 * v + (int) digits[i++] - (int) '0';228factor *= 10;229}230if (factor != 1) {231multAddMe(factor, v);232}233trimLeadingZeros();234}235236/**237* Returns an <code>FDBigInteger</code> with the numerical value238* <code>5<sup>p5</sup> * 2<sup>p2</sup></code>.239*240* @param p5 The exponent of the power-of-five factor.241* @param p2 The exponent of the power-of-two factor.242* @return <code>5<sup>p5</sup> * 2<sup>p2</sup></code>243*/244/*@245@ requires p5 >= 0 && p2 >= 0;246@ assignable \nothing;247@ ensures \result.value() == \old(pow52(p5, p2));248@*/249public static FDBigInteger valueOfPow52(int p5, int p2) {250if (p5 != 0) {251if (p2 == 0) {252return big5pow(p5);253} else if (p5 < SMALL_5_POW.length) {254int pow5 = SMALL_5_POW[p5];255int wordcount = p2 >> 5;256int bitcount = p2 & 0x1f;257if (bitcount == 0) {258return new FDBigInteger(new int[]{pow5}, wordcount);259} else {260return new FDBigInteger(new int[]{261pow5 << bitcount,262pow5 >>> (32 - bitcount)263}, wordcount);264}265} else {266return big5pow(p5).leftShift(p2);267}268} else {269return valueOfPow2(p2);270}271}272273/**274* Returns an <code>FDBigInteger</code> with the numerical value275* <code>value * 5<sup>p5</sup> * 2<sup>p2</sup></code>.276*277* @param value The constant factor.278* @param p5 The exponent of the power-of-five factor.279* @param p2 The exponent of the power-of-two factor.280* @return <code>value * 5<sup>p5</sup> * 2<sup>p2</sup></code>281*/282/*@283@ requires p5 >= 0 && p2 >= 0;284@ assignable \nothing;285@ ensures \result.value() == \old(UNSIGNED(value) * pow52(p5, p2));286@*/287public static FDBigInteger valueOfMulPow52(long value, int p5, int p2) {288assert p5 >= 0 : p5;289assert p2 >= 0 : p2;290int v0 = (int) value;291int v1 = (int) (value >>> 32);292int wordcount = p2 >> 5;293int bitcount = p2 & 0x1f;294if (p5 != 0) {295if (p5 < SMALL_5_POW.length) {296long pow5 = SMALL_5_POW[p5] & LONG_MASK;297long carry = (v0 & LONG_MASK) * pow5;298v0 = (int) carry;299carry >>>= 32;300carry = (v1 & LONG_MASK) * pow5 + carry;301v1 = (int) carry;302int v2 = (int) (carry >>> 32);303if (bitcount == 0) {304return new FDBigInteger(new int[]{v0, v1, v2}, wordcount);305} else {306return new FDBigInteger(new int[]{307v0 << bitcount,308(v1 << bitcount) | (v0 >>> (32 - bitcount)),309(v2 << bitcount) | (v1 >>> (32 - bitcount)),310v2 >>> (32 - bitcount)311}, wordcount);312}313} else {314FDBigInteger pow5 = big5pow(p5);315int[] r;316if (v1 == 0) {317r = new int[pow5.nWords + 1 + ((p2 != 0) ? 1 : 0)];318mult(pow5.data, pow5.nWords, v0, r);319} else {320r = new int[pow5.nWords + 2 + ((p2 != 0) ? 1 : 0)];321mult(pow5.data, pow5.nWords, v0, v1, r);322}323return (new FDBigInteger(r, pow5.offset)).leftShift(p2);324}325} else if (p2 != 0) {326if (bitcount == 0) {327return new FDBigInteger(new int[]{v0, v1}, wordcount);328} else {329return new FDBigInteger(new int[]{330v0 << bitcount,331(v1 << bitcount) | (v0 >>> (32 - bitcount)),332v1 >>> (32 - bitcount)333}, wordcount);334}335}336return new FDBigInteger(new int[]{v0, v1}, 0);337}338339/**340* Returns an <code>FDBigInteger</code> with the numerical value341* <code>2<sup>p2</sup></code>.342*343* @param p2 The exponent of 2.344* @return <code>2<sup>p2</sup></code>345*/346/*@347@ requires p2 >= 0;348@ assignable \nothing;349@ ensures \result.value() == pow52(0, p2);350@*/351private static FDBigInteger valueOfPow2(int p2) {352int wordcount = p2 >> 5;353int bitcount = p2 & 0x1f;354return new FDBigInteger(new int[]{1 << bitcount}, wordcount);355}356357/**358* Removes all leading zeros from this <code>FDBigInteger</code> adjusting359* the offset and number of non-zero leading words accordingly.360*/361/*@362@ requires data != null;363@ requires 0 <= nWords && nWords <= data.length && offset >= 0;364@ requires nWords == 0 ==> offset == 0;365@ ensures nWords == 0 ==> offset == 0;366@ ensures nWords > 0 ==> data[nWords - 1] != 0;367@*/368private /*@ helper @*/ void trimLeadingZeros() {369int i = nWords;370if (i > 0 && (data[--i] == 0)) {371//for (; i > 0 && data[i - 1] == 0; i--) ;372while(i > 0 && data[i - 1] == 0) {373i--;374}375this.nWords = i;376if (i == 0) { // all words are zero377this.offset = 0;378}379}380}381382/**383* Retrieves the normalization bias of the <code>FDBigIntger</code>. The384* normalization bias is a left shift such that after it the highest word385* of the value will have the 4 highest bits equal to zero:386* <code>(highestWord & 0xf0000000) == 0</code>, but the next bit should be 1387* <code>(highestWord & 0x08000000) != 0</code>.388*389* @return The normalization bias.390*/391/*@392@ requires this.value() > 0;393@*/394public /*@ pure @*/ int getNormalizationBias() {395if (nWords == 0) {396throw new IllegalArgumentException("Zero value cannot be normalized");397}398int zeros = Integer.numberOfLeadingZeros(data[nWords - 1]);399return (zeros < 4) ? 28 + zeros : zeros - 4;400}401402// TODO: Why is anticount param needed if it is always 32 - bitcount?403/**404* Left shifts the contents of one int array into another.405*406* @param src The source array.407* @param idx The initial index of the source array.408* @param result The destination array.409* @param bitcount The left shift.410* @param anticount The left anti-shift, e.g., <code>32-bitcount</code>.411* @param prev The prior source value.412*/413/*@414@ requires 0 < bitcount && bitcount < 32 && anticount == 32 - bitcount;415@ requires src.length >= idx && result.length > idx;416@ assignable result[*];417@ ensures AP(result, \old(idx + 1)) == \old((AP(src, idx) + UNSIGNED(prev) << (idx*32)) << bitcount);418@*/419private static void leftShift(int[] src, int idx, int result[], int bitcount, int anticount, int prev){420for (; idx > 0; idx--) {421int v = (prev << bitcount);422prev = src[idx - 1];423v |= (prev >>> anticount);424result[idx] = v;425}426int v = prev << bitcount;427result[0] = v;428}429430/**431* Shifts this <code>FDBigInteger</code> to the left. The shift is performed432* in-place unless the <code>FDBigInteger</code> is immutable in which case433* a new instance of <code>FDBigInteger</code> is returned.434*435* @param shift The number of bits to shift left.436* @return The shifted <code>FDBigInteger</code>.437*/438/*@439@ requires this.value() == 0 || shift == 0;440@ assignable \nothing;441@ ensures \result == this;442@443@ also444@445@ requires this.value() > 0 && shift > 0 && this.isImmutable;446@ assignable \nothing;447@ ensures \result.value() == \old(this.value() << shift);448@449@ also450@451@ requires this.value() > 0 && shift > 0 && this.isImmutable;452@ assignable \nothing;453@ ensures \result == this;454@ ensures \result.value() == \old(this.value() << shift);455@*/456public FDBigInteger leftShift(int shift) {457if (shift == 0 || nWords == 0) {458return this;459}460int wordcount = shift >> 5;461int bitcount = shift & 0x1f;462if (this.isImmutable) {463if (bitcount == 0) {464return new FDBigInteger(Arrays.copyOf(data, nWords), offset + wordcount);465} else {466int anticount = 32 - bitcount;467int idx = nWords - 1;468int prev = data[idx];469int hi = prev >>> anticount;470int[] result;471if (hi != 0) {472result = new int[nWords + 1];473result[nWords] = hi;474} else {475result = new int[nWords];476}477leftShift(data,idx,result,bitcount,anticount,prev);478return new FDBigInteger(result, offset + wordcount);479}480} else {481if (bitcount != 0) {482int anticount = 32 - bitcount;483if ((data[0] << bitcount) == 0) {484int idx = 0;485int prev = data[idx];486for (; idx < nWords - 1; idx++) {487int v = (prev >>> anticount);488prev = data[idx + 1];489v |= (prev << bitcount);490data[idx] = v;491}492int v = prev >>> anticount;493data[idx] = v;494if(v==0) {495nWords--;496}497offset++;498} else {499int idx = nWords - 1;500int prev = data[idx];501int hi = prev >>> anticount;502int[] result = data;503int[] src = data;504if (hi != 0) {505if(nWords == data.length) {506data = result = new int[nWords + 1];507}508result[nWords++] = hi;509}510leftShift(src,idx,result,bitcount,anticount,prev);511}512}513offset += wordcount;514return this;515}516}517518/**519* Returns the number of <code>int</code>s this <code>FDBigInteger</code> represents.520*521* @return Number of <code>int</code>s required to represent this <code>FDBigInteger</code>.522*/523/*@524@ requires this.value() == 0;525@ ensures \result == 0;526@527@ also528@529@ requires this.value() > 0;530@ ensures ((\bigint)1) << (\result - 1) <= this.value() && this.value() <= ((\bigint)1) << \result;531@*/532private /*@ pure @*/ int size() {533return nWords + offset;534}535536537/**538* Computes539* <pre>540* q = (int)( this / S )541* this = 10 * ( this mod S )542* Return q.543* </pre>544* This is the iteration step of digit development for output.545* We assume that S has been normalized, as above, and that546* "this" has been left-shifted accordingly.547* Also assumed, of course, is that the result, q, can be expressed548* as an integer, 0 <= q < 10.549*550* @param The divisor of this <code>FDBigInteger</code>.551* @return <code>q = (int)(this / S)</code>.552*/553/*@554@ requires !this.isImmutable;555@ requires this.size() <= S.size();556@ requires this.data.length + this.offset >= S.size();557@ requires S.value() >= ((\bigint)1) << (S.size()*32 - 4);558@ assignable this.nWords, this.offset, this.data, this.data[*];559@ ensures \result == \old(this.value() / S.value());560@ ensures this.value() == \old(10 * (this.value() % S.value()));561@*/562public int quoRemIteration(FDBigInteger S) throws IllegalArgumentException {563assert !this.isImmutable : "cannot modify immutable value";564// ensure that this and S have the same number of565// digits. If S is properly normalized and q < 10 then566// this must be so.567int thSize = this.size();568int sSize = S.size();569if (thSize < sSize) {570// this value is significantly less than S, result of division is zero.571// just mult this by 10.572int p = multAndCarryBy10(this.data, this.nWords, this.data);573if(p!=0) {574this.data[nWords++] = p;575} else {576trimLeadingZeros();577}578return 0;579} else if (thSize > sSize) {580throw new IllegalArgumentException("disparate values");581}582// estimate q the obvious way. We will usually be583// right. If not, then we're only off by a little and584// will re-add.585long q = (this.data[this.nWords - 1] & LONG_MASK) / (S.data[S.nWords - 1] & LONG_MASK);586long diff = multDiffMe(q, S);587if (diff != 0L) {588//@ assert q != 0;589//@ assert this.offset == \old(Math.min(this.offset, S.offset));590//@ assert this.offset <= S.offset;591592// q is too big.593// add S back in until this turns +. This should594// not be very many times!595long sum = 0L;596int tStart = S.offset - this.offset;597//@ assert tStart >= 0;598int[] sd = S.data;599int[] td = this.data;600while (sum == 0L) {601for (int sIndex = 0, tIndex = tStart; tIndex < this.nWords; sIndex++, tIndex++) {602sum += (td[tIndex] & LONG_MASK) + (sd[sIndex] & LONG_MASK);603td[tIndex] = (int) sum;604sum >>>= 32; // Signed or unsigned, answer is 0 or 1605}606//607// Originally the following line read608// "if ( sum !=0 && sum != -1 )"609// but that would be wrong, because of the610// treatment of the two values as entirely unsigned,611// it would be impossible for a carry-out to be interpreted612// as -1 -- it would have to be a single-bit carry-out, or +1.613//614assert sum == 0 || sum == 1 : sum; // carry out of division correction615q -= 1;616}617}618// finally, we can multiply this by 10.619// it cannot overflow, right, as the high-order word has620// at least 4 high-order zeros!621int p = multAndCarryBy10(this.data, this.nWords, this.data);622assert p == 0 : p; // Carry out of *10623trimLeadingZeros();624return (int) q;625}626627/**628* Multiplies this <code>FDBigInteger</code> by 10. The operation will be629* performed in place unless the <code>FDBigInteger</code> is immutable in630* which case a new <code>FDBigInteger</code> will be returned.631*632* @return The <code>FDBigInteger</code> multiplied by 10.633*/634/*@635@ requires this.value() == 0;636@ assignable \nothing;637@ ensures \result == this;638@639@ also640@641@ requires this.value() > 0 && this.isImmutable;642@ assignable \nothing;643@ ensures \result.value() == \old(this.value() * 10);644@645@ also646@647@ requires this.value() > 0 && !this.isImmutable;648@ assignable this.nWords, this.data, this.data[*];649@ ensures \result == this;650@ ensures \result.value() == \old(this.value() * 10);651@*/652public FDBigInteger multBy10() {653if (nWords == 0) {654return this;655}656if (isImmutable) {657int[] res = new int[nWords + 1];658res[nWords] = multAndCarryBy10(data, nWords, res);659return new FDBigInteger(res, offset);660} else {661int p = multAndCarryBy10(this.data, this.nWords, this.data);662if (p != 0) {663if (nWords == data.length) {664if (data[0] == 0) {665System.arraycopy(data, 1, data, 0, --nWords);666offset++;667} else {668data = Arrays.copyOf(data, data.length + 1);669}670}671data[nWords++] = p;672} else {673trimLeadingZeros();674}675return this;676}677}678679/**680* Multiplies this <code>FDBigInteger</code> by681* <code>5<sup>p5</sup> * 2<sup>p2</sup></code>. The operation will be682* performed in place if possible, otherwise a new <code>FDBigInteger</code>683* will be returned.684*685* @param p5 The exponent of the power-of-five factor.686* @param p2 The exponent of the power-of-two factor.687* @return688*/689/*@690@ requires this.value() == 0 || p5 == 0 && p2 == 0;691@ assignable \nothing;692@ ensures \result == this;693@694@ also695@696@ requires this.value() > 0 && (p5 > 0 && p2 >= 0 || p5 == 0 && p2 > 0 && this.isImmutable);697@ assignable \nothing;698@ ensures \result.value() == \old(this.value() * pow52(p5, p2));699@700@ also701@702@ requires this.value() > 0 && p5 == 0 && p2 > 0 && !this.isImmutable;703@ assignable this.nWords, this.data, this.data[*];704@ ensures \result == this;705@ ensures \result.value() == \old(this.value() * pow52(p5, p2));706@*/707public FDBigInteger multByPow52(int p5, int p2) {708if (this.nWords == 0) {709return this;710}711FDBigInteger res = this;712if (p5 != 0) {713int[] r;714int extraSize = (p2 != 0) ? 1 : 0;715if (p5 < SMALL_5_POW.length) {716r = new int[this.nWords + 1 + extraSize];717mult(this.data, this.nWords, SMALL_5_POW[p5], r);718res = new FDBigInteger(r, this.offset);719} else {720FDBigInteger pow5 = big5pow(p5);721r = new int[this.nWords + pow5.size() + extraSize];722mult(this.data, this.nWords, pow5.data, pow5.nWords, r);723res = new FDBigInteger(r, this.offset + pow5.offset);724}725}726return res.leftShift(p2);727}728729/**730* Multiplies two big integers represented as int arrays.731*732* @param s1 The first array factor.733* @param s1Len The number of elements of <code>s1</code> to use.734* @param s2 The second array factor.735* @param s2Len The number of elements of <code>s2</code> to use.736* @param dst The product array.737*/738/*@739@ requires s1 != dst && s2 != dst;740@ requires s1.length >= s1Len && s2.length >= s2Len && dst.length >= s1Len + s2Len;741@ assignable dst[0 .. s1Len + s2Len - 1];742@ ensures AP(dst, s1Len + s2Len) == \old(AP(s1, s1Len) * AP(s2, s2Len));743@*/744private static void mult(int[] s1, int s1Len, int[] s2, int s2Len, int[] dst) {745for (int i = 0; i < s1Len; i++) {746long v = s1[i] & LONG_MASK;747long p = 0L;748for (int j = 0; j < s2Len; j++) {749p += (dst[i + j] & LONG_MASK) + v * (s2[j] & LONG_MASK);750dst[i + j] = (int) p;751p >>>= 32;752}753dst[i + s2Len] = (int) p;754}755}756757/**758* Subtracts the supplied <code>FDBigInteger</code> subtrahend from this759* <code>FDBigInteger</code>. Assert that the result is positive.760* If the subtrahend is immutable, store the result in this(minuend).761* If this(minuend) is immutable a new <code>FDBigInteger</code> is created.762*763* @param subtrahend The <code>FDBigInteger</code> to be subtracted.764* @return This <code>FDBigInteger</code> less the subtrahend.765*/766/*@767@ requires this.isImmutable;768@ requires this.value() >= subtrahend.value();769@ assignable \nothing;770@ ensures \result.value() == \old(this.value() - subtrahend.value());771@772@ also773@774@ requires !subtrahend.isImmutable;775@ requires this.value() >= subtrahend.value();776@ assignable this.nWords, this.offset, this.data, this.data[*];777@ ensures \result == this;778@ ensures \result.value() == \old(this.value() - subtrahend.value());779@*/780public FDBigInteger leftInplaceSub(FDBigInteger subtrahend) {781assert this.size() >= subtrahend.size() : "result should be positive";782FDBigInteger minuend;783if (this.isImmutable) {784minuend = new FDBigInteger(this.data.clone(), this.offset);785} else {786minuend = this;787}788int offsetDiff = subtrahend.offset - minuend.offset;789int[] sData = subtrahend.data;790int[] mData = minuend.data;791int subLen = subtrahend.nWords;792int minLen = minuend.nWords;793if (offsetDiff < 0) {794// need to expand minuend795int rLen = minLen - offsetDiff;796if (rLen < mData.length) {797System.arraycopy(mData, 0, mData, -offsetDiff, minLen);798Arrays.fill(mData, 0, -offsetDiff, 0);799} else {800int[] r = new int[rLen];801System.arraycopy(mData, 0, r, -offsetDiff, minLen);802minuend.data = mData = r;803}804minuend.offset = subtrahend.offset;805minuend.nWords = minLen = rLen;806offsetDiff = 0;807}808long borrow = 0L;809int mIndex = offsetDiff;810for (int sIndex = 0; sIndex < subLen && mIndex < minLen; sIndex++, mIndex++) {811long diff = (mData[mIndex] & LONG_MASK) - (sData[sIndex] & LONG_MASK) + borrow;812mData[mIndex] = (int) diff;813borrow = diff >> 32; // signed shift814}815for (; borrow != 0 && mIndex < minLen; mIndex++) {816long diff = (mData[mIndex] & LONG_MASK) + borrow;817mData[mIndex] = (int) diff;818borrow = diff >> 32; // signed shift819}820assert borrow == 0L : borrow; // borrow out of subtract,821// result should be positive822minuend.trimLeadingZeros();823return minuend;824}825826/**827* Subtracts the supplied <code>FDBigInteger</code> subtrahend from this828* <code>FDBigInteger</code>. Assert that the result is positive.829* If the this(minuend) is immutable, store the result in subtrahend.830* If subtrahend is immutable a new <code>FDBigInteger</code> is created.831*832* @param subtrahend The <code>FDBigInteger</code> to be subtracted.833* @return This <code>FDBigInteger</code> less the subtrahend.834*/835/*@836@ requires subtrahend.isImmutable;837@ requires this.value() >= subtrahend.value();838@ assignable \nothing;839@ ensures \result.value() == \old(this.value() - subtrahend.value());840@841@ also842@843@ requires !subtrahend.isImmutable;844@ requires this.value() >= subtrahend.value();845@ assignable subtrahend.nWords, subtrahend.offset, subtrahend.data, subtrahend.data[*];846@ ensures \result == subtrahend;847@ ensures \result.value() == \old(this.value() - subtrahend.value());848@*/849public FDBigInteger rightInplaceSub(FDBigInteger subtrahend) {850assert this.size() >= subtrahend.size() : "result should be positive";851FDBigInteger minuend = this;852if (subtrahend.isImmutable) {853subtrahend = new FDBigInteger(subtrahend.data.clone(), subtrahend.offset);854}855int offsetDiff = minuend.offset - subtrahend.offset;856int[] sData = subtrahend.data;857int[] mData = minuend.data;858int subLen = subtrahend.nWords;859int minLen = minuend.nWords;860if (offsetDiff < 0) {861int rLen = minLen;862if (rLen < sData.length) {863System.arraycopy(sData, 0, sData, -offsetDiff, subLen);864Arrays.fill(sData, 0, -offsetDiff, 0);865} else {866int[] r = new int[rLen];867System.arraycopy(sData, 0, r, -offsetDiff, subLen);868subtrahend.data = sData = r;869}870subtrahend.offset = minuend.offset;871subLen -= offsetDiff;872offsetDiff = 0;873} else {874int rLen = minLen + offsetDiff;875if (rLen >= sData.length) {876subtrahend.data = sData = Arrays.copyOf(sData, rLen);877}878}879//@ assert minuend == this && minuend.value() == \old(this.value());880//@ assert mData == minuend.data && minLen == minuend.nWords;881//@ assert subtrahend.offset + subtrahend.data.length >= minuend.size();882//@ assert sData == subtrahend.data;883//@ assert AP(subtrahend.data, subtrahend.data.length) << subtrahend.offset == \old(subtrahend.value());884//@ assert subtrahend.offset == Math.min(\old(this.offset), minuend.offset);885//@ assert offsetDiff == minuend.offset - subtrahend.offset;886//@ assert 0 <= offsetDiff && offsetDiff + minLen <= sData.length;887int sIndex = 0;888long borrow = 0L;889for (; sIndex < offsetDiff; sIndex++) {890long diff = 0L - (sData[sIndex] & LONG_MASK) + borrow;891sData[sIndex] = (int) diff;892borrow = diff >> 32; // signed shift893}894//@ assert sIndex == offsetDiff;895for (int mIndex = 0; mIndex < minLen; sIndex++, mIndex++) {896//@ assert sIndex == offsetDiff + mIndex;897long diff = (mData[mIndex] & LONG_MASK) - (sData[sIndex] & LONG_MASK) + borrow;898sData[sIndex] = (int) diff;899borrow = diff >> 32; // signed shift900}901assert borrow == 0L : borrow; // borrow out of subtract,902// result should be positive903subtrahend.nWords = sIndex;904subtrahend.trimLeadingZeros();905return subtrahend;906907}908909/**910* Determines whether all elements of an array are zero for all indices less911* than a given index.912*913* @param a The array to be examined.914* @param from The index strictly below which elements are to be examined.915* @return Zero if all elements in range are zero, 1 otherwise.916*/917/*@918@ requires 0 <= from && from <= a.length;919@ ensures \result == (AP(a, from) == 0 ? 0 : 1);920@*/921private /*@ pure @*/ static int checkZeroTail(int[] a, int from) {922while (from > 0) {923if (a[--from] != 0) {924return 1;925}926}927return 0;928}929930/**931* Compares the parameter with this <code>FDBigInteger</code>. Returns an932* integer accordingly as:933* <pre>934* >0: this > other935* 0: this == other936* <0: this < other937* </pre>938*939* @param other The <code>FDBigInteger</code> to compare.940* @return A negative value, zero, or a positive value according to the941* result of the comparison.942*/943/*@944@ ensures \result == (this.value() < other.value() ? -1 : this.value() > other.value() ? +1 : 0);945@*/946public /*@ pure @*/ int cmp(FDBigInteger other) {947int aSize = nWords + offset;948int bSize = other.nWords + other.offset;949if (aSize > bSize) {950return 1;951} else if (aSize < bSize) {952return -1;953}954int aLen = nWords;955int bLen = other.nWords;956while (aLen > 0 && bLen > 0) {957int a = data[--aLen];958int b = other.data[--bLen];959if (a != b) {960return ((a & LONG_MASK) < (b & LONG_MASK)) ? -1 : 1;961}962}963if (aLen > 0) {964return checkZeroTail(data, aLen);965}966if (bLen > 0) {967return -checkZeroTail(other.data, bLen);968}969return 0;970}971972/**973* Compares this <code>FDBigInteger</code> with974* <code>5<sup>p5</sup> * 2<sup>p2</sup></code>.975* Returns an integer accordingly as:976* <pre>977* >0: this > other978* 0: this == other979* <0: this < other980* </pre>981* @param p5 The exponent of the power-of-five factor.982* @param p2 The exponent of the power-of-two factor.983* @return A negative value, zero, or a positive value according to the984* result of the comparison.985*/986/*@987@ requires p5 >= 0 && p2 >= 0;988@ ensures \result == (this.value() < pow52(p5, p2) ? -1 : this.value() > pow52(p5, p2) ? +1 : 0);989@*/990public /*@ pure @*/ int cmpPow52(int p5, int p2) {991if (p5 == 0) {992int wordcount = p2 >> 5;993int bitcount = p2 & 0x1f;994int size = this.nWords + this.offset;995if (size > wordcount + 1) {996return 1;997} else if (size < wordcount + 1) {998return -1;999}1000int a = this.data[this.nWords -1];1001int b = 1 << bitcount;1002if (a != b) {1003return ( (a & LONG_MASK) < (b & LONG_MASK)) ? -1 : 1;1004}1005return checkZeroTail(this.data, this.nWords - 1);1006}1007return this.cmp(big5pow(p5).leftShift(p2));1008}10091010/**1011* Compares this <code>FDBigInteger</code> with <code>x + y</code>. Returns a1012* value according to the comparison as:1013* <pre>1014* -1: this < x + y1015* 0: this == x + y1016* 1: this > x + y1017* </pre>1018* @param x The first addend of the sum to compare.1019* @param y The second addend of the sum to compare.1020* @return -1, 0, or 1 according to the result of the comparison.1021*/1022/*@1023@ ensures \result == (this.value() < x.value() + y.value() ? -1 : this.value() > x.value() + y.value() ? +1 : 0);1024@*/1025public /*@ pure @*/ int addAndCmp(FDBigInteger x, FDBigInteger y) {1026FDBigInteger big;1027FDBigInteger small;1028int xSize = x.size();1029int ySize = y.size();1030int bSize;1031int sSize;1032if (xSize >= ySize) {1033big = x;1034small = y;1035bSize = xSize;1036sSize = ySize;1037} else {1038big = y;1039small = x;1040bSize = ySize;1041sSize = xSize;1042}1043int thSize = this.size();1044if (bSize == 0) {1045return thSize == 0 ? 0 : 1;1046}1047if (sSize == 0) {1048return this.cmp(big);1049}1050if (bSize > thSize) {1051return -1;1052}1053if (bSize + 1 < thSize) {1054return 1;1055}1056long top = (big.data[big.nWords - 1] & LONG_MASK);1057if (sSize == bSize) {1058top += (small.data[small.nWords - 1] & LONG_MASK);1059}1060if ((top >>> 32) == 0) {1061if (((top + 1) >>> 32) == 0) {1062// good case - no carry extension1063if (bSize < thSize) {1064return 1;1065}1066// here sum.nWords == this.nWords1067long v = (this.data[this.nWords - 1] & LONG_MASK);1068if (v < top) {1069return -1;1070}1071if (v > top + 1) {1072return 1;1073}1074}1075} else { // (top>>>32)!=0 guaranteed carry extension1076if (bSize + 1 > thSize) {1077return -1;1078}1079// here sum.nWords == this.nWords1080top >>>= 32;1081long v = (this.data[this.nWords - 1] & LONG_MASK);1082if (v < top) {1083return -1;1084}1085if (v > top + 1) {1086return 1;1087}1088}1089return this.cmp(big.add(small));1090}10911092/**1093* Makes this <code>FDBigInteger</code> immutable.1094*/1095/*@1096@ assignable this.isImmutable;1097@ ensures this.isImmutable;1098@*/1099public void makeImmutable() {1100this.isImmutable = true;1101}11021103/**1104* Multiplies this <code>FDBigInteger</code> by an integer.1105*1106* @param i The factor by which to multiply this <code>FDBigInteger</code>.1107* @return This <code>FDBigInteger</code> multiplied by an integer.1108*/1109/*@1110@ requires this.value() == 0;1111@ assignable \nothing;1112@ ensures \result == this;1113@1114@ also1115@1116@ requires this.value() != 0;1117@ assignable \nothing;1118@ ensures \result.value() == \old(this.value() * UNSIGNED(i));1119@*/1120private FDBigInteger mult(int i) {1121if (this.nWords == 0) {1122return this;1123}1124int[] r = new int[nWords + 1];1125mult(data, nWords, i, r);1126return new FDBigInteger(r, offset);1127}11281129/**1130* Multiplies this <code>FDBigInteger</code> by another <code>FDBigInteger</code>.1131*1132* @param other The <code>FDBigInteger</code> factor by which to multiply.1133* @return The product of this and the parameter <code>FDBigInteger</code>s.1134*/1135/*@1136@ requires this.value() == 0;1137@ assignable \nothing;1138@ ensures \result == this;1139@1140@ also1141@1142@ requires this.value() != 0 && other.value() == 0;1143@ assignable \nothing;1144@ ensures \result == other;1145@1146@ also1147@1148@ requires this.value() != 0 && other.value() != 0;1149@ assignable \nothing;1150@ ensures \result.value() == \old(this.value() * other.value());1151@*/1152private FDBigInteger mult(FDBigInteger other) {1153if (this.nWords == 0) {1154return this;1155}1156if (this.size() == 1) {1157return other.mult(data[0]);1158}1159if (other.nWords == 0) {1160return other;1161}1162if (other.size() == 1) {1163return this.mult(other.data[0]);1164}1165int[] r = new int[nWords + other.nWords];1166mult(this.data, this.nWords, other.data, other.nWords, r);1167return new FDBigInteger(r, this.offset + other.offset);1168}11691170/**1171* Adds another <code>FDBigInteger</code> to this <code>FDBigInteger</code>.1172*1173* @param other The <code>FDBigInteger</code> to add.1174* @return The sum of the <code>FDBigInteger</code>s.1175*/1176/*@1177@ assignable \nothing;1178@ ensures \result.value() == \old(this.value() + other.value());1179@*/1180private FDBigInteger add(FDBigInteger other) {1181FDBigInteger big, small;1182int bigLen, smallLen;1183int tSize = this.size();1184int oSize = other.size();1185if (tSize >= oSize) {1186big = this;1187bigLen = tSize;1188small = other;1189smallLen = oSize;1190} else {1191big = other;1192bigLen = oSize;1193small = this;1194smallLen = tSize;1195}1196int[] r = new int[bigLen + 1];1197int i = 0;1198long carry = 0L;1199for (; i < smallLen; i++) {1200carry += (i < big.offset ? 0L : (big.data[i - big.offset] & LONG_MASK) )1201+ ((i < small.offset ? 0L : (small.data[i - small.offset] & LONG_MASK)));1202r[i] = (int) carry;1203carry >>= 32; // signed shift.1204}1205for (; i < bigLen; i++) {1206carry += (i < big.offset ? 0L : (big.data[i - big.offset] & LONG_MASK) );1207r[i] = (int) carry;1208carry >>= 32; // signed shift.1209}1210r[bigLen] = (int) carry;1211return new FDBigInteger(r, 0);1212}121312141215/**1216* Multiplies a <code>FDBigInteger</code> by an int and adds another int. The1217* result is computed in place. This method is intended only to be invoked1218* from1219* <code>1220* FDBigInteger(long lValue, char[] digits, int kDigits, int nDigits)1221* </code>.1222*1223* @param iv The factor by which to multiply this <code>FDBigInteger</code>.1224* @param addend The value to add to the product of this1225* <code>FDBigInteger</code> and <code>iv</code>.1226*/1227/*@1228@ requires this.value()*UNSIGNED(iv) + UNSIGNED(addend) < ((\bigint)1) << ((this.data.length + this.offset)*32);1229@ assignable this.data[*];1230@ ensures this.value() == \old(this.value()*UNSIGNED(iv) + UNSIGNED(addend));1231@*/1232private /*@ helper @*/ void multAddMe(int iv, int addend) {1233long v = iv & LONG_MASK;1234// unroll 0th iteration, doing addition.1235long p = v * (data[0] & LONG_MASK) + (addend & LONG_MASK);1236data[0] = (int) p;1237p >>>= 32;1238for (int i = 1; i < nWords; i++) {1239p += v * (data[i] & LONG_MASK);1240data[i] = (int) p;1241p >>>= 32;1242}1243if (p != 0L) {1244data[nWords++] = (int) p; // will fail noisily if illegal!1245}1246}12471248//1249// original doc:1250//1251// do this -=q*S1252// returns borrow1253//1254/**1255* Multiplies the parameters and subtracts them from this1256* <code>FDBigInteger</code>.1257*1258* @param q The integer parameter.1259* @param S The <code>FDBigInteger</code> parameter.1260* @return <code>this - q*S</code>.1261*/1262/*@1263@ ensures nWords == 0 ==> offset == 0;1264@ ensures nWords > 0 ==> data[nWords - 1] != 0;1265@*/1266/*@1267@ requires 0 < q && q <= (1L << 31);1268@ requires data != null;1269@ requires 0 <= nWords && nWords <= data.length && offset >= 0;1270@ requires !this.isImmutable;1271@ requires this.size() == S.size();1272@ requires this != S;1273@ assignable this.nWords, this.offset, this.data, this.data[*];1274@ ensures -q <= \result && \result <= 0;1275@ ensures this.size() == \old(this.size());1276@ ensures this.value() + (\result << (this.size()*32)) == \old(this.value() - q*S.value());1277@ ensures this.offset == \old(Math.min(this.offset, S.offset));1278@ ensures \old(this.offset <= S.offset) ==> this.nWords == \old(this.nWords);1279@ ensures \old(this.offset <= S.offset) ==> this.offset == \old(this.offset);1280@ ensures \old(this.offset <= S.offset) ==> this.data == \old(this.data);1281@1282@ also1283@1284@ requires q == 0;1285@ assignable \nothing;1286@ ensures \result == 0;1287@*/1288private /*@ helper @*/ long multDiffMe(long q, FDBigInteger S) {1289long diff = 0L;1290if (q != 0) {1291int deltaSize = S.offset - this.offset;1292if (deltaSize >= 0) {1293int[] sd = S.data;1294int[] td = this.data;1295for (int sIndex = 0, tIndex = deltaSize; sIndex < S.nWords; sIndex++, tIndex++) {1296diff += (td[tIndex] & LONG_MASK) - q * (sd[sIndex] & LONG_MASK);1297td[tIndex] = (int) diff;1298diff >>= 32; // N.B. SIGNED shift.1299}1300} else {1301deltaSize = -deltaSize;1302int[] rd = new int[nWords + deltaSize];1303int sIndex = 0;1304int rIndex = 0;1305int[] sd = S.data;1306for (; rIndex < deltaSize && sIndex < S.nWords; sIndex++, rIndex++) {1307diff -= q * (sd[sIndex] & LONG_MASK);1308rd[rIndex] = (int) diff;1309diff >>= 32; // N.B. SIGNED shift.1310}1311int tIndex = 0;1312int[] td = this.data;1313for (; sIndex < S.nWords; sIndex++, tIndex++, rIndex++) {1314diff += (td[tIndex] & LONG_MASK) - q * (sd[sIndex] & LONG_MASK);1315rd[rIndex] = (int) diff;1316diff >>= 32; // N.B. SIGNED shift.1317}1318this.nWords += deltaSize;1319this.offset -= deltaSize;1320this.data = rd;1321}1322}1323return diff;1324}132513261327/**1328* Multiplies by 10 a big integer represented as an array. The final carry1329* is returned.1330*1331* @param src The array representation of the big integer.1332* @param srcLen The number of elements of <code>src</code> to use.1333* @param dst The product array.1334* @return The final carry of the multiplication.1335*/1336/*@1337@ requires src.length >= srcLen && dst.length >= srcLen;1338@ assignable dst[0 .. srcLen - 1];1339@ ensures 0 <= \result && \result < 10;1340@ ensures AP(dst, srcLen) + (\result << (srcLen*32)) == \old(AP(src, srcLen) * 10);1341@*/1342private static int multAndCarryBy10(int[] src, int srcLen, int[] dst) {1343long carry = 0;1344for (int i = 0; i < srcLen; i++) {1345long product = (src[i] & LONG_MASK) * 10L + carry;1346dst[i] = (int) product;1347carry = product >>> 32;1348}1349return (int) carry;1350}13511352/**1353* Multiplies by a constant value a big integer represented as an array.1354* The constant factor is an <code>int</code>.1355*1356* @param src The array representation of the big integer.1357* @param srcLen The number of elements of <code>src</code> to use.1358* @param value The constant factor by which to multiply.1359* @param dst The product array.1360*/1361/*@1362@ requires src.length >= srcLen && dst.length >= srcLen + 1;1363@ assignable dst[0 .. srcLen];1364@ ensures AP(dst, srcLen + 1) == \old(AP(src, srcLen) * UNSIGNED(value));1365@*/1366private static void mult(int[] src, int srcLen, int value, int[] dst) {1367long val = value & LONG_MASK;1368long carry = 0;1369for (int i = 0; i < srcLen; i++) {1370long product = (src[i] & LONG_MASK) * val + carry;1371dst[i] = (int) product;1372carry = product >>> 32;1373}1374dst[srcLen] = (int) carry;1375}13761377/**1378* Multiplies by a constant value a big integer represented as an array.1379* The constant factor is a long represent as two <code>int</code>s.1380*1381* @param src The array representation of the big integer.1382* @param srcLen The number of elements of <code>src</code> to use.1383* @param v0 The lower 32 bits of the long factor.1384* @param v1 The upper 32 bits of the long factor.1385* @param dst The product array.1386*/1387/*@1388@ requires src != dst;1389@ requires src.length >= srcLen && dst.length >= srcLen + 2;1390@ assignable dst[0 .. srcLen + 1];1391@ ensures AP(dst, srcLen + 2) == \old(AP(src, srcLen) * (UNSIGNED(v0) + (UNSIGNED(v1) << 32)));1392@*/1393private static void mult(int[] src, int srcLen, int v0, int v1, int[] dst) {1394long v = v0 & LONG_MASK;1395long carry = 0;1396for (int j = 0; j < srcLen; j++) {1397long product = v * (src[j] & LONG_MASK) + carry;1398dst[j] = (int) product;1399carry = product >>> 32;1400}1401dst[srcLen] = (int) carry;1402v = v1 & LONG_MASK;1403carry = 0;1404for (int j = 0; j < srcLen; j++) {1405long product = (dst[j + 1] & LONG_MASK) + v * (src[j] & LONG_MASK) + carry;1406dst[j + 1] = (int) product;1407carry = product >>> 32;1408}1409dst[srcLen + 1] = (int) carry;1410}14111412// Fails assertion for negative exponent.1413/**1414* Computes <code>5</code> raised to a given power.1415*1416* @param p The exponent of 5.1417* @return <code>5<sup>p</sup></code>.1418*/1419private static FDBigInteger big5pow(int p) {1420assert p >= 0 : p; // negative power of 51421if (p < MAX_FIVE_POW) {1422return POW_5_CACHE[p];1423}1424return big5powRec(p);1425}14261427// slow path1428/**1429* Computes <code>5</code> raised to a given power.1430*1431* @param p The exponent of 5.1432* @return <code>5<sup>p</sup></code>.1433*/1434private static FDBigInteger big5powRec(int p) {1435if (p < MAX_FIVE_POW) {1436return POW_5_CACHE[p];1437}1438// construct the value.1439// recursively.1440int q, r;1441// in order to compute 5^p,1442// compute its square root, 5^(p/2) and square.1443// or, let q = p / 2, r = p -q, then1444// 5^p = 5^(q+r) = 5^q * 5^r1445q = p >> 1;1446r = p - q;1447FDBigInteger bigq = big5powRec(q);1448if (r < SMALL_5_POW.length) {1449return bigq.mult(SMALL_5_POW[r]);1450} else {1451return bigq.mult(big5powRec(r));1452}1453}14541455// for debugging ...1456/**1457* Converts this <code>FDBigInteger</code> to a hexadecimal string.1458*1459* @return The hexadecimal string representation.1460*/1461public String toHexString(){1462if(nWords ==0) {1463return "0";1464}1465StringBuilder sb = new StringBuilder((nWords +offset)*8);1466for(int i= nWords -1; i>=0; i--) {1467String subStr = Integer.toHexString(data[i]);1468for(int j = subStr.length(); j<8; j++) {1469sb.append('0');1470}1471sb.append(subStr);1472}1473for(int i=offset; i>0; i--) {1474sb.append("00000000");1475}1476return sb.toString();1477}14781479// for debugging ...1480/**1481* Converts this <code>FDBigInteger</code> to a <code>BigInteger</code>.1482*1483* @return The <code>BigInteger</code> representation.1484*/1485public BigInteger toBigInteger() {1486byte[] magnitude = new byte[nWords * 4 + 1];1487for (int i = 0; i < nWords; i++) {1488int w = data[i];1489magnitude[magnitude.length - 4 * i - 1] = (byte) w;1490magnitude[magnitude.length - 4 * i - 2] = (byte) (w >> 8);1491magnitude[magnitude.length - 4 * i - 3] = (byte) (w >> 16);1492magnitude[magnitude.length - 4 * i - 4] = (byte) (w >> 24);1493}1494return new BigInteger(magnitude).shiftLeft(offset * 32);1495}14961497// for debugging ...1498/**1499* Converts this <code>FDBigInteger</code> to a string.1500*1501* @return The string representation.1502*/1503@Override1504public String toString(){1505return toBigInteger().toString();1506}1507}150815091510