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