@@ -315,12 +315,18 @@ public BigInteger(byte[] val, int off, int len) {
315315 throw new NumberFormatException ("Zero length BigInteger" );
316316 }
317317 Objects .checkFromIndexSize (off , len , val .length );
318+ if (len == 0 ) {
319+ mag = ZERO .mag ;
320+ signum = ZERO .signum ;
321+ return ;
322+ }
318323
319- if (val [off ] < 0 ) {
320- mag = makePositive (val , off , len );
324+ int b = val [off ];
325+ if (b < 0 ) {
326+ mag = makePositive (b , val , off , len );
321327 signum = -1 ;
322328 } else {
323- mag = stripLeadingZeroBytes (val , off , len );
329+ mag = stripLeadingZeroBytes (b , val , off , len );
324330 signum = (mag .length == 0 ? 0 : 1 );
325331 }
326332 if (mag .length >= MAX_MAG_LENGTH ) {
@@ -4568,77 +4574,167 @@ private static int[] trustedStripLeadingZeroInts(int[] val) {
45684574 return keep == 0 ? val : java .util .Arrays .copyOfRange (val , keep , vlen );
45694575 }
45704576
4571- /**
4577+ private static int [] stripLeadingZeroBytes (byte [] a , int from , int len ) {
4578+ return stripLeadingZeroBytes (Integer .MIN_VALUE , a , from , len );
4579+ }
4580+
4581+ /*
45724582 * Returns a copy of the input array stripped of any leading zero bytes.
4583+ * The returned array is either empty, or its 0-th element is non-zero,
4584+ * meeting the "minimal" requirement for field mag (see comment on mag).
4585+ *
4586+ * The range [from, from + len) must be well-formed w.r.t. array a.
4587+ *
4588+ * b < -128 means that a[from] has not yet been read.
4589+ * Otherwise, b must be a[from], have been read only once before invoking
4590+ * this method, and len > 0 must hold.
45734591 */
4574- private static int [] stripLeadingZeroBytes (byte [] a , int off , int len ) {
4575- int indexBound = off + len ;
4576- int keep ;
4577-
4578- // Find first nonzero byte
4579- for (keep = off ; keep < indexBound && a [keep ] == 0 ; keep ++)
4580- ;
4581-
4582- // Allocate new array and copy relevant part of input array
4583- int intLength = ((indexBound - keep ) + 3 ) >>> 2 ;
4584- int [] result = new int [intLength ];
4585- int b = indexBound - 1 ;
4586- for (int i = intLength -1 ; i >= 0 ; i --) {
4587- result [i ] = a [b --] & 0xff ;
4588- int bytesRemaining = b - keep + 1 ;
4589- int bytesToTransfer = Math .min (3 , bytesRemaining );
4590- for (int j =8 ; j <= (bytesToTransfer << 3 ); j += 8 )
4591- result [i ] |= ((a [b --] & 0xff ) << j );
4592+ private static int [] stripLeadingZeroBytes (int b , byte [] a , int from , int len ) {
4593+ /*
4594+ * Except for the first byte, each read access to the input array a
4595+ * is of the form a[from++].
4596+ * The index from is never otherwise altered, except right below,
4597+ * and only increases in steps of 1, always up to index to.
4598+ * Hence, each byte in the array is read exactly once, from lower to
4599+ * higher indices (from most to least significant byte).
4600+ */
4601+ if (len == 0 ) {
4602+ return ZERO .mag ;
45924603 }
4593- return result ;
4604+ int to = from + len ;
4605+ if (b < -128 ) {
4606+ b = a [from ];
4607+ }
4608+ /* Either way, a[from] has now been read exactly once, skip to next. */
4609+ ++from ;
4610+ /*
4611+ * Set up the shortest int[] for the sequence of the bytes
4612+ * b, a[from+1], ..., a[to-1] (len > 0)
4613+ * Shortest means first skipping leading zeros.
4614+ */
4615+ for (; b == 0 && from < to ; b = a [from ++])
4616+ ; //empty body
4617+ if (b == 0 ) {
4618+ /* Here, from == to as well. All bytes are zeros. */
4619+ return ZERO .mag ;
4620+ }
4621+ /*
4622+ * Allocate just enough ints to hold (to - from + 1) bytes, that is
4623+ * ((to - from + 1) + 3) / 4 = (to - from) / 4 + 1
4624+ */
4625+ int [] res = new int [((to - from ) >> 2 ) + 1 ];
4626+ /*
4627+ * A "digit" is a group of 4 adjacent bytes aligned w.r.t. index to.
4628+ * (Implied 0 bytes are prepended as needed.)
4629+ * b is the most significant byte not 0.
4630+ * Digit d0 spans the range of indices that includes current (from - 1).
4631+ */
4632+ int d0 = b & 0xFF ;
4633+ while (((to - from ) & 0x3 ) != 0 ) {
4634+ d0 = d0 << 8 | a [from ++] & 0xFF ;
4635+ }
4636+ res [0 ] = d0 ;
4637+ /*
4638+ * Prepare the remaining digits.
4639+ * (to - from) is a multiple of 4, so prepare an int for every 4 bytes.
4640+ * This is a candidate for Unsafe.copy[Swap]Memory().
4641+ */
4642+ int i = 1 ;
4643+ while (from < to ) {
4644+ res [i ++] = a [from ++] << 24 | (a [from ++] & 0xFF ) << 16
4645+ | (a [from ++] & 0xFF ) << 8 | (a [from ++] & 0xFF );
4646+ }
4647+ return res ;
45944648 }
45954649
4596- /**
4650+ /*
45974651 * Takes an array a representing a negative 2's-complement number and
45984652 * returns the minimal (no leading zero bytes) unsigned whose value is -a.
4653+ *
4654+ * len > 0 must hold.
4655+ * The range [from, from + len) must be well-formed w.r.t. array a.
4656+ * b is assumed to be the result of reading a[from] and to meet b < 0.
45994657 */
4600- private static int [] makePositive (byte [] a , int off , int len ) {
4601- int keep , k ;
4602- int indexBound = off + len ;
4603-
4604- // Find first non-sign (0xff) byte of input
4605- for (keep =off ; keep < indexBound && a [keep ] == -1 ; keep ++)
4606- ;
4607-
4608-
4609- /* Allocate output array. If all non-sign bytes are 0x00, we must
4610- * allocate space for one extra output byte. */
4611- for (k =keep ; k < indexBound && a [k ] == 0 ; k ++)
4612- ;
4613-
4614- int extraByte = (k == indexBound ) ? 1 : 0 ;
4615- int intLength = ((indexBound - keep + extraByte ) + 3 ) >>> 2 ;
4616- int result [] = new int [intLength ];
4617-
4618- /* Copy one's complement of input into output, leaving extra
4619- * byte (if it exists) == 0x00 */
4620- int b = indexBound - 1 ;
4621- for (int i = intLength -1 ; i >= 0 ; i --) {
4622- result [i ] = a [b --] & 0xff ;
4623- int numBytesToTransfer = Math .min (3 , b -keep +1 );
4624- if (numBytesToTransfer < 0 )
4625- numBytesToTransfer = 0 ;
4626- for (int j =8 ; j <= 8 *numBytesToTransfer ; j += 8 )
4627- result [i ] |= ((a [b --] & 0xff ) << j );
4628-
4629- // Mask indicates which bits must be complemented
4630- int mask = -1 >>> (8 *(3 -numBytesToTransfer ));
4631- result [i ] = ~result [i ] & mask ;
4658+ private static int [] makePositive (int b , byte [] a , int from , int len ) {
4659+ /*
4660+ * By assumption, b == a[from] < 0 and len > 0.
4661+ *
4662+ * First collect the bytes into the resulting array res.
4663+ * Then convert res to two's complement.
4664+ *
4665+ * Except for b == a[from], each read access to the input array a
4666+ * is of the form a[from++].
4667+ * The index from is never otherwise altered, except right below,
4668+ * and only increases in steps of 1, always up to index to.
4669+ * Hence, each byte in the array is read exactly once, from lower to
4670+ * higher indices (from most to least significant byte).
4671+ */
4672+ int to = from + len ;
4673+ /* b == a[from] has been read exactly once, skip to next index. */
4674+ ++from ;
4675+ /* Skip leading -1 bytes. */
4676+ for (; b == -1 && from < to ; b = a [from ++])
4677+ ; //empty body
4678+ /*
4679+ * A "digit" is a group of 4 adjacent bytes aligned w.r.t. index to.
4680+ * b is the most significant byte not -1, or -1 only if from == to.
4681+ * Digit d0 spans the range of indices that includes current (from - 1).
4682+ * (Implied -1 bytes are prepended to array a as needed.)
4683+ * It usually corresponds to res[0], except for the special case below.
4684+ */
4685+ int d0 = -1 << 8 | b & 0xFF ;
4686+ while (((to - from ) & 0x3 ) != 0 ) {
4687+ d0 = d0 << 8 | (b = a [from ++]) & 0xFF ;
4688+ }
4689+ int f = from ; // keeps the current from for sizing purposes later
4690+ /* Skip zeros adjacent to d0, if at all. */
4691+ for (; b == 0 && from < to ; b = a [from ++])
4692+ ; //empty body
4693+ /*
4694+ * b is the most significant non-zero byte at or after (f - 1),
4695+ * or 0 only if from == to.
4696+ * Digit d spans the range of indices that includes (f - 1).
4697+ */
4698+ int d = b & 0xFF ;
4699+ while (((to - from ) & 0x3 ) != 0 ) {
4700+ d = d << 8 | a [from ++] & 0xFF ;
46324701 }
4633-
4634- // Add one to one's complement to generate two's complement
4635- for (int i =result .length -1 ; i >= 0 ; i --) {
4636- result [i ] = (int )((result [i ] & LONG_MASK ) + 1 );
4637- if (result [i ] != 0 )
4638- break ;
4702+ /*
4703+ * If the situation here is like this:
4704+ * index: f to == from
4705+ * ..., -1,-1, 0,0,0,0, 0,0,0,0, ..., 0,0,0,0
4706+ * digit: d0 d
4707+ * then, as shown, the number of zeros is a positive multiple of 4.
4708+ * The array res needs a minimal length of (1 + 1 + (to - f) / 4)
4709+ * to accommodate the two's complement, including a leading 1.
4710+ * In any other case, there is at least one byte that is non-zero.
4711+ * The array for the two's complement has length (0 + 1 + (to - f) / 4).
4712+ * c is 1, resp., 0 for the two situations.
4713+ */
4714+ int c = (to - from | d0 | d ) == 0 ? 1 : 0 ;
4715+ int [] res = new int [c + 1 + ((to - f ) >> 2 )];
4716+ res [0 ] = c == 0 ? d0 : -1 ;
4717+ int i = res .length - ((to - from ) >> 2 );
4718+ if (i > 1 ) {
4719+ res [i - 1 ] = d ;
46394720 }
4640-
4641- return result ;
4721+ /*
4722+ * Prepare the remaining digits.
4723+ * (to - from) is a multiple of 4, so prepare an int for every 4 bytes.
4724+ * This is a candidate for Unsafe.copy[Swap]Memory().
4725+ */
4726+ while (from < to ) {
4727+ res [i ++] = a [from ++] << 24 | (a [from ++] & 0xFF ) << 16
4728+ | (a [from ++] & 0xFF ) << 8 | (a [from ++] & 0xFF );
4729+ }
4730+ /* Convert to two's complement. Here, i == res.length */
4731+ while (--i >= 0 && res [i ] == 0 )
4732+ ; // empty body
4733+ res [i ] = -res [i ];
4734+ while (--i >= 0 ) {
4735+ res [i ] = ~res [i ];
4736+ }
4737+ return res ;
46424738 }
46434739
46444740 /**
0 commit comments