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