Introduction Big-endian and Little-endian Big-endian, Little-endian are related to multibyte-type data, such as the Int,short,long type, but not to single-byte data byte. The Big-endian is the low byte emitted at the high address of the memory (right), and the high byte is emitted at the lower address of the memory (left). And Little-endian is the opposite. For example, int a = 0x05060708, in the case of Big-endian is stored as:
Address 0 1 2 3
Data 05 06 07 08
In case of Little-endian, store as: Address 0 1 2 3
Data was BigInteger
Let's take a look at the JDK's introduction to the BigInteger class:
Immutable arbitrary-precision integers. All operations behave as if bigintegers were represented in both ' s-complement notation (like Java ' s primitive integer types ).
BigInteger provides analogues to all of Java's primitive integer operators, and all relevant methods from Java.lang.Math. Additionally, BigInteger provides operations for modular arithmetic, GCD calculation, primality testing, Prime generation, Bit manipulation, and a few other miscellaneous operations.
The meaning of the above passage is:
BigInteger is an immutable integer of arbitrary precision. In all operations, BigInteger (such as the basic integer type of Java) are represented in twos complement form. BigInteger provides a counterpart to all Java's basic integer operators and provides all the relevant methods of Java.lang.Math. In addition, BigInteger provides the following operations: modulo arithmetic, GCD calculation, prime number test, prime generation, bit manipulation, and some other operations.
Here's a look at the key attributes of BigInteger, the main ones are the following three:
(1) Final int Signum
The Signum attribute is to differentiate between positive and negative and 0 flags, which are already understood in the JDK notes, 1 for negative numbers, 0 for 0, and 1 for integers:
The signum of this BigInteger:-1 for negative, 0 for zero, or 1 for positive. Note that the BigInteger zero must has a signum of 0. This was necessary to ensures that there is exactly one representation for each BigInteger value.
(2) Final int[] Mag
Mag is an abbreviated form of magnitude, and mag represents a positive source byte array. The mag array is stored BigInteger numeric size, in the order of Big-endian, that is, the high-level bytes into the low address, low-bit bytes into the high address, arranged in sequence. The original JDK notes are as follows:
The magnitude of this BigInteger, in Big-endian order:the zeroth element of this array is the most-significant int of the Magnitude. The magnitude must is "minimal" in the and the Most-significant Int (mag[0]) must be non-zero. This was necessary to ensure that there is exactly one representation for each BigInteger value. Note that this implies, the BigInteger Zero has a zero-length mag array.
(3) Final static long long_mask = 0xffffffffL;
This mask was used to obtain the value of an int as if it were unsigned.
Constructor BigInteger (byte[] val) This construction method is more difficult to understand, online and can not find information, so I read the source.
Public BigInteger (byte[] val) {if (val.length = = 0) throw new NumberFormatException ("Zero length BigInteger"); if (Val [0] < 0) { mag = makepositive (val); Signum =-1;} else { mag = stripleadingzerobytes (val); Signum = (Mag.length = = 0? 0:1);} }
If the first byte is a negative number, then this byte[] Val is the complement of the negative. Therefore, the absolute value of the negative number can be obtained by the complement of the inverse (complement complement), then the sign bit is set to-, then the negative number represented by this complement is obtained. Here is the source code, where the red for my annotations.
private static int[] Makepositive (byte a[]) {int Keep, k; int bytelength = a.length;//Find First non-sign (0xff) byte of Inputfor (keep=0; keep<bytelength && a[keep]==- 1; keep++) <span style= "color: #ff0000;" >//keep indicates that the first non-signed bit is the byte index of 1, and the byte that keep the index begins is a valid byte </span>; <span style= "color: #ff0000;" The >//k is used to determine whether the byte after the start of the non-sign bit is all 0, and if so, indicates that the value is the minimum value that the complement can represent. Fixed bits number, the complement represents the value range is the negative minimum value of the absolute value is 1 larger than the positive maximum, so if you want to represent the absolute value of the negative minimum, add 1 bit bits, here is the extra byte. </span>/* Allocate output Array. If all non-sign Bytes is 0x00, we must * allocate space for one extra output byte. */for (k=keep; k<bytelength && a[k]==0; k++); int extrabyte = (k==bytelength)? 1:0; int intlength = ((Bytelength-keep + extrabyte) + 3)/4;<span style= "color: #ff0000;" The length of the >//result array depends on the number of valid bytes and extrabyte</span>int result[] = new Int[intlength];<span style= "color: #ff0000;" >//the array of results to return </span>/* Copy one's complement of input into output, leaving extra * byte (if itexists) = = 0x00 */int b = byteLength-1; for (int i = intLength-1; I >= 0; i--) {result[i] = a[b--] & 0xff; int numbytestotransfer = Math.min (3, b-keep+1) <span style= "color: #ff0000;" >;//numbytestotransfer indicates that next several bytes need to be populated into the result array, a int4 byte, so the maximum takes 3</span> if (Numbytestotransfer < 0) Numbytestotransfer = 0; for (int j=8; J <= 8*numbytestotransfer; j + = 8) result[i] |= ((a[b--] & 0xff) << j); <span style= "COLOR: #ff0000;" >//8 bits per byte, so each sliding scale 8 bits </span>/Mask indicates which bits must be Complemented<span style= "color: #ff0 000; " >//mask is used to mark which few bytes need to be reversed (one's complement) </span> int mask =-1 >>> (8* (3-numbytestotransfer)); Result[i] = ~result[i] & mask; }//Add one to one's complement to generate, Complement<span style= "color: #ff0000;" After the >//complement is reversed, the value at the maximum index of the result array is added 1 to get the original code (that is, the integer corresponding to the negative complement) </span>for (int i=result.length-1; i>=0; i--) {result[i] = (int) ((Result[i] & Long_mask) + 1); if (result[i]! = 0) <span style= "color: #ff0000;" >//result[i] At this time is already the original code, if the original code is all 0, complement also must be 0 of the body. Complement full 0 after the reverse is full 1, plus 1 to carry, so result[i+1] to add 1</span> break; }return result; }
Summary: If the parameter byte array starts with 1, regardless of a few, as long as 1 is contiguous, then these 1 are considered symbols--1 of the next byte is the valid byte. If you do not start with 1 but other negative numbers, the valid bytes start at index 0. Second, if the first byte is an integer, then the Stripleadingzerobytes method is used, and the twos complement of each byte is concatenated sequentially and then returned after removing the beginning 0.
/** * Returns A copy of the input array stripped of any leading zero bytes. * /private static int[] Stripleadingzerobytes (byte a[]) { int bytelength = a.length;int keep;//Find First Nonzero Bytefor (keep=0; keep<bytelength && a[keep]==0; keep++) ;//Allocate new array and copy relevant part of I Nput array int intlength = ((bytelength-keep) + 3) >>> 2;int[] result = new Int[intlength]; int b = byteLength-1; for (int i = intLength-1; I >= 0; i--) { result[i] = a[b--] & 0xff; int bytesremaining = b-keep + 1; int bytestotransfer = Math.min (3, bytesremaining); for (int j=8; J <= (Bytestotransfer << 3), J + + 8) Result[i] |= ((a[b--] & 0xff) << j); } return result; }
BigInteger (int signum, byte[] magnitude)
public BigInteger (int signum, byte[] magnitude) {This.mag = Stripleadingzerobytes ( magnitude); if (Signum <-1 | | signum > 1) throw (new NumberFormatException ("Invalid signum value"); if (THIS.MAG.L ength==0) {this.signum = 0;} else {if (Signum = = 0) throw (new NumberFormatException ("Signum-magnitude mismatch")); This.signum = Signum;} }
This construction method is very well understood, the mag array is also using the Stripleadingzerobytes method, each byte of the twos complement in order to remove the beginning of the 0 after the return, but the sign bit can be given by the pass parameter. BigInteger (string val) converts the BigInteger decimal string representation to BigInteger. The string representation includes an optional minus sign followed by one or more decimal digit sequences. The character-to-number mapping is provided by Character.digit. The string cannot contain any other characters (for example, spaces). BigInteger (string val, int radix) Converts the string representation of the BigInteger of the specified cardinality to BigInteger. The string representation includes an optional minus sign followed by one or more digits of the specified cardinality. The character-to-number mapping is provided by Character.digit. The string cannot contain any other characters (for example, spaces). BigInteger (int numbits, random rnd) constructs a randomly generated BigInteger, which is a value that is evenly distributed within the range of 0 to (2^NUMBITS-1) (inclusive). The uniformity of the distribution assumes that the RND provides a fair source of random bits (fair source). Note that this construction method always constructs a non-negative BigInteger. BigInteger (int bitlength, int certainty, random rnd) constructs a randomly generated positive BigInteger, which may be a prime number with a specified bitlength. With respect to this construction method, it is recommended that the Probableprime method be preferred, except where a certain number must be specified. Certainty represents the measure of uncertainty allowed by the caller. The new BigInteger represents the probability of a prime number exceeding (1-1/2^certainty). The execution time of this construction method is proportional to the value of this parameter. Caveats Java.math.BigInteger Series Tutorials (eight) BigInteger how to store big data? from the above introduction, we already know the BigInteger data storage, it is stored in an array of int. TheseThe int value in an int array is essentially a binary digit. The maximum value for int is: 2147483647. That is, mag[] inside can be put into 2,147,483,647 int values, each int value is 32 bits, mag[] can represent the array range is: [ -22147483647*32-1, 22147483647*32-1-1]. public static BigInteger ValueOf (long Val) This method can return BigInteger, if the value is between 16-16, then the BigInteger returned is the same object. The following is the source code:
public static BigInteger ValueOf (long val) {//If-max_constant < Val < Max_constant, return stashed Constantif (Val = = 0) return zero;if (val > 0 && val <= max_constant) return posconst[(int) Val];else if (Val < 0 && val >=-max_constant) return negconst[(int)-val];return new BigInteger (val); }
/** * Initialize static constant array when class is loaded. */ private final static int max_constant = +; private static BigInteger posconst[] = new biginteger[max_constant+1]; private static BigInteger negconst[] = new biginteger[max_constant+1]; static {for (int i = 1; I <= max_constant; i++) { int[] magnitude = new int[1]; Magnitude[0] = i; Posconst[i] = new BigInteger (magnitude, 1); Negconst[i] = new BigInteger (magnitude,-1);} }
System.out.println (biginteger.valueof) = = biginteger.valueof (+))//truesystem.out.println (biginteger.valueof (+) = = biginteger.valueof (+));//falsesystem.out.println (biginteger.valueof ( -16) = = biginteger.valueof (-16));// TrueSystem.out.println (biginteger.valueof ( -17) = = biginteger.valueof ( -17));//false
Basic Operations Example
public static void Main (string[] args) { BigInteger B1 = biginteger.valueof (20l); BigInteger b2 = biginteger.valueof (10l); System.out.println (B1.add (B2). ToString ());//Add to System.out.println (B1.subtract (B2). ToString ());//minus Ten System.out.println (B1.multiply (B2). ToString ());//Multiply System.out.println (b1.divide (B2). ToString ());//except 2 System.out.println (B1.remainder (B2). toString ());//Take more than 0 }
A brief analysis of BigInteger