@@ -351,12 +351,18 @@ public BigInteger(byte[] val, int off, int len) {
351351 throw new NumberFormatException ("Zero length BigInteger" );
352352 }
353353 Objects .checkFromIndexSize (off , len , val .length );
354+ if (len == 0 ) {
355+ mag = ZERO .mag ;
356+ signum = ZERO .signum ;
357+ return ;
358+ }
354359
355- if (val [off ] < 0 ) {
356- mag = makePositive (val , off , len );
360+ int b = val [off ];
361+ if (b < 0 ) {
362+ mag = makePositive (b , val , off , len );
357363 signum = -1 ;
358364 } else {
359- mag = stripLeadingZeroBytes (val , off , len );
365+ mag = stripLeadingZeroBytes (b , val , off , len );
360366 signum = (mag .length == 0 ? 0 : 1 );
361367 }
362368 if (mag .length >= MAX_MAG_LENGTH ) {
@@ -4604,77 +4610,167 @@ private static int[] trustedStripLeadingZeroInts(int[] val) {
46044610 return keep == 0 ? val : java .util .Arrays .copyOfRange (val , keep , vlen );
46054611 }
46064612
4607- /**
4613+ private static int [] stripLeadingZeroBytes (byte [] a , int from , int len ) {
4614+ return stripLeadingZeroBytes (Integer .MIN_VALUE , a , from , len );
4615+ }
4616+
4617+ /*
46084618 * Returns a copy of the input array stripped of any leading zero bytes.
4619+ * The returned array is either empty, or its 0-th element is non-zero,
4620+ * meeting the "minimal" requirement for field mag (see comment on mag).
4621+ *
4622+ * The range [from, from + len) must be well-formed w.r.t. array a.
4623+ *
4624+ * b < -128 means that a[from] has not yet been read.
4625+ * Otherwise, b must be a[from], have been read only once before invoking
4626+ * this method, and len > 0 must hold.
46094627 */
4610- private static int [] stripLeadingZeroBytes (byte [] a , int off , int len ) {
4611- int indexBound = off + len ;
4612- int keep ;
4613-
4614- // Find first nonzero byte
4615- for (keep = off ; keep < indexBound && a [keep ] == 0 ; keep ++)
4616- ;
4617-
4618- // Allocate new array and copy relevant part of input array
4619- int intLength = ((indexBound - keep ) + 3 ) >>> 2 ;
4620- int [] result = new int [intLength ];
4621- int b = indexBound - 1 ;
4622- for (int i = intLength -1 ; i >= 0 ; i --) {
4623- result [i ] = a [b --] & 0xff ;
4624- int bytesRemaining = b - keep + 1 ;
4625- int bytesToTransfer = Math .min (3 , bytesRemaining );
4626- for (int j =8 ; j <= (bytesToTransfer << 3 ); j += 8 )
4627- result [i ] |= ((a [b --] & 0xff ) << j );
4628+ private static int [] stripLeadingZeroBytes (int b , byte [] a , int from , int len ) {
4629+ /*
4630+ * Except for the first byte, each read access to the input array a
4631+ * is of the form a[from++].
4632+ * The index from is never otherwise altered, except right below,
4633+ * and only increases in steps of 1, always up to index to.
4634+ * Hence, each byte in the array is read exactly once, from lower to
4635+ * higher indices (from most to least significant byte).
4636+ */
4637+ if (len == 0 ) {
4638+ return ZERO .mag ;
46284639 }
4629- return result ;
4640+ int to = from + len ;
4641+ if (b < -128 ) {
4642+ b = a [from ];
4643+ }
4644+ /* Either way, a[from] has now been read exactly once, skip to next. */
4645+ ++from ;
4646+ /*
4647+ * Set up the shortest int[] for the sequence of the bytes
4648+ * b, a[from+1], ..., a[to-1] (len > 0)
4649+ * Shortest means first skipping leading zeros.
4650+ */
4651+ for (; b == 0 && from < to ; b = a [from ++])
4652+ ; //empty body
4653+ if (b == 0 ) {
4654+ /* Here, from == to as well. All bytes are zeros. */
4655+ return ZERO .mag ;
4656+ }
4657+ /*
4658+ * Allocate just enough ints to hold (to - from + 1) bytes, that is
4659+ * ((to - from + 1) + 3) / 4 = (to - from) / 4 + 1
4660+ */
4661+ int [] res = new int [((to - from ) >> 2 ) + 1 ];
4662+ /*
4663+ * A "digit" is a group of 4 adjacent bytes aligned w.r.t. index to.
4664+ * (Implied 0 bytes are prepended as needed.)
4665+ * b is the most significant byte not 0.
4666+ * Digit d0 spans the range of indices that includes current (from - 1).
4667+ */
4668+ int d0 = b & 0xFF ;
4669+ while (((to - from ) & 0x3 ) != 0 ) {
4670+ d0 = d0 << 8 | a [from ++] & 0xFF ;
4671+ }
4672+ res [0 ] = d0 ;
4673+ /*
4674+ * Prepare the remaining digits.
4675+ * (to - from) is a multiple of 4, so prepare an int for every 4 bytes.
4676+ * This is a candidate for Unsafe.copy[Swap]Memory().
4677+ */
4678+ int i = 1 ;
4679+ while (from < to ) {
4680+ res [i ++] = a [from ++] << 24 | (a [from ++] & 0xFF ) << 16
4681+ | (a [from ++] & 0xFF ) << 8 | (a [from ++] & 0xFF );
4682+ }
4683+ return res ;
46304684 }
46314685
4632- /**
4686+ /*
46334687 * Takes an array a representing a negative 2's-complement number and
46344688 * returns the minimal (no leading zero bytes) unsigned whose value is -a.
4689+ *
4690+ * len > 0 must hold.
4691+ * The range [from, from + len) must be well-formed w.r.t. array a.
4692+ * b is assumed to be the result of reading a[from] and to meet b < 0.
46354693 */
4636- private static int [] makePositive (byte [] a , int off , int len ) {
4637- int keep , k ;
4638- int indexBound = off + len ;
4639-
4640- // Find first non-sign (0xff) byte of input
4641- for (keep =off ; keep < indexBound && a [keep ] == -1 ; keep ++)
4642- ;
4643-
4644-
4645- /* Allocate output array. If all non-sign bytes are 0x00, we must
4646- * allocate space for one extra output byte. */
4647- for (k =keep ; k < indexBound && a [k ] == 0 ; k ++)
4648- ;
4649-
4650- int extraByte = (k == indexBound ) ? 1 : 0 ;
4651- int intLength = ((indexBound - keep + extraByte ) + 3 ) >>> 2 ;
4652- int result [] = new int [intLength ];
4653-
4654- /* Copy one's complement of input into output, leaving extra
4655- * byte (if it exists) == 0x00 */
4656- int b = indexBound - 1 ;
4657- for (int i = intLength -1 ; i >= 0 ; i --) {
4658- result [i ] = a [b --] & 0xff ;
4659- int numBytesToTransfer = Math .min (3 , b -keep +1 );
4660- if (numBytesToTransfer < 0 )
4661- numBytesToTransfer = 0 ;
4662- for (int j =8 ; j <= 8 *numBytesToTransfer ; j += 8 )
4663- result [i ] |= ((a [b --] & 0xff ) << j );
4664-
4665- // Mask indicates which bits must be complemented
4666- int mask = -1 >>> (8 *(3 -numBytesToTransfer ));
4667- result [i ] = ~result [i ] & mask ;
4694+ private static int [] makePositive (int b , byte [] a , int from , int len ) {
4695+ /*
4696+ * By assumption, b == a[from] < 0 and len > 0.
4697+ *
4698+ * First collect the bytes into the resulting array res.
4699+ * Then convert res to two's complement.
4700+ *
4701+ * Except for b == a[from], each read access to the input array a
4702+ * is of the form a[from++].
4703+ * The index from is never otherwise altered, except right below,
4704+ * and only increases in steps of 1, always up to index to.
4705+ * Hence, each byte in the array is read exactly once, from lower to
4706+ * higher indices (from most to least significant byte).
4707+ */
4708+ int to = from + len ;
4709+ /* b == a[from] has been read exactly once, skip to next index. */
4710+ ++from ;
4711+ /* Skip leading -1 bytes. */
4712+ for (; b == -1 && from < to ; b = a [from ++])
4713+ ; //empty body
4714+ /*
4715+ * A "digit" is a group of 4 adjacent bytes aligned w.r.t. index to.
4716+ * b is the most significant byte not -1, or -1 only if from == to.
4717+ * Digit d0 spans the range of indices that includes current (from - 1).
4718+ * (Implied -1 bytes are prepended to array a as needed.)
4719+ * It usually corresponds to res[0], except for the special case below.
4720+ */
4721+ int d0 = -1 << 8 | b & 0xFF ;
4722+ while (((to - from ) & 0x3 ) != 0 ) {
4723+ d0 = d0 << 8 | (b = a [from ++]) & 0xFF ;
4724+ }
4725+ int f = from ; // keeps the current from for sizing purposes later
4726+ /* Skip zeros adjacent to d0, if at all. */
4727+ for (; b == 0 && from < to ; b = a [from ++])
4728+ ; //empty body
4729+ /*
4730+ * b is the most significant non-zero byte at or after (f - 1),
4731+ * or 0 only if from == to.
4732+ * Digit d spans the range of indices that includes (f - 1).
4733+ */
4734+ int d = b & 0xFF ;
4735+ while (((to - from ) & 0x3 ) != 0 ) {
4736+ d = d << 8 | a [from ++] & 0xFF ;
46684737 }
4669-
4670- // Add one to one's complement to generate two's complement
4671- for (int i =result .length -1 ; i >= 0 ; i --) {
4672- result [i ] = (int )((result [i ] & LONG_MASK ) + 1 );
4673- if (result [i ] != 0 )
4674- break ;
4738+ /*
4739+ * If the situation here is like this:
4740+ * index: f to == from
4741+ * ..., -1,-1, 0,0,0,0, 0,0,0,0, ..., 0,0,0,0
4742+ * digit: d0 d
4743+ * then, as shown, the number of zeros is a positive multiple of 4.
4744+ * The array res needs a minimal length of (1 + 1 + (to - f) / 4)
4745+ * to accommodate the two's complement, including a leading 1.
4746+ * In any other case, there is at least one byte that is non-zero.
4747+ * The array for the two's complement has length (0 + 1 + (to - f) / 4).
4748+ * c is 1, resp., 0 for the two situations.
4749+ */
4750+ int c = (to - from | d0 | d ) == 0 ? 1 : 0 ;
4751+ int [] res = new int [c + 1 + ((to - f ) >> 2 )];
4752+ res [0 ] = c == 0 ? d0 : -1 ;
4753+ int i = res .length - ((to - from ) >> 2 );
4754+ if (i > 1 ) {
4755+ res [i - 1 ] = d ;
46754756 }
4676-
4677- return result ;
4757+ /*
4758+ * Prepare the remaining digits.
4759+ * (to - from) is a multiple of 4, so prepare an int for every 4 bytes.
4760+ * This is a candidate for Unsafe.copy[Swap]Memory().
4761+ */
4762+ while (from < to ) {
4763+ res [i ++] = a [from ++] << 24 | (a [from ++] & 0xFF ) << 16
4764+ | (a [from ++] & 0xFF ) << 8 | (a [from ++] & 0xFF );
4765+ }
4766+ /* Convert to two's complement. Here, i == res.length */
4767+ while (--i >= 0 && res [i ] == 0 )
4768+ ; // empty body
4769+ res [i ] = -res [i ];
4770+ while (--i >= 0 ) {
4771+ res [i ] = ~res [i ];
4772+ }
4773+ return res ;
46784774 }
46794775
46804776 /**
0 commit comments