@@ -315,12 +315,18 @@ public BigInteger(byte[] val, int off, int len) {
315
315
throw new NumberFormatException ("Zero length BigInteger" );
316
316
}
317
317
Objects .checkFromIndexSize (off , len , val .length );
318
+ if (len == 0 ) {
319
+ mag = ZERO .mag ;
320
+ signum = ZERO .signum ;
321
+ return ;
322
+ }
318
323
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 );
321
327
signum = -1 ;
322
328
} else {
323
- mag = stripLeadingZeroBytes (val , off , len );
329
+ mag = stripLeadingZeroBytes (b , val , off , len );
324
330
signum = (mag .length == 0 ? 0 : 1 );
325
331
}
326
332
if (mag .length >= MAX_MAG_LENGTH ) {
@@ -4568,77 +4574,167 @@ private static int[] trustedStripLeadingZeroInts(int[] val) {
4568
4574
return keep == 0 ? val : java .util .Arrays .copyOfRange (val , keep , vlen );
4569
4575
}
4570
4576
4571
- /**
4577
+ private static int [] stripLeadingZeroBytes (byte [] a , int from , int len ) {
4578
+ return stripLeadingZeroBytes (Integer .MIN_VALUE , a , from , len );
4579
+ }
4580
+
4581
+ /*
4572
4582
* 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.
4573
4591
*/
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 ;
4592
4603
}
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 ;
4594
4648
}
4595
4649
4596
- /**
4650
+ /*
4597
4651
* Takes an array a representing a negative 2's-complement number and
4598
4652
* 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.
4599
4657
*/
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 ;
4632
4701
}
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 ;
4639
4720
}
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 ;
4642
4738
}
4643
4739
4644
4740
/**
0 commit comments