@@ -312,12 +312,18 @@ public BigInteger(byte[] val, int off, int len) {
312312 throw new NumberFormatException ("Zero length BigInteger" );
313313 }
314314 Objects .checkFromIndexSize (off , len , val .length );
315+ if (len == 0 ) {
316+ mag = ZERO .mag ;
317+ signum = ZERO .signum ;
318+ return ;
319+ }
315320
316- if (val [off ] < 0 ) {
317- mag = makePositive (val , off , len );
321+ int b = val [off ];
322+ if (b < 0 ) {
323+ mag = makePositive (b , val , off , len );
318324 signum = -1 ;
319325 } else {
320- mag = stripLeadingZeroBytes (val , off , len );
326+ mag = stripLeadingZeroBytes (b , val , off , len );
321327 signum = (mag .length == 0 ? 0 : 1 );
322328 }
323329 if (mag .length >= MAX_MAG_LENGTH ) {
@@ -4438,77 +4444,168 @@ private static int[] trustedStripLeadingZeroInts(int val[]) {
44384444 return keep == 0 ? val : java .util .Arrays .copyOfRange (val , keep , vlen );
44394445 }
44404446
4441- /**
4447+ private static int [] stripLeadingZeroBytes (byte [] a , int from , int len ) {
4448+ return stripLeadingZeroBytes (Integer .MIN_VALUE , a , from , len );
4449+ }
4450+
4451+ /*
44424452 * Returns a copy of the input array stripped of any leading zero bytes.
4453+ * The returned array is either empty, or its 0-th element is non-zero,
4454+ * meeting the "minimal" requirement for field mag (see comment on mag).
4455+ *
4456+ * The range [from, from + len) must be well-formed w.r.t. array a.
4457+ *
4458+ * b < -128 means that a[from] has not yet been read.
4459+ * Otherwise, b must be a[from], have been read only once before invoking
4460+ * this method, and len > 0 must hold.
44434461 */
4444- private static int [] stripLeadingZeroBytes (byte a [], int off , int len ) {
4445- int indexBound = off + len ;
4446- int keep ;
44474462
4448- // Find first nonzero byte
4449- for (keep = off ; keep < indexBound && a [keep ] == 0 ; keep ++)
4450- ;
4451-
4452- // Allocate new array and copy relevant part of input array
4453- int intLength = ((indexBound - keep ) + 3 ) >>> 2 ;
4454- int [] result = new int [intLength ];
4455- int b = indexBound - 1 ;
4456- for (int i = intLength -1 ; i >= 0 ; i --) {
4457- result [i ] = a [b --] & 0xff ;
4458- int bytesRemaining = b - keep + 1 ;
4459- int bytesToTransfer = Math .min (3 , bytesRemaining );
4460- for (int j =8 ; j <= (bytesToTransfer << 3 ); j += 8 )
4461- result [i ] |= ((a [b --] & 0xff ) << j );
4463+ private static int [] stripLeadingZeroBytes (int b , byte [] a , int from , int len ) {
4464+ /*
4465+ * Except for the first byte, each read access to the input array a
4466+ * is of the form a[from++].
4467+ * The index from is never otherwise altered, except right below,
4468+ * and only increases in steps of 1, always up to index to.
4469+ * Hence, each byte in the array is read exactly once, from lower to
4470+ * higher indices (from most to least significant byte).
4471+ */
4472+ if (len == 0 ) {
4473+ return ZERO .mag ;
44624474 }
4463- return result ;
4475+ int to = from + len ;
4476+ if (b < -128 ) {
4477+ b = a [from ];
4478+ }
4479+ /* Either way, a[from] has now been read exactly once, skip to next. */
4480+ ++from ;
4481+ /*
4482+ * Set up the shortest int[] for the sequence of the bytes
4483+ * b, a[from+1], ..., a[to-1] (len > 0)
4484+ * Shortest means first skipping leading zeros.
4485+ */
4486+ for (; b == 0 && from < to ; b = a [from ++])
4487+ ; //empty body
4488+ if (b == 0 ) {
4489+ /* Here, from == to as well. All bytes are zeros. */
4490+ return ZERO .mag ;
4491+ }
4492+ /*
4493+ * Allocate just enough ints to hold (to - from + 1) bytes, that is
4494+ * ((to - from + 1) + 3) / 4 = (to - from) / 4 + 1
4495+ */
4496+ int [] res = new int [((to - from ) >> 2 ) + 1 ];
4497+ /*
4498+ * A "digit" is a group of 4 adjacent bytes aligned w.r.t. index to.
4499+ * (Implied 0 bytes are prepended as needed.)
4500+ * b is the most significant byte not 0.
4501+ * Digit d0 spans the range of indices that includes current (from - 1).
4502+ */
4503+ int d0 = b & 0xFF ;
4504+ while (((to - from ) & 0x3 ) != 0 ) {
4505+ d0 = d0 << 8 | a [from ++] & 0xFF ;
4506+ }
4507+ res [0 ] = d0 ;
4508+ /*
4509+ * Prepare the remaining digits.
4510+ * (to - from) is a multiple of 4, so prepare an int for every 4 bytes.
4511+ * This is a candidate for Unsafe.copy[Swap]Memory().
4512+ */
4513+ int i = 1 ;
4514+ while (from < to ) {
4515+ res [i ++] = a [from ++] << 24 | (a [from ++] & 0xFF ) << 16
4516+ | (a [from ++] & 0xFF ) << 8 | (a [from ++] & 0xFF );
4517+ }
4518+ return res ;
44644519 }
44654520
4466- /**
4521+ /*
44674522 * Takes an array a representing a negative 2's-complement number and
44684523 * returns the minimal (no leading zero bytes) unsigned whose value is -a.
4524+ *
4525+ * len > 0 must hold.
4526+ * The range [from, from + len) must be well-formed w.r.t. array a.
4527+ * b is assumed to be the result of reading a[from] and to meet b < 0.
44694528 */
4470- private static int [] makePositive (byte a [], int off , int len ) {
4471- int keep , k ;
4472- int indexBound = off + len ;
4473-
4474- // Find first non-sign (0xff) byte of input
4475- for (keep =off ; keep < indexBound && a [keep ] == -1 ; keep ++)
4476- ;
4477-
4478-
4479- /* Allocate output array. If all non-sign bytes are 0x00, we must
4480- * allocate space for one extra output byte. */
4481- for (k =keep ; k < indexBound && a [k ] == 0 ; k ++)
4482- ;
4483-
4484- int extraByte = (k == indexBound ) ? 1 : 0 ;
4485- int intLength = ((indexBound - keep + extraByte ) + 3 ) >>> 2 ;
4486- int result [] = new int [intLength ];
4487-
4488- /* Copy one's complement of input into output, leaving extra
4489- * byte (if it exists) == 0x00 */
4490- int b = indexBound - 1 ;
4491- for (int i = intLength -1 ; i >= 0 ; i --) {
4492- result [i ] = a [b --] & 0xff ;
4493- int numBytesToTransfer = Math .min (3 , b -keep +1 );
4494- if (numBytesToTransfer < 0 )
4495- numBytesToTransfer = 0 ;
4496- for (int j =8 ; j <= 8 *numBytesToTransfer ; j += 8 )
4497- result [i ] |= ((a [b --] & 0xff ) << j );
4498-
4499- // Mask indicates which bits must be complemented
4500- int mask = -1 >>> (8 *(3 -numBytesToTransfer ));
4501- result [i ] = ~result [i ] & mask ;
4529+ private static int [] makePositive (int b , byte [] a , int from , int len ) {
4530+ /*
4531+ * By assumption, b == a[from] < 0 and len > 0.
4532+ *
4533+ * First collect the bytes into the resulting array res.
4534+ * Then convert res to two's complement.
4535+ *
4536+ * Except for b == a[from], each read access to the input array a
4537+ * is of the form a[from++].
4538+ * The index from is never otherwise altered, except right below,
4539+ * and only increases in steps of 1, always up to index to.
4540+ * Hence, each byte in the array is read exactly once, from lower to
4541+ * higher indices (from most to least significant byte).
4542+ */
4543+ int to = from + len ;
4544+ /* b == a[from] has been read exactly once, skip to next index. */
4545+ ++from ;
4546+ /* Skip leading -1 bytes. */
4547+ for (; b == -1 && from < to ; b = a [from ++])
4548+ ; //empty body
4549+ /*
4550+ * A "digit" is a group of 4 adjacent bytes aligned w.r.t. index to.
4551+ * b is the most significant byte not -1, or -1 only if from == to.
4552+ * Digit d0 spans the range of indices that includes current (from - 1).
4553+ * (Implied -1 bytes are prepended to array a as needed.)
4554+ * It usually corresponds to res[0], except for the special case below.
4555+ */
4556+ int d0 = -1 << 8 | b & 0xFF ;
4557+ while (((to - from ) & 0x3 ) != 0 ) {
4558+ d0 = d0 << 8 | (b = a [from ++]) & 0xFF ;
4559+ }
4560+ int f = from ; // keeps the current from for sizing purposes later
4561+ /* Skip zeros adjacent to d0, if at all. */
4562+ for (; b == 0 && from < to ; b = a [from ++])
4563+ ; //empty body
4564+ /*
4565+ * b is the most significant non-zero byte at or after (f - 1),
4566+ * or 0 only if from == to.
4567+ * Digit d spans the range of indices that includes (f - 1).
4568+ */
4569+ int d = b & 0xFF ;
4570+ while (((to - from ) & 0x3 ) != 0 ) {
4571+ d = d << 8 | a [from ++] & 0xFF ;
45024572 }
4503-
4504- // Add one to one's complement to generate two's complement
4505- for (int i =result .length -1 ; i >= 0 ; i --) {
4506- result [i ] = (int )((result [i ] & LONG_MASK ) + 1 );
4507- if (result [i ] != 0 )
4508- break ;
4573+ /*
4574+ * If the situation here is like this:
4575+ * index: f to == from
4576+ * ..., -1,-1, 0,0,0,0, 0,0,0,0, ..., 0,0,0,0
4577+ * digit: d0 d
4578+ * then, as shown, the number of zeros is a positive multiple of 4.
4579+ * The array res needs a minimal length of (1 + 1 + (to - f) / 4)
4580+ * to accommodate the two's complement, including a leading 1.
4581+ * In any other case, there is at least one byte that is non-zero.
4582+ * The array for the two's complement has length (0 + 1 + (to - f) / 4).
4583+ * c is 1, resp., 0 for the two situations.
4584+ */
4585+ int c = (to - from | d0 | d ) == 0 ? 1 : 0 ;
4586+ int [] res = new int [c + 1 + ((to - f ) >> 2 )];
4587+ res [0 ] = c == 0 ? d0 : -1 ;
4588+ int i = res .length - ((to - from ) >> 2 );
4589+ if (i > 1 ) {
4590+ res [i - 1 ] = d ;
45094591 }
4510-
4511- return result ;
4592+ /*
4593+ * Prepare the remaining digits.
4594+ * (to - from) is a multiple of 4, so prepare an int for every 4 bytes.
4595+ * This is a candidate for Unsafe.copy[Swap]Memory().
4596+ */
4597+ while (from < to ) {
4598+ res [i ++] = a [from ++] << 24 | (a [from ++] & 0xFF ) << 16
4599+ | (a [from ++] & 0xFF ) << 8 | (a [from ++] & 0xFF );
4600+ }
4601+ /* Convert to two's complement. Here, i == res.length */
4602+ while (--i >= 0 && res [i ] == 0 )
4603+ ; // empty body
4604+ res [i ] = -res [i ];
4605+ while (--i >= 0 ) {
4606+ res [i ] = ~res [i ];
4607+ }
4608+ return res ;
45124609 }
45134610
45144611 /**
0 commit comments