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