src/java.base/share/classes/jdk/internal/math/FDBigInteger.java
changeset 57894 01b9c26e2651
parent 47216 71c04702a3d5
equal deleted inserted replaced
57893:49fea19f0726 57894:01b9c26e2651
    22  * or visit www.oracle.com if you need additional information or have any
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 package jdk.internal.math;
    25 package jdk.internal.math;
    26 
    26 
       
    27 import jdk.internal.misc.VM;
       
    28 
    27 import java.math.BigInteger;
    29 import java.math.BigInteger;
    28 import java.util.Arrays;
    30 import java.util.Arrays;
    29 //@ model import org.jmlspecs.models.JMLMath;
    31 //@ model import org.jmlspecs.models.JMLMath;
    30 
    32 
    31 /**
    33 /**
    62     @ public pure model static \bigint pow10(int p10) {
    64     @ public pure model static \bigint pow10(int p10) {
    63     @     return pow52(p10, p10);
    65     @     return pow52(p10, p10);
    64     @ }
    66     @ }
    65     @*/
    67     @*/
    66 
    68 
    67     static final int[] SMALL_5_POW = {
    69     static final int[] SMALL_5_POW;
    68             1,
    70 
    69             5,
    71     static final long[] LONG_5_POW;
    70             5 * 5,
       
    71             5 * 5 * 5,
       
    72             5 * 5 * 5 * 5,
       
    73             5 * 5 * 5 * 5 * 5,
       
    74             5 * 5 * 5 * 5 * 5 * 5,
       
    75             5 * 5 * 5 * 5 * 5 * 5 * 5,
       
    76             5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
    77             5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
    78             5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
    79             5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
    80             5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
    81             5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5
       
    82     };
       
    83 
       
    84     static final long[] LONG_5_POW = {
       
    85             1L,
       
    86             5L,
       
    87             5L * 5,
       
    88             5L * 5 * 5,
       
    89             5L * 5 * 5 * 5,
       
    90             5L * 5 * 5 * 5 * 5,
       
    91             5L * 5 * 5 * 5 * 5 * 5,
       
    92             5L * 5 * 5 * 5 * 5 * 5 * 5,
       
    93             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
    94             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
    95             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
    96             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
    97             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
    98             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
    99             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   100             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   101             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   102             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   103             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   104             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   105             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   106             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   107             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   108             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   109             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   110             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   111             5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   112     };
       
   113 
    72 
   114     // Maximum size of cache of powers of 5 as FDBigIntegers.
    73     // Maximum size of cache of powers of 5 as FDBigIntegers.
   115     private static final int MAX_FIVE_POW = 340;
    74     private static final int MAX_FIVE_POW = 340;
   116 
    75 
   117     // Cache of big powers of 5 as FDBigIntegers.
    76     // Cache of big powers of 5 as FDBigIntegers.
   118     private static final FDBigInteger POW_5_CACHE[];
    77     private static final FDBigInteger POW_5_CACHE[];
   119 
    78 
       
    79     // Zero as an FDBigInteger.
       
    80     public static final FDBigInteger ZERO;
       
    81 
       
    82     // Archive proxy
       
    83     private static Object[] archivedCaches;
       
    84 
   120     // Initialize FDBigInteger cache of powers of 5.
    85     // Initialize FDBigInteger cache of powers of 5.
   121     static {
    86     static {
   122         POW_5_CACHE = new FDBigInteger[MAX_FIVE_POW];
    87         VM.initializeFromArchive(FDBigInteger.class);
   123         int i = 0;
    88         Object[] caches = archivedCaches;
   124         while (i < SMALL_5_POW.length) {
    89         if (caches == null) {
   125             FDBigInteger pow5 = new FDBigInteger(new int[]{SMALL_5_POW[i]}, 0);
    90             long[] long5pow = {
   126             pow5.makeImmutable();
    91                     1L,
   127             POW_5_CACHE[i] = pow5;
    92                     5L,
   128             i++;
    93                     5L * 5,
   129         }
    94                     5L * 5 * 5,
   130         FDBigInteger prev = POW_5_CACHE[i - 1];
    95                     5L * 5 * 5 * 5,
   131         while (i < MAX_FIVE_POW) {
    96                     5L * 5 * 5 * 5 * 5,
   132             POW_5_CACHE[i] = prev = prev.mult(5);
    97                     5L * 5 * 5 * 5 * 5 * 5,
   133             prev.makeImmutable();
    98                     5L * 5 * 5 * 5 * 5 * 5 * 5,
   134             i++;
    99                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5,
   135         }
   100                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
   136     }
   101                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
   137 
   102                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
   138     // Zero as an FDBigInteger.
   103                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
   139     public static final FDBigInteger ZERO = new FDBigInteger(new int[0], 0);
   104                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
   140 
   105                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
   141     // Ensure ZERO is immutable.
   106                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
   142     static {
   107                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
   143         ZERO.makeImmutable();
   108                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   109                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   110                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   111                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   112                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   113                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   114                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   115                     5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   116                     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,
       
   117                     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,
       
   118                 };
       
   119             int[] small5pow = {
       
   120                     1,
       
   121                     5,
       
   122                     5 * 5,
       
   123                     5 * 5 * 5,
       
   124                     5 * 5 * 5 * 5,
       
   125                     5 * 5 * 5 * 5 * 5,
       
   126                     5 * 5 * 5 * 5 * 5 * 5,
       
   127                     5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   128                     5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   129                     5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   130                     5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   131                     5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   132                     5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
       
   133                     5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5
       
   134                 };
       
   135             FDBigInteger[] pow5cache = new FDBigInteger[MAX_FIVE_POW];
       
   136             int i = 0;
       
   137             while (i < small5pow.length) {
       
   138                 FDBigInteger pow5 = new FDBigInteger(new int[] { small5pow[i] }, 0);
       
   139                 pow5.makeImmutable();
       
   140                 pow5cache[i] = pow5;
       
   141                 i++;
       
   142             }
       
   143             FDBigInteger prev = pow5cache[i - 1];
       
   144             while (i < MAX_FIVE_POW) {
       
   145                 pow5cache[i] = prev = prev.mult(5);
       
   146                 prev.makeImmutable();
       
   147                 i++;
       
   148             }
       
   149             FDBigInteger zero = new FDBigInteger(new int[0], 0);
       
   150             zero.makeImmutable();
       
   151             archivedCaches = caches = new Object[] {small5pow, long5pow, pow5cache, zero};
       
   152         }
       
   153         SMALL_5_POW = (int[])caches[0];
       
   154         LONG_5_POW = (long[])caches[1];
       
   155         POW_5_CACHE = (FDBigInteger[])caches[2];
       
   156         ZERO = (FDBigInteger)caches[3];
   144     }
   157     }
   145 
   158 
   146     // Constant for casting an int to a long via bitwise AND.
   159     // Constant for casting an int to a long via bitwise AND.
   147     private static final long LONG_MASK = 0xffffffffL;
   160     private static final long LONG_MASK = 0xffffffffL;
   148 
   161