@@ -312,12 +312,18 @@ public BigInteger(byte[] val, int off, int len) {
312
312
throw new NumberFormatException ("Zero length BigInteger" );
313
313
}
314
314
Objects .checkFromIndexSize (off , len , val .length );
315
+ if (len == 0 ) {
316
+ mag = ZERO .mag ;
317
+ signum = ZERO .signum ;
318
+ return ;
319
+ }
315
320
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 );
318
324
signum = -1 ;
319
325
} else {
320
- mag = stripLeadingZeroBytes (val , off , len );
326
+ mag = stripLeadingZeroBytes (b , val , off , len );
321
327
signum = (mag .length == 0 ? 0 : 1 );
322
328
}
323
329
if (mag .length >= MAX_MAG_LENGTH ) {
@@ -4438,77 +4444,168 @@ private static int[] trustedStripLeadingZeroInts(int val[]) {
4438
4444
return keep == 0 ? val : java .util .Arrays .copyOfRange (val , keep , vlen );
4439
4445
}
4440
4446
4441
- /**
4447
+ private static int [] stripLeadingZeroBytes (byte [] a , int from , int len ) {
4448
+ return stripLeadingZeroBytes (Integer .MIN_VALUE , a , from , len );
4449
+ }
4450
+
4451
+ /*
4442
4452
* 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.
4443
4461
*/
4444
- private static int [] stripLeadingZeroBytes (byte a [], int off , int len ) {
4445
- int indexBound = off + len ;
4446
- int keep ;
4447
4462
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 ;
4462
4474
}
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 ;
4464
4519
}
4465
4520
4466
- /**
4521
+ /*
4467
4522
* Takes an array a representing a negative 2's-complement number and
4468
4523
* 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.
4469
4528
*/
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 ;
4502
4572
}
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 ;
4509
4591
}
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 ;
4512
4609
}
4513
4610
4514
4611
/**
0 commit comments