home *** CD-ROM | disk | FTP | other *** search
/ Best Tools for JAVA / Best Tools for JAVA.iso / JAVA_ALL / JDBC / JDBC_011 / JAVA / LANG / BIGNUM.JAV
Encoding:
Text File  |  1996-11-10  |  61.1 KB  |  2,222 lines

  1. /*
  2.  * @(#)Bignum.java    1.8 96/11/08
  3.  *
  4.  * Copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "LICENSE"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  *
  19.  * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
  20.  * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
  21.  * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
  22.  * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
  23.  * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
  24.  * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
  25.  * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").  SUN
  26.  * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
  27.  * HIGH RISK ACTIVITIES.
  28.  */
  29.  
  30.  
  31.  
  32. package java.lang;
  33. import java.util.Random;
  34.  
  35. /**
  36.  * The Bignum class represents fixed point numbers of practically
  37.  * unlimited precision. The size of each instance depends on the
  38.  * number of digits it represents(its precision). The precision of an
  39.  * instance's fractional part is determined by its scale.
  40.  *
  41.  * <P>The rounding behaviors needed for business and scientific
  42.  * computation often differ. To meet this requirement, the rounding
  43.  * behavior for the class as a whole can be changed.
  44.  *
  45.  * <P>The Bignum class should be used for values that require high
  46.  * precision fixed point or integer computation. Examples of this are
  47.  * money values, security key values and values stored in databases
  48.  * using the high precision SQL NUMERIC or DECIMAL type.
  49.  *
  50.  * <P>Calculations on Bignum objects always return a new Bignum object
  51.  * with the same scale as the Bignum that performed the
  52.  * calculation. Most operations are carried out to one extra decimal
  53.  * place and rounded to the desired scale.
  54.  *
  55.  * <P>Bignum's are immutable and thread-safe.
  56.  *
  57.  * <P>Since Bignum values with 10's of thousands of digits can be
  58.  * represented, the practical limit to their precision is the space
  59.  * and time needed to work with them. The max scale value is max int;
  60.  * the max precision of this implementation is limited only by Java's
  61.  * maximum array size.
  62.  *
  63.  * <P>Bignum objects are composed of three properties: <UL>
  64.  * <LI>Scale: The number of digits to the right of the decimal point.
  65.  * <LI>Sign:  Positive or negative.
  66.  * <LI>Value: In this implementation, a vector of integer digits of radix 2^30.
  67.  * </UL> */
  68. public final class Bignum extends java.lang.Number {
  69.  
  70.     /**
  71.      * Sets the rounding option for all Bignum's in a program; the
  72.      * default rounding option is ROUND_ABOVE_4.
  73.      *
  74.      * <P>All Bignum computation is done using an extra digit of
  75.      * precision which is truncated prior to returning the result. The
  76.      * rounding option determines how the value of this extra digit
  77.      * affects the returned value. Rounding also applies when the
  78.      * scale of a Bignum is reduced; here, rounding defines how the
  79.      * value of the most significant truncated digit affects the
  80.      * result.
  81.      *
  82.      * <P>If rounding causes the least signifcant digit of a result to
  83.      * be incremented by 1, we say the result has been 'rounded up'. If
  84.      * the least signficant digit of a result is left as is, we say the
  85.      * result has been 'rounded down'.
  86.      *
  87.      * <P>The following rounding options are provided:
  88.      *
  89.      * <DL>
  90.      *  <DT>NO_ROUNDING:        <DD>All results are rounded down regardless
  91.      *                          of the value of the most significant truncated digit.
  92.      *                          For example, 1.999 would round to 1.99.
  93.      *
  94.      *  <DT>ROUND_ABOVE_4:      <DD>If the value of the most significant truncated
  95.      *                          digit is > 4, the result is rounded up; otherwise,
  96.      *                          the result is rounded down. For example, 1.994 would
  97.      *                          round down to 1.99 and 1.995 would round up to 2.00
  98.      *
  99.      *  <DT>ROUND_ABOVE_5:      <DD>If the value of the most significant truncated
  100.      *                          digit is > 5, the result is rounded up; otherwise,
  101.      *                          the result is rounded down. For example, 1.995 would
  102.      *                          round down to 1.99 and 1.996 would round up to 2.00.
  103.      *
  104.      *  <DT>ROUND_ALWAYS :      <DD>If the value of the most significant truncated
  105.      *                          digit is > 0, the result is rounded up; otherwise,
  106.      *                          the result is rounded down. For example, 1.990 would
  107.      *                          round down to 1.99 and 1.991 would round up to 2.00.
  108.      *
  109.      *  <DT>ROUND_STATISTICAL : <DD>If the value of the most significant truncated
  110.      *                          digit is > 5, the result is rounded up.  If the value
  111.      *                          of the most significant truncated digit is < 5, the
  112.      *                          result is rounded down. If the value of the most
  113.      *                          significant truncated digit is = 5, the result is
  114.      *                          rounded down if the remaining least significant digit
  115.      *                          is even; if it's odd the result is rounded up.
  116.      *                          For example, 1.994 would round down to 1.99; 1.996 would
  117.      *                          round up to 2.00; 1.985 would round down to 1.98; and, 1.995
  118.      *                          would round up to 2.00. This option is used to help reduce
  119.      *                          systematic rounding bias. See Bevington and Robinson,
  120.      *                          'Data Reduction and Error Analysis for the Physical Sciences',
  121.      *                          pp. 4, McGraw Hill, Inc., (1992).
  122.      * </DL>
  123.      * @param val The rounding option to use for all Bignum's.
  124.      */
  125.  
  126.     public static void setRoundingOption(int val) {
  127.         switch(val) {
  128.     case ROUND_STATISTICAL :
  129.         roundingValue = -1;
  130.         break;
  131.     case  NO_ROUNDING :
  132.         roundingValue = 9;
  133.         break;
  134.     case  ROUND_ABOVE_5 :
  135.         roundingValue = 5 ;
  136.         break;
  137.     case  ROUND_ABOVE_4:
  138.         roundingValue= 4;
  139.         break;
  140.     case  ROUND_ALWAYS:
  141.         roundingValue = 0;
  142.         break;
  143.     default:
  144.         if (val < 0 || val > 9)
  145.         throw new IllegalArgumentException("Attempt to set invalid RoundingOption");
  146.         break;
  147.     }
  148.     }
  149.  
  150.     /**
  151.      * Returns the current rounding option for all Bignum's in this
  152.      * program.
  153.      *
  154.      * @return current rounding option
  155.      */
  156.     public static int getRoundingOption() {
  157.         return(roundingValue);
  158.     }
  159.  
  160.     /**
  161.      * Creates a Bignum from a string. The string may contain a sign
  162.      * and a decimal point, e.g "-55.12".  Spaces and other
  163.      * non-numeric characters are ignored. Scientific notation, i.e.
  164.      * mantissa with exponent (3E.05) is supported.
  165.      *
  166.      * @param s the string used to initialize the Bignum.
  167.      */
  168.  
  169.     public Bignum(String s) {
  170.     init(s,-1);
  171.     }
  172.  
  173.     /**
  174.      * Construct a Bignum given a String and an integer scale.  The
  175.      * scale represents the desired number of places to the right of
  176.      * the decimal point.
  177.      *
  178.      * <P>The String may contain a sign and a decimal point,
  179.      * e.g. "-55.12".  Spaces and other non-numeric characters are
  180.      * ignored. Scientific notation, i.e. mantissa with exponent
  181.      * (3E.05) is supported. The scale must be an integer with value
  182.      * greater than or equal to zero.  If the scale differs from the
  183.      * implicit decimal point given in the String the value is
  184.      * adjusted to the given scale.  This may involve rounding.
  185.      *
  186.      * <P>For example, Bignum("99.995",2) would result in a Bignum
  187.      * with a scale of 2 and a value of "100.00".  If the String
  188.      * contains no decimal point, then the scale is determined solely
  189.      * by the given integer scale. No implicit decimal point is
  190.      * assumed.  For example, the constructor Bignum("123",2) creates
  191.      * a Bignum with a scale of 2 and a value of
  192.      * "123.00".
  193.      *
  194.      * <P><B>Note:</B> Rounding is controlled by the roundingIndex
  195.      * function.
  196.      *
  197.      * @param  s    the string used to initialize the Bignum.
  198.      * @param scale the value greater than or equal to zero
  199.      * representing the desired number of digits to the right of the
  200.      * decimal point.
  201.      */
  202.     public Bignum(String s,int scale) {
  203.     verifyScale(scale);
  204.     init(s,scale);
  205.     }
  206.  
  207.     /**
  208.      * Construct a Bignum from an integer given an integer value and
  209.      * an integer scale.  The scale is set to the value specified. No
  210.      * implicit decimal point is assumed, i.e., if the integer value is
  211.      * "1234" and the scale 2, the resulting Bignum will be "1234.00.
  212.      *
  213.      * @param  x    The int used to initialize the new Bignum.
  214.      * @param scale The desired number of digits after the decimal point.
  215.      */
  216.     public Bignum(int x,int scale) {
  217.     verifyScale(scale);
  218.     if(x < 0) {
  219.         negative = true;
  220.         x *= -1;
  221.         if(x < 0) {
  222.         int[] v = {0,2};
  223.         value = v;
  224.         _setScale(scale);
  225.         return;
  226.         }
  227.     }
  228.     else
  229.         negative = false;
  230.     int digit0 = (int)(x & MASK);
  231.     long carry = (long)x >> SRADIX;
  232.     int digit1 = (int) (carry & MASK);
  233.  
  234.     if(digit1 > 0) {
  235.         int[] v = {digit0,digit1};
  236.         value = v;
  237.     }
  238.     else {
  239.         int [] v = {digit0};
  240.         value = v;
  241.     }
  242.     _setScale(scale);
  243.     }
  244.     /**
  245.      * Construct a Bignum from an integer given an integer value.
  246.      * The scale is set to zero.
  247.      *
  248.      * @param  x    The long used to initialize the new Bignum.
  249.      */
  250.     public Bignum(int x) {
  251.     this(x,0);
  252.     }
  253.     /**
  254.      * Construct a Bignum from a long integer given a long value and
  255.      * an integer scale.  The scale is set to the value specified. No
  256.      * implicit decimal point is assumed, i.e., if the long value is
  257.      * "1234" and the scale 2, the resulting Bignum will be "1234.00.
  258.      *
  259.      * @param  x    The long value used to initialize the new Bignum.
  260.      * @param scale The desired number of digits after the decimal point.
  261.      */
  262.     public Bignum(long x,int scale) {
  263.     verifyScale(scale);
  264.  
  265.     if(x < 0) {
  266.         negative = true;
  267.         x *= -1L;
  268.         if(x < 0) {
  269.         int[] v = {0,0,8};
  270.         value = v;
  271.         _setScale(scale);
  272.         return;
  273.         }
  274.     }
  275.     else
  276.         negative = false;
  277.     int digit0 = (int)(x & MASK);
  278.     long carry = x >> SRADIX;
  279.     int digit1 = (int) (carry & MASK);
  280.     carry = carry >> SRADIX;
  281.     int digit2 = (int) (carry & MASK);
  282.     if(digit2 > 0) {
  283.         int[] v= {digit0,digit1,digit2};
  284.         value = v;
  285.     }
  286.     else
  287.         if(digit1 > 0) {
  288.                 int[] v = {digit0,digit1};
  289.                 value = v;
  290.             }
  291.             else {
  292.                 int [] v = {digit0};
  293.         value = v;
  294.         }
  295.     _setScale(scale);
  296.     }
  297.     /**
  298.      * Construct a Bignum from a long integer given a long integer value.
  299.      * The scale is set to zero.
  300.      *
  301.      * @param  x    The long used to initialize the new Bignum.
  302.      */
  303.     public Bignum(long x) {
  304.     this(x,0);
  305.     }
  306.  
  307.     /**
  308.      * Construct a Bignum from a double given a double value and an
  309.      * integer scale.  The scale is set to the value specified. No
  310.      * implicit decimal point is assumed, i.e., if the double value is
  311.      * "1234" and the scale 2, the resulting Bignum will be "1234.00.
  312.      * If the double value is "1234.5" and the scale 2 the value will
  313.      * be "1234.50".  Rounding may occur during this conversion.
  314.      *
  315.      * @param  x    The double value used to initialize the new Bignum.
  316.      * @param scale The desired number of digits after the decimal point.
  317.      */
  318.     public Bignum(double x, int scale) {
  319.     verifyScale(scale);
  320.     Double d = new Double(x);//I'm going to have to redo this to
  321.     init(d.toString(),scale);// calculate exponent and fraction
  322.     //This is a cheat.
  323.     }
  324.  
  325.     /**
  326.      * Construct a Bignum from another Bignum.  The
  327.      * scale and value of the new Bignum are copied from the Bignum
  328.      * given in the argument.
  329.      *
  330.      * @param x The Bignum used to initialize the new Bignum.
  331.      */
  332.     public Bignum(Bignum x) {
  333.     scale = x.scale;
  334.     value = new int[x.value.length];
  335.     System.arraycopy(x.value,0,value,0,value.length);
  336.     negative = x.negative;
  337.     }
  338.  
  339.     /**
  340.      * Given an existing Bignum and an integer scale value, construct
  341.      * a new Bignum with the scale adjusted accordingly.  The
  342.      * scale and value of the new Bignum are copied from
  343.      * the argument Bignum. The scale is then adjusted to the scale
  344.      * given as a parameter. This may result in rounding of the value.
  345.      *
  346.      * @param  x        The Bignum to copy.
  347.      * @param scale An integer representing the desired * scale of the
  348.      * new Bignum.
  349.      */
  350.     public Bignum(Bignum x, int scale) {
  351.     verifyScale(scale);
  352.     this.scale = x.scale;
  353.     value = new int[x.value.length];
  354.     System.arraycopy(x.value,0,value,0,value.length);
  355.     negative = x.negative;
  356.     if (this.scale != scale) {
  357.         _setScale(scale);
  358.     }
  359.     }
  360.     //----------------------Static Factory Methods----------------------------
  361.     /**
  362.      * Return a Bignum created from the given byte array.
  363.      * The array is treated as a string of bits representing an unsigned
  364.      * integer, with the most significant bit at the 0th position.  This
  365.      * function is supplied to simplify and optimize operations in
  366.      * algorithms using large integers, such as hashing calculations.
  367.      *
  368.      * @param byteArray An array of bytes holding the bitstring value of
  369.      *    the desired Bignum.
  370.      * @return A new Bignum whose value is determined by the given byte array.
  371.      */
  372.     public static Bignum createFromByteArray(byte[] byteArray) {
  373.     Bignum    r = new Bignum(0);
  374.     int    numBits = byteArray.length * 8;
  375.     int    numWords = (numBits + (SRADIX - 1)) / SRADIX;
  376.  
  377.     r.scale = 0;
  378.     r.negative = false;
  379.     r.value = new int [numWords];
  380.  
  381.     // byteArray[] is big-endian, base256; value[] is little-endian
  382.     // and base 2^SRADIX.  this stuffs bits into value[], LSB first.
  383.  
  384.     for (int i = byteArray.length - 1, digit = 0; i >= 0; i--) {
  385.         int        bits, bitOffset;
  386.  
  387.         bits = byteArray [i] & 0x0ff;
  388.         bitOffset = ((byteArray.length - i - 1) * 8) % SRADIX;
  389.         r.value [digit] |= (bits << bitOffset) & MASK;
  390.  
  391.         bitOffset = SRADIX - bitOffset;
  392.         if (bitOffset <= 8) {
  393.             digit++;
  394.             if (bitOffset < 8)
  395.             r.value [digit] |= (bits >>> bitOffset);
  396.         }
  397.     }//for
  398.  
  399.     return r;
  400.     }
  401.     /**
  402.      * Returns  a byte array derived from the value of the numeric.
  403.      * The array is considered a string of bits with the most significant bit
  404.      * at the 0th position.This function should be used with great caution.
  405.      * It is supplied to simplify and optimize calculations in algorithms that
  406.      * used hashing calculations, e.g. many security algorithms.
  407.      * @returns A byte array derived from the value of the Bignum
  408.      */
  409.     public  byte[] toByteArray(){
  410.     int i,j;
  411.     i = significantBits();
  412.     if(i <= 0) {
  413.         byte[] b = new byte[1];
  414.         b[0] = 0x00;
  415.     }
  416.     j = i/8;
  417.     if(i%8 >0) j++;
  418.  
  419.     byte [] outArray = new byte[j];
  420.  
  421.     int[] r = new int[value.length];
  422.     System.arraycopy(value,0,r,0,value.length);
  423.     for(j=outArray.length - 1;j >= 0; j--) {
  424.         outArray[j] = (byte)(r[0] & 0x000000FF);
  425.         int carry = 0;
  426.         for (i=value.length - 1; i>=0; --i) {
  427.         int val = r[i];
  428.         r[i] = (val>>>8) | carry;
  429.         carry = (int)((val<<(SRADIX-8)) & MASK);
  430.         }
  431.     }
  432.     return outArray;
  433.     }
  434.  
  435.     /**
  436.      * Return a Bignum created from the given Integer array.
  437.      * The array is considered a string of bits with the least significant bit
  438.      * at the 0th position. This function should be used with great caution.
  439.      * It is supplied to simplify and optimize calculations in algorithms that
  440.      * used hashing calculations, e.g. many security algorithms.
  441.      * @param  intArray    An array of integers holding the desired value of the new Bignum.
  442.      * @return A new Bignum whose value is determined by the given integer array.
  443.      */
  444.     public static Bignum createFromIntegerArray(int [] intArray) {
  445.     int[] t1 = new int[intArray.length + 1];
  446.     for(int i = 0; i < intArray.length;i++){
  447.         t1[i]  = (int)(intArray[i] & MASK);
  448.     }
  449.     Bignum r = new Bignum(t1);
  450.     r.scale = 0;
  451.     r.negative = false;
  452.  
  453.     return r;
  454.     }
  455.     /**
  456.      * Return a Bignum value created by dividing the argument by
  457.      * 10**scale.  Thus, createFromScaled(504,2) would create the
  458.      * value "5.04". A negative scale throws an IllegalArgumentException.
  459.      *
  460.      * @param  scaled The scaled value as a long.
  461.      * @param  s      The desired scale value
  462.      * @return A new Bignum.
  463.      */
  464.     public static Bignum createFromScaled(long scaled, int s) {
  465.     verifyScale(s);
  466.     Bignum n = new Bignum(scaled);
  467.     if (s != 0)
  468.         n.scale = s;
  469.     return n;
  470.     }
  471.  
  472.     /**
  473.      * Return a Bignum created from the given string and radix.
  474.      * Decimal places are ignored and the scale is set to zero.
  475.      * The string may contain a sign.
  476.      * @param  s    A string containing the intended value of the Bignum.
  477.      * @param  radix    The base of the string representation.
  478.      * @return A new Bignum whose value is given by the string argument.
  479.      */
  480.     public static Bignum createFromRadixString(String s, int radix) {
  481.     Bignum r = new Bignum(0);
  482.     r.scale = 0;
  483.     r.negative = false;
  484.     r.value = new int[s.length()/(radix/2) + 1];
  485.  
  486.     int[] t1;
  487.     //char maxChar = Character.forDigit(radix - 1,radix);
  488.     int a;
  489.     char c;
  490.     boolean gotFirstDigit = false;
  491.     for (int i = 0;i < s.length() ;i++ ) {
  492.         c = s.charAt(i);
  493.         a = Character.digit(c,radix);
  494.         if(a >= 0){
  495.         gotFirstDigit = true;
  496.         t1 = mulAndAdd(r.value,radix,a);
  497.         if(t1 != null)
  498.             r.value = t1;
  499.         continue;
  500.         }
  501.         if (c == '-' && !gotFirstDigit) {
  502.         r.negative = true;
  503.         continue;
  504.         }
  505.     }//for
  506.     return r;
  507.     }
  508.     /**
  509.      *Random number generator
  510.      *Returns a random number using randomSeed as a seed and with a number of bits of up to bitSize.
  511.      *@param bitSize The position of the most significant bit in the random number
  512.      *@param randomSeed a Random number used as the seed for the random number generated
  513.      *@return a new Bignum of maximium size bitSize
  514.      */
  515.     public static Bignum random(int bits, Random randomSeed){
  516.     int ni = (bits-1)/SRADIX + 1;
  517.     int i;
  518.     bits = bits % SRADIX;
  519.     int[] rs = new int[ni];
  520.     for (i=0; i<ni; ++i) {
  521.         int r = (int) (randomSeed.nextInt() & MASK);
  522.         rs[i] = r;
  523.     }
  524.     rs[ni-1] &= (1<<bits)-1;
  525.     Bignum rslt = new Bignum(rs);
  526.     rslt.dropLeadingZeroes();
  527.     return rslt;
  528.     }
  529.  
  530.  
  531.     /**
  532.      * The following methods convert the Bignum value to an
  533.      * appropriate Java built-in type.  Note that these conversions
  534.      * may result in a loss of precision.
  535.      *
  536.      */
  537.  
  538.     /**
  539.      * Convert the Bignum value an int.
  540.      * This conversion may result in a loss of precision.  Digits
  541.      * after the decimal point are dropped.
  542.      *
  543.      * @return An int value representation of the Bignum.
  544.      */
  545.     public int intValue() {
  546.     return ((int)longValue());
  547.     }
  548.  
  549.     /**
  550.      * Convert the Bignum value to a long.
  551.      * This conversion may result in a loss of precision.  Digits
  552.      * after the decimal point are dropped.
  553.      *
  554.      * @return A long value representation of the Bignum.
  555.      */
  556.     public long longValue() {
  557.     Bignum temp = new Bignum(this);
  558.     temp._setScale(0);
  559.     long lv = 0;
  560.     int i = temp.value.length < 3 ? temp.value.length - 1: 2;
  561.  
  562.     for(;i >= 0;i--){
  563.         lv = (lv << SRADIX) + temp.value[i];
  564.     }
  565.     return temp.negative? -lv : lv;
  566.     }
  567.  
  568.     /**
  569.      * Convert the Bignum value to a float.
  570.      * This conversion may result in a loss of precision.
  571.      *
  572.      * @return A float value representation of the Bignum.
  573.      */
  574.     public float floatValue() {
  575.     return ((float) doubleValue());
  576.     }
  577.  
  578.     /**
  579.      * Convert the Bignum value to a double.
  580.      * This conversion may result in a loss of precision.
  581.      *
  582.      * @return A double value representation of the Bignum.
  583.      */
  584.     public  double doubleValue() {
  585.     Bignum temp = new Bignum(this);
  586.     temp._setScale(0);
  587.     double d=0.0;
  588.     int m = value.length - 1;
  589.     m = m > 4? m - 4 : 0;
  590.     for(int i=value.length - 1;i>=m;i--) {
  591.         d = d * MASK + (double) value[i];
  592.     }
  593.     if(m > 0)
  594.         d = d * Math.pow(SRADIX,m);
  595.     temp = this.subtract(temp);
  596.  
  597.     if (scale != 0) {
  598.         double  s = 1;
  599.         s = Math.pow(10,scale);
  600.         d = d/s;
  601.     }
  602.     return negative? -d : d;
  603.     }
  604.  
  605.  
  606.     /**
  607.      * Convert the Bignum value to a String.
  608.      * Negative numbers are represented by a leading "-". No sign is
  609.      * added for positive numbers.
  610.      *
  611.      * @return A String representation of the Bignum.
  612.      */
  613.     public  String toString() {
  614.     if(value == null)
  615.         return "null";
  616.     int l = value.length * 10 + 2;
  617.  
  618.     if(l < scale)
  619.         l = scale + 2;
  620.  
  621.     char[] x = new char[l];
  622.     int xi=x.length - 1;
  623.     int dp = xi - scale;
  624.     if(scale == 0)
  625.         dp = -9999;
  626.     int[] temp = new int[value.length];
  627.     System.arraycopy(value,0,temp,0,temp.length);
  628.     for (int i=temp.length - 1; i >= 0;) {
  629.         if(temp[i] == 0){
  630.         i--;
  631.         continue;
  632.         }
  633.         int rem = div0(temp,temp,10);
  634.         x[xi--] = Character.forDigit(rem,10);
  635.         if(xi == dp) xi--;
  636.     }
  637.     if(xi == x.length - 1) //was value all zeroes?
  638.         x[xi--] = '0';
  639.     if(dp > 0){
  640.         while(xi > dp)
  641.         x[xi--] = '0';
  642.         x[dp] = '.';
  643.     }
  644.     String ms = negative ? "-":"";
  645.     ms += (new String(x,xi,x.length - xi)).trim();
  646.     return ms;
  647.     }
  648.  
  649.     /**
  650.      * Returns a String representation of the Bignum in the given radix.
  651.      * In this version scaling is ignored for any radix other than 10.
  652.      * @param radix    the base of the number to be returned
  653.      * @return a String representation of the Bignum in the given radix
  654.      */
  655.     public String toString(int radix) {
  656.     if(radix == 10)
  657.         return toString();
  658.  
  659.     if(value == null)
  660.         return "null";
  661.  
  662.     StringBuffer sb = new StringBuffer();
  663.     int[] temp = new int[value.length];
  664.     int len = 0;
  665.     System.arraycopy(value,0,temp,0,temp.length);
  666.     for (int i=temp.length - 1; i >= 0;) {
  667.         if(temp[i] == 0){
  668.         i--;
  669.         continue;
  670.         }
  671.         int rem = div0(temp,temp,radix);
  672.         sb.insert(0,Character.forDigit(rem,radix));
  673.         len++;
  674.     }
  675.     if(len==0)
  676.         sb.insert(0,'0');
  677.     String ms = negative ? "-":"";
  678.     ms += (sb.toString()).trim();
  679.     return ms;
  680.  
  681.     }
  682.  
  683.  
  684.     /**
  685.      * Return the number of digits to the right of the decimal point.
  686.      *
  687.      *
  688.      * @return An integer value representing the number of decimal
  689.      * places to the right of the decimal point.
  690.      */
  691.     public int getScale() {
  692.     return (scale);
  693.     }
  694.  
  695.  
  696.     //-----------------------------Arithmetic Operations------------------
  697.     /**
  698.      * Returns the arithmetic sum of the Bignum and the argument.
  699.      * The scale of the sum is determined by this object not by the
  700.      * argument. The calculation is performed using a
  701.      * scale equal to the greater scale of the two operands. Rounding is
  702.      * applied to the result.
  703.      *
  704.      * @param  n  The Bignum to add.
  705.      * @return The sum as a Bignum.
  706.      */
  707.     public Bignum add(Bignum n) {
  708.         Bignum result= new Bignum(this);
  709.     Bignum x;
  710.     if(scale != n.scale){
  711.         x = new Bignum(n);
  712.         x._setScale(scale);
  713.     }
  714.     else
  715.         x = n;
  716.         //signs match
  717.         if (result.negative == x.negative) {
  718.             result.value = add0(result.value,x.value);
  719.             return (result);
  720.         }
  721.         //result is positive
  722.         if (!result.negative) {
  723.             int cmp = result.compareAbs(x);
  724.             if (cmp < 0) { //abs value of result is less
  725.         result.value = sub0(x.value,result.value);
  726.         result.negative = x.negative;
  727.         return (result);
  728.             } else {
  729.         if (cmp > 0) { //abs value of result is greater
  730.             result.value = sub0(result.value,x.value);
  731.             return (result);
  732.         } else { //abs values are equal
  733.             result.zero();
  734.             return (result);
  735.  
  736.         }
  737.             }
  738.         }
  739.  
  740.         //result is negative
  741.         int cmp = result.compareAbs(x);
  742.         if (cmp < 0) { //abs value of result is less
  743.             result.value = sub0(x.value,result.value);
  744.             result.negative = x.negative;
  745.             return (result);
  746.         } else {
  747.             if (cmp > 0) { //abs value of result is greater
  748.         result.value = sub0(result.value,x.value);
  749.  
  750.         return (result);
  751.             }
  752.         }
  753.         //abs values  are equal
  754.         result.zero();
  755.         return (result);
  756.     }
  757.  
  758.     /**
  759.      * Returns the arithmetic difference between the Bignum and the
  760.      * argument.  The scale of the difference is determined by this object
  761.      * not by the argument. The calculation is performed using a
  762.      * scale equal to the greater scale of the two operands. Rounding is
  763.      * applied to the result.
  764.      *
  765.      * @param  n The Bignum to subtract.
  766.      * @return The difference as a Bignum.
  767.      */
  768.     public Bignum subtract(Bignum n) {
  769.     Bignum result = new Bignum(this);
  770.     Bignum x;
  771.     if(result.scale != n.scale) {
  772.         if(result.scale > n.scale) {
  773.             x = new Bignum(n);
  774.             x._setScale(result.scale);
  775.         }
  776.         else {
  777.             x = n;
  778.             result._setScale(x.scale);
  779.         }
  780.     }
  781.     else
  782.         x = n;
  783.  
  784.     if (result.negative == false && x.negative == false) {
  785.         switch(result.compareAbs(x)) {
  786.         case 0:
  787.         result.zero();
  788.         break;
  789.         case 1:
  790.         result.value = sub0(result.value,x.value);
  791.         break;
  792.         default:
  793.         result.value = sub0(x.value,result.value);
  794.         result.negative = true;
  795.         }
  796.         if(result.scale != this.scale)
  797.             result._setScale(this.scale);
  798.         return (result);
  799.     }
  800.  
  801.     if (result.negative == false && x.negative == true) {
  802.         result.value = add0(result.value,x.value);
  803.     }
  804.     else if (result.negative == true && x.negative == false) {
  805.         result.value = add0(result.value,x.value);
  806.     }
  807.     else {
  808.         switch(result.compareAbs(x)) {
  809.         case 0:
  810.         result.zero();
  811.         break;
  812.         case 1:
  813.         result.value = sub0(result.value,x.value);
  814.         result.negative = true;
  815.         break;
  816.         default:
  817.         result.value = sub0(x.value,result.value);
  818.         result.negative = false;
  819.         }
  820.     }
  821.     if(result.scale != this.scale)
  822.         result._setScale(this.scale);
  823.  
  824.     return (result);
  825.     }
  826.  
  827.     /**
  828.      * Returns the arithmetic product of the object Bignum and the
  829.      * argument.  The scale of the product is determined by this object
  830.      * not by the argument.
  831.      *
  832.      * @param  x The multiplier as a Bignum.
  833.      * @return The product as a Bignum.
  834.      */
  835.     public Bignum multiply(Bignum x) {
  836.  
  837.     Bignum prod = new Bignum(this); //product
  838.     Bignum m; //multiplicand
  839.     Bignum mx; //multiplier
  840.  
  841.     prod.scale += x.scale;
  842.     prod.negative = (negative == x.negative? false: true);
  843.  
  844.     if (value.length > x.value.length) {
  845.         //use the smallest number as the multiplier
  846.         m = this;
  847.         mx = x;
  848.     } else {
  849.         m = x;
  850.         mx = this;
  851.     }
  852.     if(mx.value.length == 1)
  853.         prod.value = mul0(m.value,mx.value[0]);//use the faster single digit multiply
  854.     else
  855.         prod.value = mul0(m.value,mx.value);
  856.  
  857.     if(prod.scale != scale)
  858.         prod._setScale(scale);
  859.     prod.dropLeadingZeroes();
  860.     return (prod);
  861.     }
  862.  
  863.     /**
  864.      * Returns the arithmetic quotient calculated by dividing the
  865.      * Bignum by the argument.  The scale of the quotient is
  866.      * determined by this object not by the argument.
  867.      *
  868.      * @param  x The divisor as a Bignum.
  869.      * @return The quotient as a Bignum.
  870.      */
  871.  
  872.     public Bignum divide(Bignum x) {
  873.     if (x.compareAbs(Bignum.ZERO) == 0) {
  874.         throw new ArithmeticException("Division by zero");
  875.     }
  876.  
  877.     Bignum dividend = new Bignum(this);
  878.     Bignum divisor = new Bignum(x);
  879.  
  880.     dividend.dropLeadingZeroes();
  881.     divisor.dropLeadingZeroes();
  882.     //scaling for decimal places
  883.     if(roundingValue < 9 || (divisor.scale > dividend.scale)) {
  884.         int scaleFactor = divisor.scale + 1;
  885.         dividend.scale++;
  886.         int m1 = 9; //this is approx log10 of BASE
  887.         int m4 = 1000000000;
  888.         int x1 = scaleFactor;
  889.         for(;x1 >= m1;x1 -= m1 )
  890.         dividend.value = mul0(dividend.value,m4);
  891.         if(x1 > 0 )
  892.         dividend.value = mul0(dividend.value,pow(10,x1));
  893.     }
  894.  
  895.     //----------------------------------------------------------------
  896.     Bignum quot = new Bignum(new int[(dividend.value.length - divisor.value.length) + 1]);
  897.     quot.negative = divisor.negative ? !dividend.negative : dividend.negative;
  898.     quot.scale = dividend.scale;
  899.     if(divisor.value.length == 1){
  900.         //if divisor is only 1 digit use quick division
  901.         //remainder can only be an int
  902.         div0(quot.value,dividend.value,divisor.value[0]);
  903.         quot._setScale(scale);
  904.         return quot;
  905.     }
  906.     //Next normalize the dividend and divisor, i.e. divisor[leftmostDigit] >= BASE/2
  907.     //
  908.     int vLeftmostDigit = divisor.value[divisor.value.length - 1];
  909.     if(vLeftmostDigit >= (BASE)/2){
  910.             int[] tvalue = new int[dividend.value.length + 1];
  911.             System.arraycopy(dividend.value, 0, tvalue, 0, dividend.value.length);
  912.             tvalue[tvalue.length - 1] = 0;
  913.             dividend.value = tvalue;
  914.             div (dividend, divisor, quot);
  915.         } else {
  916.             int[] tvalue = new int[dividend.value.length + 1];
  917.             System.arraycopy(dividend.value,0,tvalue,0,dividend.value.length);
  918.             int d = (BASE)/(vLeftmostDigit + 1);
  919.             dividend.value = mul0(tvalue,d);
  920.             divisor.value = mul0(divisor.value,d);
  921.             div (dividend, divisor, quot);
  922.         }
  923.     quot._setScale(scale);
  924.     return quot;
  925.     }
  926.     /**
  927.      * Returns an array of two Bignum objects. The first element in
  928.      * the array holds the quotient value resulting from the arithmetic
  929.      * division of this Bignum object by the argument. The second element
  930.      * in the array holds the remainder.
  931.      *
  932.      * @param  x The divisor as a Bignum.
  933.      * @return An array of two Bignum objects containing the quotient and
  934.      * remainder of the division.
  935.      */
  936.  
  937.     public Bignum[] integerDivide(Bignum x) {
  938.     if (x.compareAbs(Bignum.ZERO) == 0) {
  939.         throw new ArithmeticException("Division by zero");
  940.     }
  941.  
  942.     Bignum dividend = new Bignum(this);
  943.     Bignum divisor = new Bignum(x);
  944.     Bignum quot = _intDivide(divisor,dividend,scale);
  945.  
  946.     Bignum[] r = {quot,dividend};
  947.     return r;
  948.     }
  949.  
  950.  
  951.     /* Private helper function for performing integer division
  952.      * and remainder arithmetic.
  953.      * the remainder is returned in dividend
  954.      */
  955.     static private Bignum  _intDivide(Bignum divisor,Bignum dividend, int scale){
  956.  
  957.  
  958.     dividend.dropLeadingZeroes();
  959.     divisor.dropLeadingZeroes();
  960.  
  961.  
  962.     //scaling for decimal places
  963.     if(divisor.scale > dividend.scale) {
  964.         int scaleFactor = divisor.scale;// + 1;
  965.         //dividend.scale++;
  966.         int m1 = 9; //this is approx log10 of BASE
  967.         int m4 = 1000000000;
  968.         int x1 = scaleFactor;
  969.         for(;x1 >= m1;x1 -= m1 )
  970.         dividend.value = mul0(dividend.value,m4);
  971.         if(x1 > 0 )
  972.         dividend.value = mul0(dividend.value,pow(10,x1));
  973.     }
  974.  
  975.     //--------------------------------------------------------------------
  976.     if(dividend.lessThan(divisor)){
  977.         return new Bignum(0,0);
  978.     }
  979.     Bignum quot = new Bignum(new int[(dividend.value.length - divisor.value.length) + 1]);
  980.     quot.negative = divisor.negative ? !dividend.negative : dividend.negative;
  981.     if(dividend.scale >= divisor.scale)
  982.         quot.scale = dividend.scale - divisor.scale;
  983.     else
  984.         quot.scale = 0;
  985.  
  986.     //if divisor is only 1 digit use quick division
  987.     if(divisor.value.length == 1){
  988.         //remainder can only be an int
  989.         int rem = div0(quot.value,dividend.value,divisor.value[0]);
  990.         dividend.zero();
  991.         dividend.value[0] = (int) (rem & MASK);
  992.         long carry = (long)rem >> SRADIX;
  993.         int digit1 = (int) (carry & MASK);
  994.         if (digit1 > 0) {
  995.         if(dividend.value.length < 2 ) {
  996.             int[] newval = {dividend.value[0],digit1};
  997.             dividend.value = newval;
  998.         }
  999.         else
  1000.             dividend.value[1] = digit1;
  1001.         }
  1002.         if(quot.scale > 0)
  1003.         return truncate(quot);
  1004.         else
  1005.         return quot;
  1006.     }
  1007.     //Next normalize the dividend and divisor, i.e. divisor[leftmostDigit] >= BASE/2
  1008.     //
  1009.     int vLeftmostDigit = divisor.value[divisor.value.length - 1];
  1010.  
  1011.     if(vLeftmostDigit >= (BASE)/2){
  1012.             int[] tvalue = new int[dividend.value.length + 1];
  1013.             System.arraycopy(dividend.value, 0, tvalue, 0, dividend.value.length);
  1014.             tvalue[tvalue.length - 1] = 0;
  1015.             dividend.value = tvalue;
  1016.             div (dividend, divisor, quot);
  1017.         } else {
  1018.             int[] tvalue = new int[dividend.value.length + 1];
  1019.             System.arraycopy(dividend.value,0,tvalue,0,dividend.value.length);
  1020.             int d = (BASE)/(vLeftmostDigit + 1);
  1021.             dividend.value = mul0(tvalue,d);
  1022.             divisor.value = mul0(divisor.value,d);
  1023.             div (dividend, divisor, quot);
  1024.             div0(dividend.value,dividend.value,d);
  1025.         }
  1026.  
  1027.     //quot._setScale(scale);
  1028.  
  1029.     if(quot.scale > 0) {
  1030.         quot = truncate(quot);
  1031.  
  1032.         }
  1033.  
  1034.     return quot;
  1035.  
  1036.     }
  1037.     /**
  1038.      * Returns the arithmentic remainder calculated by dividing this
  1039.      * Bignum object by the argument.  No rounding is performed.
  1040.      *
  1041.      * @param  x The divisor as a Bignum.
  1042.      * @return The remainder as a Bignum.
  1043.      */
  1044.     public Bignum remainder(Bignum x) {
  1045.     if (x.compareAbs(Bignum.ZERO) == 0) {
  1046.         throw new ArithmeticException("Division by zero");
  1047.     }
  1048.  
  1049.     if(this.lessThan(x))
  1050.         return new Bignum(this);
  1051.  
  1052.        Bignum dividend = new Bignum(this);
  1053.        Bignum divisor = new Bignum(x);
  1054.     _intDivide(divisor,dividend,scale);
  1055.     return dividend;
  1056.     }
  1057.  
  1058.  
  1059.  
  1060.  
  1061.     /**
  1062.      * Square root
  1063.      * Returns the square root of this Bignum.
  1064.      * @return the square root of this Bignum.
  1065.      */
  1066.     public Bignum sqrt() {
  1067.  
  1068.     // Uses a Newtonian convergence algorithm.
  1069.         Bignum g = new Bignum(this,scale + 1);
  1070.         Bignum temp = new Bignum(0);
  1071.         div0(g.value,g.value,2);
  1072.         Bignum eps = createFromScaled(5,g.scale);
  1073.         Bignum diff = (g.multiply(g)).subtract(this);
  1074.         while(diff.compareAbs(eps) > 0){
  1075.             temp.value = mul0(g.value,2);
  1076.             temp.scale = g.scale;
  1077.             temp.negative = g.negative;
  1078.  
  1079.             temp = diff.divide(temp);
  1080.             g = g.subtract(temp);
  1081.             temp = g.multiply(g);
  1082.  
  1083.             diff = temp.subtract(this);
  1084.         }
  1085.         return g;
  1086.     }
  1087.  
  1088.     /**
  1089.      * Returns a new Bignum whose value is calculated by
  1090.      * raising this Bignum to the power of the given exponent.
  1091.      * @param e An integer value cotaining the exponent to be used.
  1092.      * @return this Bignum raised to the power given by the exponent argument.
  1093.      */
  1094.  
  1095.     public Bignum pow(int e) {
  1096.     //A binary power algorithm is used.
  1097.     if(e==0) return new Bignum(1.0,scale);
  1098.     Bignum ans = new Bignum(this);
  1099.     int[] t = {1};
  1100.     while(e > 1) {
  1101.         if((e & 0x0001)==0x0001){
  1102.         t = mul0(t, ans.value);
  1103.         }
  1104.         ans.value = mul0(ans.value,ans.value);
  1105.         e >>=1;
  1106.     }
  1107.     ans.value = mul0(ans.value,t);
  1108.     ans.dropLeadingZeroes();
  1109.     return ans;
  1110.     }
  1111.  
  1112.     /**
  1113.      * Returns true if the arithmetic value of the Bignum equals the
  1114.      * argument.
  1115.      *
  1116.      * @param  obj The object to compare.
  1117.      * @return The boolean result of the comparison.
  1118.      */
  1119.     public  boolean equals(Object obj) {
  1120.         Bignum x = (Bignum) obj;
  1121.         if (compare(x) == 0) {
  1122.             return (true);
  1123.         }
  1124.         return (false);
  1125.     }
  1126.  
  1127.     /**
  1128.      * Returns true if the arithmetic value of the Bignum is less
  1129.      * than the argument.
  1130.      *
  1131.      * @param  x The object to compare.
  1132.      * @return The boolean result of the comparison.
  1133.      */
  1134.     public boolean lessThan(Bignum x) {
  1135.     if (compare(x) == -1) {
  1136.         return (true);
  1137.     }
  1138.     return (false);
  1139.     }
  1140.  
  1141.     /**
  1142.      * Returns true if the arithmetic value of the Bignum is less
  1143.      * than or equals the argument.
  1144.      *
  1145.      * @param  x The object to compare.
  1146.      * @return The boolean result of the comparison.
  1147.      */
  1148.     public  boolean lessThanOrEquals(Bignum x) {
  1149.     if (compare(x) != 1) {
  1150.         return (true);
  1151.     }
  1152.     return (false);
  1153.     }
  1154.  
  1155.     /**
  1156.      * Returns true if the arithmetic value of the Bignum is greater
  1157.      * than the argument.
  1158.      *
  1159.      * @param  x The object to compare.
  1160.      * @return The boolean result of the comparison.
  1161.      */
  1162.     public  boolean greaterThan(Bignum x) {
  1163.     if (compare(x) == 1) {
  1164.         return (true);
  1165.     }
  1166.     return (false);
  1167.     }
  1168.  
  1169.     /**
  1170.      * Returns true if the arithmetic value of the Bignum is greater
  1171.      * than or equals the argument.
  1172.      *
  1173.      * @param  x The object to compare.
  1174.      * @return The boolean result of the comparison.
  1175.      */
  1176.     public  boolean greaterThanOrEquals(Bignum x) {
  1177.     if (compare(x) != -1) {
  1178.         return (true);
  1179.     }
  1180.     return (false);
  1181.     }
  1182.  
  1183.     /**
  1184.      * Returns an integer hashcode for the Bignum.
  1185.      *
  1186.      * @return The hashcode as an integer.
  1187.      */
  1188.     public int hashCode() {
  1189.         int hash = 0;
  1190.         for(int i = 0; i < value.length; i++) {
  1191.             try {
  1192.                 hash += value[i];
  1193.             }catch(Exception ex){
  1194.                 hash = 0;
  1195.             }
  1196.  
  1197.         }
  1198.         return hash;
  1199.     }
  1200.  
  1201.     /**
  1202.      * Returns a Bignum copied from the current object with the scale
  1203.      * set as specified by the argument.  Note that changing the scale
  1204.      * to a smaller value may result in rounding.
  1205.      *
  1206.      * @param  scale the character to be converted
  1207.      * @return A Bignum with the adjusted scale.
  1208.      * @see Bignum#setRoundingOption
  1209.      */
  1210.     public Bignum setScale(int scale) {
  1211.         verifyScale(scale);
  1212.         Bignum x = new Bignum(this,scale);
  1213.         return (x);
  1214.     }
  1215.     //------------------------------Bit Operations------------------------
  1216.     /**
  1217.      *Returns the number of significant bits in the Bignum.
  1218.      *@return an integer containing the number of the most significant bit
  1219.      * of this Bignum.
  1220.      */
  1221.     public int significantBits() {
  1222.     int i;
  1223.     for(i = value.length - 1; i >= 0 && value[i] == 0;--i);
  1224.     if(i < 0)
  1225.         return 0;
  1226.     int val = value[i];
  1227.     int l = i;
  1228.     i = 0;
  1229.     while(val !=0){
  1230.         val >>>=1;
  1231.         ++i;
  1232.     }
  1233.  
  1234.     l = l  * SRADIX;
  1235.     return l + i;
  1236.     }
  1237.     /**
  1238.      * Returns a new Bignum whose value is calculated by shifting this
  1239.      * Bignum to the left by the number of bits given in shiftBits
  1240.      *
  1241.      * @param shiftBits the number of bits to shift.
  1242.      * @return A new Bignum whose value is this Bignum / 2^shiftBits
  1243.      */
  1244.     public  Bignum shiftRight(int shiftBits){
  1245.     if(shiftBits < 0)
  1246.         throw new IllegalArgumentException("Number of bits to shift may not be negative");
  1247.  
  1248.     int nw = shiftBits / SRADIX;
  1249.     shiftBits %= SRADIX;
  1250.     int[] r = new int[value.length - nw];
  1251.     System.arraycopy(value,nw,r,0,value.length - nw);
  1252.     int i;
  1253.     int carry = 0;
  1254.     for (i=r.length - 1; i>=0; --i) {
  1255.         int val = r[i];
  1256.         r[i] = (val>>>shiftBits) | carry;
  1257.         carry = (int)((val<<(SRADIX-shiftBits)) & MASK);
  1258.     }
  1259.     Bignum result = new Bignum(r);
  1260.     result.dropLeadingZeroes();
  1261.     return result;
  1262.  
  1263.     }
  1264.     /**
  1265.      *  Returns a new Bignum calculated by shifting this Bignum to the
  1266.      *  left by the number of bits given in shiftBits.
  1267.      *
  1268.      *  @param shiftBits The number of bits to shift
  1269.      *  @return A new Bignum whose value is this Bignum * 2^shiftBits
  1270.      */
  1271.     public Bignum shiftLeft(int shiftBits){
  1272.     if(shiftBits < 0)
  1273.         throw new IllegalArgumentException("Number of bits to shift may not be negative");
  1274.     int nw = shiftBits / SRADIX;
  1275.     shiftBits %= SRADIX;
  1276.     int[] r = new int[value.length + nw + 1];
  1277.  
  1278.     System.arraycopy(value, 0, r, nw, value.length);
  1279.  
  1280.     int i;
  1281.     int carry = 0;
  1282.     for (i=0; i< r.length - 1; ++i) {
  1283.         int val = r[i];
  1284.         r[i] = (int)((val<<shiftBits) | carry & MASK);
  1285.         carry = val >>>(SRADIX - shiftBits);
  1286.     }
  1287.     if(carry != 0)
  1288.         r[r.length -1] = carry;
  1289.  
  1290.     Bignum result = new Bignum(r);
  1291.     result.dropLeadingZeroes();
  1292.     return result;
  1293.     }
  1294.  
  1295.     //------------------------------Modular Arithmetic----------------------
  1296.     /**
  1297.      * Returns the modular multiplicative inverse of this Bignum
  1298.      * @param mod the modulus to be used
  1299.      * @return the modular multiplicative inverse of this Bignum using "mod" as
  1300.      * the modulus
  1301.      */
  1302.     public Bignum modInverse(Bignum mod) {
  1303.     Bignum i = new Bignum(mod);
  1304.     Bignum h = new Bignum(this);
  1305.     Bignum v = new Bignum(ZERO);
  1306.     Bignum d = new Bignum(1);
  1307.     while(h.greaterThan(ZERO)) {
  1308.         Bignum tt[] = i.integerDivide(h);
  1309.         Bignum t = tt[0];
  1310.         Bignum x = h;
  1311.         h = i.subtract(t.multiply(x));
  1312.         i = x;
  1313.         x = d;
  1314.         d = v.subtract(t.multiply(x));
  1315.         v = x;
  1316.  
  1317.     }
  1318.     if(!v.negative)
  1319.         return v.remainder(mod);
  1320.     Bignum m = (v.remainder(mod)).multiply(mod);
  1321.     return(v.subtract(m));
  1322.  
  1323.  
  1324.     }
  1325.  
  1326.     /**
  1327.      * Modular exponentiation. Calculates a new Bignum
  1328.      * @param exponent the exponent to be used
  1329.      * @param mod the modulus to be used
  1330.      * @return a new Bignum whose values is this^exponent mod "mod".
  1331.      */
  1332.  
  1333.     public Bignum modExp (Bignum exponent, Bignum mod){
  1334.     int ipr = exponent.significantBits() - 1;
  1335.     int ibit = 1 << (ipr % SRADIX);
  1336.     ipr = ipr / SRADIX;
  1337.     int[] t = new int[value.length  + 1];
  1338.     Bignum rslt = new Bignum(ONE);
  1339.     while (ipr >= 0) {
  1340.  
  1341.         rslt.value  = mul0(rslt.value,rslt.value,t);
  1342.         if(rslt.value != t)
  1343.         t = rslt.value;
  1344.         rslt = rslt.remainder(mod);
  1345.         if ((exponent.value[ipr] & ibit) != 0) {
  1346.                 for(int i = 0; i < t.length;i++) t[i] = 0;
  1347.         rslt.value = mul0(rslt.value,this.value,t);
  1348.         if(rslt.value != t)
  1349.             t = rslt.value;
  1350.         rslt = rslt.remainder(mod);
  1351.         }
  1352.         ibit >>>= 1;
  1353.         if (ibit==0) {
  1354.         --ipr;
  1355.         ibit = 1<<(SRADIX-1);
  1356.         }
  1357.         for(int i = 0; i < t.length;i++) t[i] = 0;
  1358.     }
  1359.     return rslt;
  1360.     }
  1361.     //----------------------Prime Number Testing----------------------------
  1362.     private static int[] smallPrimes = new int[51];
  1363.  
  1364.     static {
  1365.         smallPrimes[0] = 2;
  1366.         smallPrimes[1] = 3;
  1367.         smallPrimes[2] = 5;
  1368.         smallPrimes[3] = 7;
  1369.         smallPrimes[4] = 11;
  1370.         smallPrimes[5] = 13;
  1371.         smallPrimes[6] = 17;
  1372.         smallPrimes[7] = 19;
  1373.         smallPrimes[8] = 23;
  1374.         smallPrimes[9] = 29;
  1375.         smallPrimes[10] =31;
  1376.         smallPrimes[11] =37;
  1377.         smallPrimes[12] =41;
  1378.         smallPrimes[13] =43;
  1379.         smallPrimes[14] =47;
  1380.         smallPrimes[15] =53;
  1381.         smallPrimes[16] =59;
  1382.         smallPrimes[17] =61;
  1383.         smallPrimes[18] =67;
  1384.         smallPrimes[19] =71;
  1385.         smallPrimes[20] =73;
  1386.         smallPrimes[21] =79;
  1387.         smallPrimes[22] =83;
  1388.         smallPrimes[23] =89;
  1389.         smallPrimes[24] =97;
  1390.         smallPrimes[25] =101;
  1391.         smallPrimes[26] =103;
  1392.         smallPrimes[27] =107;
  1393.         smallPrimes[28] =109;
  1394.         smallPrimes[29] =113;
  1395.         smallPrimes[30] =127;
  1396.         smallPrimes[31] =131;
  1397.         smallPrimes[32] =137;
  1398.         smallPrimes[33] =139;
  1399.         smallPrimes[34] =149;
  1400.         smallPrimes[35] =151;
  1401.         smallPrimes[36] =157;
  1402.         smallPrimes[37] =163;
  1403.         smallPrimes[38] =167;
  1404.         smallPrimes[39] =173;
  1405.         smallPrimes[40] =179;
  1406.         smallPrimes[41] =181;
  1407.         smallPrimes[42] =191;
  1408.         smallPrimes[43] =193;
  1409.         smallPrimes[44] =197;
  1410.         smallPrimes[45] =199;
  1411.         smallPrimes[46] =211;
  1412.         smallPrimes[47] =223;
  1413.         smallPrimes[48] =227;
  1414.         smallPrimes[49] =229;
  1415.         smallPrimes[50] =233;
  1416.     }
  1417.  
  1418.     /**
  1419.      * This method tests for primality, first by attempting to divide
  1420.      * by a few small primes, then by using the Rabin probabilistic
  1421.      * primality test 50 times.  The probability of failing this test
  1422.      * is less than 1 / (4^n).
  1423.      *
  1424.      * @return a boolean, true if this Bignum is probably prime, false
  1425.      * otherwise.
  1426.      */
  1427.     public boolean isProbablePrime() {
  1428.     Bignum n1, n2;
  1429.        // test to see if this is divisible by a small prime.
  1430.        if((value[0] & 0x00000001) != 0x00000001) //make sure its odd
  1431.            return equals( TWO);
  1432.     for (int i = 1; i < 11 ; i++) {
  1433.         int prime = smallPrimes[i];
  1434.         if (quickMod(prime) == 0)
  1435.         if(value[0] != prime)
  1436.             return false;
  1437.     }
  1438.     // use a probabilistic test on this
  1439.     return isProbablePrime0(50);
  1440.     }
  1441.     private  int quickMod(int d) {
  1442.         int rem = 0;
  1443.         int i = value.length;
  1444.     while (i-- > 0) {
  1445.         long temp = (long) (((value[i]) <<32) | rem);
  1446.         rem = (int)(temp % d);
  1447.     }
  1448.     if(negative && rem !=0)
  1449.         rem = d - rem;
  1450.     return rem;
  1451.  
  1452.     }
  1453.  
  1454.     private boolean isProbablePrime0(int n) {
  1455.     Bignum wm1 = subtract(ONE);
  1456.     //calculate a = largest power of 2 that divides wm1
  1457.     int a = 0;
  1458.     int l = 0;
  1459.     for(int i = 0;i < wm1.value.length && wm1.value[i] == 0;l++,i++);
  1460.     int val = wm1.value[l];
  1461.     while((val & 1) ==0) {
  1462.             a++;
  1463.         val >>>= 1;
  1464.         }
  1465.     a = l * SRADIX + a;
  1466.     if(a == 0 ) //wm1 is odd so w must be even
  1467.         return false;
  1468.  
  1469.     int j;
  1470.     Bignum m = wm1.shiftRight(a);
  1471.  
  1472.     Bignum  z = new Bignum(3);
  1473.     //System.out.println(m.toString(16));
  1474.  
  1475.     z = z.modExp(m,this);
  1476.     //System.out.println(z.toString(16));
  1477.     if (z.equals(ONE) || z.equals(wm1))
  1478.         return true;
  1479.         for (j=1; j<a; j++)
  1480.         {
  1481.         z = z.multiply(z);
  1482.         z = z.remainder(this);
  1483.         if (z.equals(wm1))
  1484.             return true;
  1485.         if (z.equals(ONE))
  1486.             return false;
  1487.         }
  1488.  
  1489.     int s = wm1.significantBits();
  1490.  
  1491.     for(int i = 0; i < n; i++) {
  1492.             //System.out.println("Round: " + i);
  1493.         Bignum b = random(s,new Random());
  1494.         if(b.greaterThan(wm1))
  1495.         b = b.remainder(wm1);
  1496.         z = b.modExp(m, this);
  1497.         if(z.equals(ONE) || z.equals(wm1))
  1498.         continue;
  1499.         for(j=1;j<a;j++){
  1500.         z = z.modExp(TWO,this);
  1501.         if(z.equals(wm1))
  1502.             break;
  1503.         if(z.equals(ONE))
  1504.             return false;
  1505.         }
  1506.         if(j == a)
  1507.         return false;
  1508.  
  1509.     }
  1510.  
  1511.     return true;
  1512.     }
  1513.     //---------------------------Miscellaneous Operations------------------
  1514.     // public constants
  1515.     public final static  int   ROUND_STATISTICAL    = -1;
  1516.     public final static  int   NO_ROUNDING   = 9;
  1517.     public final static  int   ROUND_ABOVE_5 = 5 ;
  1518.     public final static  int   ROUND_ABOVE_4 = 4;
  1519.     public final static  int   ROUND_ALWAYS  = 0;
  1520.  
  1521.     //-----------------------------Implementation---------------------------
  1522.     /**
  1523.      * The maximum scale supported.
  1524.      *
  1525.      */
  1526.     private static final int MAXSCALE = 0x3fffffff;          //Maximum scale.
  1527.  
  1528.  
  1529.  
  1530.     private int value[];
  1531.     private int scale;
  1532.     private boolean negative;
  1533.     //----------------------------------------------------------------------
  1534.     /**
  1535.      * The roundingValue is a digit between -1 and 9 that determines
  1536.      * rounding behavior.
  1537.      */
  1538.     private static int roundingValue = 4;
  1539.  
  1540.     /**
  1541.      * To avoid problems with negative carries,etc, we user a base 2^30;
  1542.      */
  1543.     static final int SRADIX = 30;
  1544.     private static final int BASE = 1<<SRADIX;
  1545.  
  1546.     // Useful masks
  1547.     private static final long MASK = 0x3fffffffL;
  1548.  
  1549.     public static final Bignum ZERO = new Bignum("0,0");
  1550.     public static final Bignum ONE  = new Bignum(1,0);
  1551.     public static final Bignum TWO = new Bignum(2,0);
  1552.  
  1553.     //----------------------------------------------------------------------
  1554.  
  1555.     /**
  1556.      * Throws IllegalArgument exception is the scale is negative or
  1557.      * greater then MAXSCALE (0x3fffffffL).
  1558.      *
  1559.      */
  1560.     static private void verifyScale(int scale) {
  1561.  
  1562.        if (scale < 0) {
  1563.            throw new IllegalArgumentException("Scale is negative");
  1564.        }
  1565.        if (scale > MAXSCALE) {
  1566.            throw new IllegalArgumentException("Scale greater than maximum scale");
  1567.        }
  1568.     }
  1569.  
  1570.     /**
  1571.      * Compare the value of this Bignum to the value of the argument.
  1572.      * Returns 1 if this is greater than the argument,
  1573.      *        -1 if this is less than the argument,
  1574.      *         0 if this is equal to the argument.
  1575.      * @param  B  A Bignum to compare.
  1576.      * @return      1 if this > B,0 if this = B,-1 if this < B.
  1577.      */
  1578.     public int compare(Bignum B) {
  1579.     if (negative == false && B.negative == false) {
  1580.         return (compareAbs(B));
  1581.     }
  1582.     if (negative == true && B.negative == false) {
  1583.         return (-1);
  1584.     }
  1585.     if (negative == false && B.negative == true) {
  1586.         return (1);
  1587.     }
  1588.     int r = compareAbs(B);
  1589.     if (r != 0) {
  1590.         r *= -1;
  1591.     }
  1592.     return (r);
  1593.     }
  1594.  
  1595.     /**
  1596.      * Private function used for arithmetic comparisons.  Performs an
  1597.      * absolute comparison.
  1598.      *
  1599.      * @param  A A Bignum to compare.
  1600.      * @return 1 if this > A,0 if this = A,-1 if this < A.
  1601.      */
  1602.     private int compareAbs(Bignum A) {
  1603.     Bignum B;
  1604.     if(A.scale == scale)
  1605.         B = A;
  1606.     else
  1607.         B = new Bignum(A,scale);
  1608.  
  1609.     //look for the first significant digit
  1610.     int sigA,sigB;
  1611.     for (sigB = B.value.length  - 1;sigB > 0 && B.value[sigB] == 0 ; sigB-- );
  1612.     sigB++;
  1613.     for (sigA = value.length - 1 ;sigA > 0 && value[sigA] == 0 ; sigA--);
  1614.     sigA++;
  1615.     if (sigA > sigB)
  1616.         return (1);
  1617.     if (sigB > sigA)
  1618.         return (-1);
  1619.     if (sigA == 0 && sigB == 0)
  1620.         return (0);
  1621.     while (--sigA >= 0 )  {
  1622.         if (value[sigA] > B.value[sigA]) {
  1623.         return (1);
  1624.         }
  1625.         if (value[sigA] < B.value[sigA]) {
  1626.         return (-1);
  1627.         }
  1628.     }
  1629.     return (0);
  1630.     }
  1631.  
  1632.     /**
  1633.      * Private function used to initialize a Bignum using a string.
  1634.      * The radix is assumed to be 10
  1635.      * @param  s    A string containing the intended value of the Bignum.
  1636.      * @param  scale    The number of digits to the right of the decimal point.
  1637.      *                  Should be -1 if the scale is to be determined by the contents
  1638.      *                  of the argument string s.
  1639.      */
  1640.     private void init(String s, int iscale) {
  1641.     boolean scaleGiven = true;
  1642.     scale = 0;
  1643.     int mantVal = 0;
  1644.     if (iscale < 0) {
  1645.         scaleGiven = false;
  1646.     }
  1647.     int inScale = 0; //Scale computed from decimal point in s
  1648.  
  1649.  
  1650.     negative = false;         //Default to positive
  1651.     if (scaleGiven) {
  1652.         value = new int[(s.length() + iscale)/3 + 1];
  1653.     } else {
  1654.         value = new int[s.length()/5 + 1];
  1655.     }
  1656.     int[] t1 = new int[1];
  1657.     t1[0] = 10;
  1658.     //int [] t1;
  1659.     boolean mant = false;
  1660.     boolean gotFirstDigit = false;
  1661.     boolean gotFirstExpDigit = false;
  1662.  
  1663.     for (int i = 0;i < s.length() ;i++ ) {
  1664.         char c = s.charAt(i);
  1665.         if (c >= '0' && c <= '9') {
  1666.         if (inScale != 0) {
  1667.             if(!mant)
  1668.             inScale++;
  1669.         }
  1670.         int a = Character.digit(c,10);
  1671.         if(mant ) {
  1672.             mantVal = mantVal * 10 + a;
  1673.             gotFirstExpDigit = true;
  1674.         }
  1675.         else {
  1676.             t1 = mulAndAdd(value,10,a);
  1677.             if(t1 != null)
  1678.             value = t1;
  1679.             gotFirstDigit = true;
  1680.         }
  1681.         continue;
  1682.         }
  1683.         if (c == '-') {
  1684.         if(mant ){
  1685.             if(!gotFirstExpDigit)
  1686.                 mantVal = -mantVal;
  1687.         }
  1688.         else{
  1689.             if(!gotFirstDigit)
  1690.                 negative = true;
  1691.         }
  1692.         continue;
  1693.         }
  1694.         if (c == '.' && inScale == 0) {
  1695.         inScale = 1;
  1696.         }
  1697.         if (c== 'E' || c =='e')
  1698.         mant = true;
  1699.     }//for
  1700.     if(mant) {
  1701.         if(inScale != 0)
  1702.         scale = inScale - 1;
  1703.         else
  1704.         scale = 0;
  1705.         if(mantVal < 0) {
  1706.         mantVal *= -1;
  1707.         divide((new Bignum(10,0)).pow(mantVal));
  1708.         }
  1709.         else
  1710.         value = mul0(value,(new Bignum(10,0)).pow(mantVal).value);
  1711.         if(scaleGiven)
  1712.         _setScale(iscale);
  1713.         return;
  1714.  
  1715.     }
  1716.     if (inScale != 0) {
  1717.         //did we find a decimal point in the string
  1718.         inScale--;
  1719.         scale = inScale;
  1720.         //if so, use it
  1721.         if (scaleGiven) {
  1722.         if (scale != iscale)    {
  1723.             //the number of decimal places in string exceeds request
  1724.             _setScale(iscale);
  1725.         }
  1726.  
  1727.         }
  1728.     } else {
  1729.         // there was no decimal point in the string
  1730.         scale = 0;
  1731.         if (scaleGiven) {
  1732.         _setScale(iscale);
  1733.         }
  1734.     }
  1735.     }
  1736.  
  1737.     /**
  1738.      * Set the value of the Bignum to zeroes.  The precision and
  1739.      * scale are retained.
  1740.      */
  1741.     private void zero() {
  1742.         negative = false;
  1743.         for (int i = 0; i < value.length; i++) {
  1744.             value[i] = 0;
  1745.         }
  1746.     }
  1747.  
  1748.     /**
  1749.      * Remove leading zeroes from the value of the Bignum. Zeroes to
  1750.      * the right of the decimal point are retained.
  1751.      *
  1752.      * <P>The precision is changed accordingly. One zero is retained
  1753.      * if all digits are zero and the scale is zero.
  1754.      */
  1755.     private void dropLeadingZeroes() {
  1756.     int i;
  1757.     for(i = value.length -1;i >= 0 && value[i] == 0;i--);
  1758.     if(i < 0) i = 0;
  1759.     if(++i >= value.length ) return;
  1760.     int[] nval = new int[i];
  1761.     System.arraycopy(value,0,nval,0,i);
  1762.     value = nval;
  1763.     }
  1764.     /**
  1765.      *Returns a new Bignum whose value equals the
  1766.      *integer part of the input argument. The fractional part, if any,
  1767.      *is dropped.
  1768.      *@param Bignum The input value to truncate
  1769.      *@returns A new Bignum equal to the integer value of the argument
  1770.      */
  1771.     public static Bignum truncate(Bignum in) {
  1772.     if(in.scale == 0)
  1773.         return new Bignum(in);
  1774.         int scaleFactor = in.scale  - 1;
  1775.         int[] tval = new int[1];
  1776.         tval[0] = 0;
  1777.  
  1778.     int m1 = 9; //
  1779.     int m4 = 1000000000;
  1780.     int x = scaleFactor;
  1781.     for(;x >= m1;x -= m1 )
  1782.         tval = mul0(tval,m4);
  1783.     if(x > 0 )
  1784.         tval = mul0(tval,pow(10,x));
  1785.     tval = add0(in.value,tval);
  1786.     x = scaleFactor + 1;
  1787.     for(;x >= m1;x -= m1)
  1788.         div0(tval,tval,m4);
  1789.  
  1790.     if(x > 0)
  1791.         div0(tval,tval,pow(10,x));
  1792.     Bignum out = new Bignum(tval);
  1793.     out.scale = 0;
  1794.     out.negative = in.negative;
  1795.     return out;
  1796.  
  1797.     }
  1798.  
  1799.     /**
  1800.      * Set the number of the digits to the right of the decimal point.
  1801.      * The precision and value of the Bignum will be adjusted
  1802.      * accordingly.  Note that changing the scale to a smaller value
  1803.      * may result in rounding the value.
  1804.      *
  1805.      * @param  scale the character to be converted
  1806.      * @see Bignum#setRoundingOption
  1807.      */
  1808.     private void _setScale(int iscale) {
  1809.         verifyScale(iscale);
  1810.         if (iscale == scale) {
  1811.             return;
  1812.         }
  1813.         if(iscale > scale){
  1814.         for(int i = iscale - scale;i > 0;--i)
  1815.         value = mul0(value,10);
  1816.             scale = iscale;
  1817.             return;
  1818.         }
  1819.         int tempRoundingValue = roundingValue;
  1820.         //to round to the nearest even, first truncate.
  1821.         //Later, check to see if it the result of the truncation
  1822.         //is odd. If it is add 1;
  1823.         if(roundingValue == ROUND_STATISTICAL)
  1824.             tempRoundingValue = 9;
  1825.         //iscale < scale
  1826.         int scaleFactor = (scale - iscale) - 1;
  1827.         int[] tval = new int[1];
  1828.         tval[0] = 9 - tempRoundingValue;
  1829.  
  1830.     int m1 = 9; //this is approx log10 of BASE
  1831.     int m4 = 1000000000;
  1832.     int x = scaleFactor;
  1833.     for(;x >= m1;x -= m1 )
  1834.         tval = mul0(tval,m4);
  1835.     if(x > 0 )
  1836.         tval = mul0(tval,pow(10,x));
  1837.     value = add0(value,tval);
  1838.     x = scaleFactor + 1;
  1839.     for(;x >= m1;x -= m1)
  1840.         div0(value,value,m4);
  1841.  
  1842.     if(x > 0)
  1843.         div0(value,value,pow(10,x));
  1844.     if(roundingValue == ROUND_STATISTICAL) {
  1845.         //Check for an odd result
  1846.         if((value[0] & 0x00000001) == 0x00000001)
  1847.             value[0] += 1; //and add 1 it was odd
  1848.  
  1849.     }
  1850.     scale = iscale;
  1851.     }
  1852.     //---------------------------------------------------------------------
  1853.     /**
  1854.      * Algorithmic multiplication of two positive integers represented as
  1855.      * 32-bit integers. Knuth Algorithm M.
  1856.      *
  1857.      * u is required to be longer or equal to v.
  1858.      *
  1859.      */
  1860.     private static int[] mul0(int[] u, int[] v) {
  1861.     int n = u.length - 1;
  1862.     int m = v.length - 1;
  1863.     long k = 0;
  1864.  
  1865.     int[] w = new int[u.length + v.length];
  1866.     for (int j = 0; j <= n; j++) {
  1867.         k = 0;
  1868.         int q = j;
  1869.         for (int i = 0; i <= m; i++) {
  1870.             //
  1871.             long uv = u[j];
  1872.             long t = uv * v[i] + w[q] + k;
  1873.             w[(q++)] = (int)(t & MASK);
  1874.             k = t >> SRADIX;
  1875.         }
  1876.         for(;k != 0;) {
  1877.             long uv = w[q] + k ;
  1878.             w[q++] = (int) (uv & MASK);
  1879.             k = uv >> SRADIX;
  1880.         }
  1881.         //
  1882.  
  1883.     }
  1884.     if(w[w.length -1] != 0)
  1885.         return w;
  1886.  
  1887.     int ul = w.length - 1;
  1888.     for(;ul > 0 && w[ul] == 0;ul--);
  1889.     ul++;
  1890.     int[] w1 = new int[ul];
  1891.     System.arraycopy(w,0,w1,0,w1.length);
  1892.         return w1;
  1893.     }
  1894.  
  1895.     private static int[] mul0(int[] u, int v) {
  1896.     int n = u.length - 1;
  1897.     long k = 0;
  1898.     long x = v & MASK;
  1899.     int[] w = new int[u.length];
  1900.     if (x != 0) {
  1901.         for (int i = 0; i <= n; i++) {
  1902.             long uv = (u[i] & MASK) * x + k;
  1903.             w[i] = (int)(uv & MASK);
  1904.             k = uv >> SRADIX;
  1905.         }
  1906.         if(k != 0){
  1907.             int[] ww = new int[w.length + 1];
  1908.             System.arraycopy(w,0,ww,0,w.length);
  1909.             ww[ww.length - 1] = (int) k;
  1910.             w = ww;
  1911.         }
  1912.     }
  1913.     return w;
  1914.     }
  1915.  
  1916.  
  1917.     //------------------------------------------------------------------------
  1918.     /**
  1919.      *  Quick add of two Bignum array values
  1920.      *
  1921.      */
  1922.     private static int[] add0(int[] u, int[] v) {
  1923.  
  1924.     int j=0;
  1925.     int ul = u.length - 1;
  1926.     for(;ul > 0 && u[ul] == 0;ul--);
  1927.  
  1928.     int vl = v.length - 1;
  1929.     for(;vl > 0 && v[vl] == 0;vl--);
  1930.  
  1931.     ul++;vl++;
  1932.  
  1933.     if(ul < vl){
  1934.         int[] temp = u;
  1935.         u = v;
  1936.         v = temp;
  1937.         int temp2 = ul;
  1938.         ul = vl;
  1939.         vl = temp2;
  1940.     }
  1941.     int[] w = new int[ul + 1];
  1942.  
  1943.     long carry = 0;
  1944.     long temp;
  1945.  
  1946.     for (j = 0; j < vl ; ++j) {
  1947.         temp = u[j] + v[j] + carry;
  1948.         carry = temp >> SRADIX;
  1949.         w[j] = (int) (temp & MASK);
  1950.     }
  1951.     for (; carry != 0 && j < ul; ++j) {
  1952.         temp = u[j] + carry;
  1953.         w[j] =  (int)(temp & MASK);
  1954.         carry = temp >> SRADIX;
  1955.     }
  1956.     if(carry == 0 && j < ul) {
  1957.         for(;j < ul;++j) w[j] = u[j];
  1958.     }
  1959.     else{
  1960.         w[j] = (int) (carry & MASK);
  1961.     }
  1962.     return w;
  1963.     }
  1964.     //-------------------------------------------------------------------
  1965.     /**
  1966.      * Internal routine to quickly add an integer value to a Bignum value.
  1967.      *
  1968.      */
  1969.     private static int[] add0(int[] u, int v) {
  1970.     int j=0;
  1971.     int ul = u.length - 1;
  1972.     for(;ul > 0 && u[ul] == 0;ul--);
  1973.  
  1974.     int[] w = new int[ul++ + 1];
  1975.     long carry = 0;
  1976.  
  1977.     long temp = ((long)u[j] & MASK) + ((long)v & MASK);
  1978.     carry = temp >> SRADIX;
  1979.     w[j] = (int)(temp & MASK);
  1980.     for (++j; carry != 0 && j < ul; ++j) {
  1981.         temp = u[j] + carry;
  1982.         w[j] = (int)  (temp & MASK);
  1983.         carry = temp >> SRADIX;
  1984.     }
  1985.     if(carry == 0 && j < ul) {
  1986.         for(;j < ul;++j) {w[j] = u[j];}
  1987.     }
  1988.     return w;
  1989.     }
  1990.     //---------------------------------------------------------------------
  1991.     /*
  1992.      * Subtraction of two positive integers represented as 32-bit
  1993.      * integers. See Knuth Algorithm S.
  1994.      *
  1995.      * This operation is not commutative, and u must be longer or equal
  1996.      * in length to v.
  1997.      *
  1998.      * See add0 for details on representation and implementation.
  1999.      */
  2000.     private static int[] sub0(int[] u, int[] v) {
  2001.  
  2002.     boolean borrow = false;
  2003.  
  2004.     int ul = u.length - 1;
  2005.     for(;ul > 0 && u[ul] == 0;ul--);
  2006.  
  2007.     int vl = v.length - 1;
  2008.     for(;vl > 0 && v[vl] == 0;vl--);
  2009.  
  2010.     int[] w = new int[ul + 1];
  2011.     int wj;
  2012.     int j = 0;
  2013.     for (; j <= vl;) {
  2014.         wj = u[j] - v[j] + (borrow?-1:0);
  2015.         w[j++] = (int)(wj & MASK);
  2016.         borrow = wj < 0;
  2017.     }
  2018.     if(borrow)
  2019.         {
  2020.             for (; j <=  ul; ) {
  2021.                 w[j] = (u[j] - (borrow?1:0));
  2022.                 if(w[j++] >= 0) break;
  2023.             }
  2024.         }
  2025.     for(;j <= ul;j++)
  2026.         w[j] = u[j];
  2027.     return w;
  2028.     }
  2029.  
  2030.     //-----------------------------------------------------------------
  2031.     private static int div0(int[] quotient,int[] dividend,int divisor){
  2032.     long carry = 0;
  2033.     for(int i = dividend.length - 1;i >= 0;--i){
  2034.         long x = (dividend[i] & MASK) + (carry << SRADIX);
  2035.         quotient[i] = (int) (x/((long)divisor & MASK));
  2036.         carry = x % (long)divisor;
  2037.     }
  2038.     return (int)carry;
  2039.     }
  2040.  
  2041.  
  2042.     private static void div(Bignum dvdnd, Bignum div, Bignum quot) {
  2043.        int divlen = div.value.length - 1;
  2044.  
  2045.        int d1 = div.value[divlen];    //divisor must be at least 2 digits
  2046.        int d2 = div.value[divlen - 1];
  2047.        int[] dndVal = dvdnd.value;
  2048.        int[] divVal = div.value;
  2049.        int qx = quot.value.length - 1;
  2050.        long q;
  2051.        for (int j = dvdnd.value.length - 1; j>divlen; j--) {
  2052.            int dd0  = dndVal[j];
  2053.            int dd1 = dndVal[j-1];
  2054.            int dd2 = dndVal[j-2];
  2055.         long temp1 = (((long)dd0)<<SRADIX) + (long)dd1;
  2056.            if (dd0 == d1) {
  2057.            q = (BASE)-1;
  2058.            } else {
  2059.            q = temp1 / (long) d1;
  2060.            }
  2061.            for (;;) {
  2062.            long  p1 = d2 * q;
  2063.         long  p2 = temp1 - (d1 * q);
  2064.         p2= (p2<<SRADIX) + dd2;
  2065.         if(p1 > p2)
  2066.                q--;
  2067.         else
  2068.                break;
  2069.            }
  2070.         if(q == 0){
  2071.                    quot.value[qx--] = 0;
  2072.         continue;
  2073.         }
  2074.            int k = j-divlen-1;
  2075.            long carry = 0;
  2076.            for (int dk = 0; dk <= divlen; dk++) {
  2077.            long x1 = divVal[dk] * q + carry;
  2078.            int x2 = dndVal[k] - (int)(x1 & MASK);
  2079.            if (x2<0) {
  2080.                dndVal[k++] = x2 + (BASE);
  2081.                carry = (x1>>SRADIX) + 1;
  2082.            } else {
  2083.                dndVal[k++] = x2;
  2084.                carry = (x1>>SRADIX);
  2085.            }//elseif
  2086.            }//for
  2087.            if (carry != 0){
  2088.            int temp = dndVal[k] - (int)carry;
  2089.            if(temp >= 0)
  2090.                dndVal[k] = temp;
  2091.            else{
  2092.                dndVal[k] = temp + (BASE);
  2093.                //the guess was too big! back it off by 1
  2094.                carry = 0;
  2095.                k = j - divlen -1;
  2096.             q--;
  2097.                for (int dk = 0; dk <= divlen; dk++) {
  2098.                long nv = divVal[dk] + dndVal[k] + carry;
  2099.                dndVal[k++] = (int)(nv & MASK);
  2100.                carry = nv>>SRADIX;
  2101.                }//for
  2102.                if (carry == 1)
  2103.                dndVal[k] =(int) ((dndVal[k]+1) & MASK);
  2104.            }//else
  2105.            }//if
  2106.            quot.value[qx--] = (int)q;
  2107.  
  2108.     }//for
  2109.  
  2110.     }
  2111.     /**
  2112.      * Private power integer function used in division
  2113.      * and scaling.
  2114.      * @arg b the integer base value.
  2115.      * @arg e the exponent to be used
  2116.      *@return an integer value calculated as b^e;
  2117.      */
  2118.     private static int pow(int b,int e){
  2119.     if(e == 0) return 1;
  2120.     if(e == 1) return b;
  2121.     int ans = b;
  2122.     int temp = 1;
  2123.     while(e != 1){
  2124.         if((e & 0x0001)==0x0001)
  2125.                temp *= ans;
  2126.         ans *= ans;
  2127.         e >>=1;
  2128.     }
  2129.     return ans * temp;
  2130.     }
  2131.     /**
  2132.      *Private routine that multiplies the val by integer m
  2133.      * and adds the integer a.
  2134.      *@Returns a new array, if a new one had to be allocated,
  2135.      *otherwise, returns null;
  2136.      */
  2137.     private static int[] mulAndAdd(int val[],int m, int a){
  2138.     int n = val.length - 1;
  2139.     long k = a & MASK;
  2140.     long x = m & MASK;
  2141.     int[] w = val;
  2142.     if (x!= 0) {
  2143.         for (int i = 0; i <= n; i++) {
  2144.             long uv = (val[i] & MASK) * x + k;
  2145.             w[i] = (int)(uv & MASK);
  2146.             k = uv >> SRADIX;
  2147.         }
  2148.         if(k != 0){
  2149.             int[] ww = new int[w.length + 1];
  2150.             System.arraycopy(w,0,ww,0,w.length);
  2151.             ww[ww.length - 1] = (int) (k & MASK);
  2152.             w = ww;
  2153.         }
  2154.     }
  2155.     return w==val?null:w;
  2156.     }
  2157.  
  2158.     /**
  2159.      * Private constructor that creates a Bignum from an
  2160.      * array of integers. This is used internally to optimize
  2161.      * certain operations.
  2162.      * @param valueArray an array of integers that are presumed to hold the
  2163.      * value of the new Bignum.
  2164.      */
  2165.     private Bignum(int[] valueArray){
  2166.     value = valueArray;
  2167.     negative = false;
  2168.     }
  2169.  
  2170.  
  2171.     //---------------------------------------------------------------------
  2172.     /**
  2173.      * Algorithmic multiplication of two positive integers represented as
  2174.      * 32-bit integers. Knuth Algorithm M.
  2175.      *
  2176.      * u is required to be longer or equal to v.
  2177.      *
  2178.      */
  2179.     private static int[] mul0(int[] u, int[] v, int[] x) {
  2180.     int[] w = x;
  2181.        int n = u.length - 1;
  2182.        while(u[n] == 0) n--;
  2183.        int m = v.length - 1;
  2184.        while(v[m] == 0) m--;
  2185.        if(m < 0 || n < 0) {
  2186.            if(w == null) w = new int[1];
  2187.            w[0] = 0;
  2188.            return w;
  2189.        }
  2190.        long k = 0,uv,t;
  2191.        int q =0, maxpos = 0;
  2192.     if (w == null || w.length < (n + m + 3))
  2193.            w = new int[n + m + 3];
  2194.        for (int j = 0; j <= n; j++) {
  2195.            k = 0;
  2196.            q = j;
  2197.            for (int i = 0; i <= m; i++) {
  2198.            //
  2199.            uv = u[j];
  2200.            t = uv * v[i] + w[q] + k;
  2201.            w[(q++)] = (int)(t & MASK);
  2202.            k = t >> SRADIX;
  2203.            }
  2204.            for(;k != 0;) {
  2205.            uv = w[q] + k ;
  2206.            w[q++] = (int) (uv & MASK);
  2207.            k = uv >> SRADIX;
  2208.            }
  2209.            if(q > maxpos)
  2210.                maxpos = q;
  2211.            //
  2212.  
  2213.        }
  2214.     return w;
  2215.  
  2216.     }
  2217.  
  2218.  
  2219. }//Bignum
  2220.  
  2221.  
  2222.