Implementation of large integer arithmetic based on Java (addition, subtraction, multiplication) Learning notes

Source: Internet
Author: User

A large integer, as the name implies, is a particularly large integer.

A 64-bit machine can represent a maximum of 2 of the 64-time minus One:

18446744073709551615

The minimum number of integers (int) that can be represented in the Java language is-2147483648

 Public class Test {    publicstaticvoid  main (string[] args) {      System.out.println ( Integer.min_value);}    }

Most greatly

2147483647

 Public class Test {    publicstaticvoid  main (string[] args) {      System.out.println ( Integer.max_value);}    }

and the largest integer that long can represent is

 Public class Test {    publicstaticvoid  main (string[] args) {       System.out.println (Long.max_value);    }}

9223372036854775807

Minimum is

 Public class Test {    publicstaticvoid  main (string[] args) {       System.out.println ( Long.min_value);}    }

-9223372036854775808

If these ranges are exceeded, an out of range error is reported, so Java provides the BigInteger class to perform large integer operations. In fact, it is not difficult to realize the principle of BigInteger. The following is the implementation of addition, subtraction, which has been multiplied.

A Bignum attribute is required inside the class

public class Mybiginteger {
String Bignum;
Public Mybiginteger (String bigone) {
This.bignum = Bigone;
}

addition : According to the teacher in class to guide, probably the idea is very simple, is to divide the large integer into several segments (every four numbers a paragraph), and then the corresponding number of fields to add.

For example, 12345678987654321 and 8765432123456789 Add. Then divide the two numbers into

1 2345 6789) 8765 4321

8765 4321 2345 6789 the corresponding and is

2 1111 1111) 1111 1110

(The main idea of grouping is from the forward, each four numbers a group, to the front of a group if not enough four digits, then a group of)

//Chunking , used in addition and subtraction    Privatestring[] Getgroup (String number) {intLength = (int) Math.ceil (Number.length ()/4.0); String[] group=NewString[length];  for(inti = length; i > 0; i--) {//Note that the substring is the previous intercept character, not the forward character from the backward            if(Number.length ()-(length-i) * 4-4 < 0) {Group[length-I] = number.substring (0, Number.length ()-(length-i) * 4); } Else{group[length-I] = number.substring (Number.length ()-(length-i) * 4-4, Number.length ()-(length-i) * 4); }        }        returnGroup; }

There is a need to take into account the rounding problem between blocks. Because each corresponding block is added, you can use Integer.parseint (...). is converted to a number and added, but the corresponding block may be added more than 9999, which will be rounded up to the front block. This will set a property boolean[] Fillthousand. To determine if a carry is required, the length of the array should be one more than the length of the block after two decimal blocks (such as the two number blocks above, the block length is 5 and 4, so the length of the Fillthousand should be 6.)

If a corresponding block wants to be larger than 9999, subtract this number by 10000 (or convert it to a string and intercept it from the second character), and turn the Fillthousand property of the previous block to true.

If a block is true for the Fillthousand property, then add 1 to the corresponding block. If the Fillthousand property of the front block is true (which is why the Ffillthousand length is set to 6), the total result is preceded by a "1".

(Here, I'm taking a longer number as the first number, note, just the length, in subtraction, I'll take the larger number as the first number)

private string Addpn (string bigtwo) {//temporarily without considering negative int a1 = (int) Math.ceil (Bignum.length ()/4.0); int a2 = (int) Math.ceil (bi Gtwo.length ()/4.0); string[] group1 = new STRING[A1]; string[] group2 = new String[a2];group1 = Getgroup (bignum); group2 = Getgroup (bigtwo); if (Bigtwo.length () > Bignum.leng Th ()) {//Put long on A1 string[] temp = Group1;group1 = group2;group2 = TEMP;A1 = Group1.length;a2 = Group2.length;} String AddAll = ""; boolean[] Fillthousand = new BOOLEAN[A1 + 1];//whether each block of numbers requires a carry for (int i = 0; i < A1; i++) {if (I <= a2-1) {integer i1 = integer.parseint (Group1[i]); Integer i2 = Integer.parseint (Group2[i]); Integer iall = I1 + i2;if (Fillthousand[i]) {iall + = 1;} if (Iall > 9999 && i! = a2-1) {//Iall=integer.parseint (iall.tostring (). substring (1,5)); If 10000, this method does not work. 0000=0string Subiall = iall.tostring (). substring (1, 5); iall = Integer.parseint (Subiall); Fillthousand[i + 1] = true;} if (iall.tostring (). Length () = = 3 && i! = a2-1) {AddAll = "0" + Iall + AddAll;}else if (iall.tostring (). Length () = = 2 && i! = a2-1) {AddAll = "xx" + Iall + addall;} else if (Iall.tostring (). L  Ength () = = 4 && i! = a2-1) {AddAll = Iall + addall;} else if (iall.tostring (). Length () = = 1 && i! = A2- 1) {AddAll = "$" + Iall + AddAll;} if (i = = a2-1) {if (Iall > 9999) {//Iall=integer.parseint (iall.tostring (). substring (1,5)); If 10000, this method does not work. 0000=0string Subiall = iall.tostring (). substring (1, 5); iall = Integer.parseint (Subiall); Fillthousand[i + 1] = true;} if (iall.tostring (). Length () = = 3) {AddAll = "0" + Iall + addall;} else if (iall.tostring (). Length () = = 2) {AddAll = "00" + Iall + AddAll;} else if (iall.tostring (). Length () = = 1) {AddAll = "+" + Iall + addall;//Ensure that the first number does not add 0} else if (iall.tostring (). Length ( ) = = 4) {AddAll = Iall + addall;} else if (a1 = = a2) {AddAll = Iall + AddAll;}} If the first piece is added more than 1000if (Fillthousand[a1]) {AddAll = "1" + AddAll;}} else {Integer Iall = Integer.parseint (Group1[i]), if (Fillthousand[i]) {iall + = 1;} IF (i = = a1-1) {AddAll = Iall + AddAll;} if (iall.tostring (). Length () = = 3 && i! = a1-1) {AddAll = "0" + Iall + addall;} else if (iall.tostring (). Length ( ) = = 2 && i! = a1-1) {AddAll = "xx" + Iall + addall;} else if (iall.tostring (). Length () = = 1 && i! = A1 -1) {//Iall is more than 1000addAll = "$" + Iall + addall;//to ensure that the first number does not add 0} else if (iall.tostring (). Length () = = 1 && ia ll = = 0 && i = = a1-1) {AddAll = addall;//ensure that the first number does not add 0} else if (iall.tostring (). Length () = = 4 && I! = a1-1) {AddAll = Iall + AddAll;} If the first piece is added more than 1000if (Fillthousand[a1]) {AddAll = "1" + AddAll;}}} If you do not do this, there will be 000000000001 cases if (addall! = "") {if (Addall.charat (0) = = ' 0 ') {int a = 0;while (Integer.parseint (addall.s Ubstring (A, A + 1)) = = 0) {A + = 1;if (A = = Addall.length ()) {break;}} AddAll = Addall.substring (A, Addall.length ()), if (A = = Addall.length ()) {AddAll = "0";}}} else {AddAll = "0";} return addall;}

  

The above is the code for the addition of two positive integers, but there are also negative additions in addition. So combined with the subsequent subtraction of two positive integers. A complete algorithm for addition can be obtained

Public Mybiginteger Add (Mybiginteger bigtwo) {String returnnum=null;if (!) ( This.bignum.charAt (0) = = '-') &&! (bigtwo.bignum.charAt (0) = = '-')) {returnnum = ADDPN (bigtwo.bignum);} else if (this.bignum.charAt (0) = = '-' &&! ( Bigtwo.bignum.charAt (0) = = '-')} {bignum = bignum.substring (1, Bignum.length ()); if (SUBSTRACTPN (bigtwo.bignum). charAt (0) = = '-') {returnnum = SUBSTRACTPN (bigtwo.bignum). substring (1, SUBSTRACTPN (bigtwo.bignum). Length ());} else { Returnnum = "-" + SUBSTRACTPN (Bigtwo.bignum);}} else if (! ( This.bignum.charAt (0) = = '-') && bigtwo.bignum.charAt (0) = = '-') {bigtwo.bignum = bigtwo.bignum.substring (1, Bigtwo.bignum.length ()); returnnum = SUBSTRACTPN (bigtwo.bignum);} else//two are negative {bignum = bignum.substring (1, Bignum.length ()); bigtwo.bignum = bigtwo.bignum.substring (1, Bigtwo.bignum.length ()); returnnum = "-" + ADDPN (bigtwo.bignum);} return new Mybiginteger (Returnnum);}

  

Subtraction:

Subtraction algorithm is more complicated than the algorithm of addition, because subtraction should consider not only borrow but also positive and negative.

Or do the subtraction of two integers first

First or the group ....

And then treat the big numbers as minuend.

Subtraction inside to set two large properties, one is a Boolean reverse, which means that if the first number is less than the second number, then swap two positions, and then precede the result with "-".

private string SUBSTRACTPN (string bigtwo) {//temporarily without considering negative int a1 = (int) Math.ceil (Bignum.length ()/4.0); int a2 = (int) math.c Eil (bigtwo.length ()/4.0); string[] group1 = new STRING[A1]; string[] group2 = new String[a2];group1 = Getgroup (bignum); group2 = Getgroup (Bigtwo); Boolean reverse = false;//determine if it is a small number Minus a large number, if, then swap two positions, and at the end add a minus sign Boolean onemoretwo = true;//the same number of digits, compare size if (bigtwo.length () = = Bignum.length ()) {// If the two-digit length is equal, compare the size of the first two paragraphs if (Integer.parseint (Group2[a1-1]) > Integer.parseint (group1[a1-1])) {onemoretwo = false;} if ((Integer.parseint (group2[a1-1]) = = Integer.parseint (Group1[a1-1]) && (Integer.parseint (Group2[a1-2]) &G T Integer.parseint (Group1[a1-2])) {onemoretwo = false;}} if (Bigtwo.length () > bignum.length () | |!onemoretwo) {//Put a long number on A1 string[] temp = Group1;group1 = Group2;group2 = Temp ; a1 = Group1.length;a2 = Group2.length;reverse = true;} 。。。。。。。。。。。。 。。。。。。。。。。。。 。。。。。。。。。。。。 This is the last two lines, omitting a number of codes in the middle if (reverse) {Substractall= "-" + substractall;  }

  

another boolean[] borrowone, whether borrow, is similar to the Fillthousand attribute of the addition. If the result of subtracting a corresponding block is less than 0, then add 10000 to the result and borrow 1 from the previous block. Then set the borrowone of the previous block to true.

If the Borrowone property of a block is true, the result of this block is reduced by 1.

boolean[] Borrowone = new BOOLEAN[A1 + 1];//determine if borrow string Substractall = "" is required; for (int i = 0; i < A1; i++) {if (I <= a2-1) {integer i1 = integer.parseint (Group1[i]); Integer i2 = Integer.parseint (Group2[i]); Integer isubs tract = i1-i2;//processing isubstract is 0000 if (Borrowone[i]) {isubstract-= 1;} if (Isubstract < 0) {isubstract = isubstract + 10000;//determine number of digits Borrowone[i + 1] = true;if (isubstract > 0 && is  Ubstract.tostring (). Length () = = 3) {Substractall = "0" + isubstract + substractall;} else if (Isubstract > 0 && Isubstract.tostring (). Length () = = 2) {Substractall = "xx" + Isubstract + substractall;} else if (Isubstract > 0 && Amp Isubstract.tostring (). Length () = = 1) {Substractall = "$" + Isubstract + substractall;} else if (Isubstract > 0 && Amp  Isubstract.tostring (). Length () = = 4) {Substractall = Isubstract + substractall;} else if (isubstract = = 0) {Substractall = "0000" + Substractall;}} else if (isubstract > 0 && isubstract.tosTring (). Length () = = 3) {Substractall = "0" + isubstract + substractall;} else if (isubstract > 0 && isubstract. ToString (). Length () = = 2) {Substractall = "xx" + Isubstract + substractall;} else if (isubstract > 0 && isubstr Act.tostring (). Length () = = 1) {Substractall = "$" + Isubstract + substractall;} else if (Isubstract > 0 && is Ubstract.tostring (). Length () = = 4) {Substractall = Isubstract + substractall;} else if (isubstract = = 0) {Substractall = " 0000 "+ Substractall;}} else {Integer isubstract = Integer.parseint (Group1[i]), if (Borrowone[i]) {isubstract-= 1;} if (i = = a1-1) {Substractall = Isubstract + substractall;} if (isubstract > 0 && isubstract.tostring (). Length () = = 3 && i! = a1-1) {Substractall = "0" + isubstr Act + Substractall;} else if (isubstract > 0 && isubstract.tostring (). Length () = = 2 && i! = a1-1) {substractall = "xx" + I Substract + Substractall;} else if (isubstract > 0 && isubstrAct.tostring (). Length () = = 1 && i! = a1-1) {Substractall = "$" + Isubstract + substractall;} else if (Isubstra CT > 0 && isubstract.tostring (). Length () = = 4 && i! = a1-1) {Substractall = isubstract + substractall ;} else if (isubstract = = 0) {substractall = "0000" + Substractall;}}}

  

Of course, subtraction, we have to deal with 000001 cases like this.

If you do not do this, there will be 000000000001 cases

if (Integer.parseint (substractall.substring (0, 1) = = 0) {
int a = 0;
while (Integer.parseint (Substractall.substring (A, A + 1)) = = 0) {
A + = 1;
}
Substractall = Substractall.substring (A, substractall.length ());
}

The above is the implementation of positive subtraction, combined with addition, you can achieve a complete subtraction

public Mybiginteger substract (Mybiginteger bigtwo) {//Only equals cannot be used ==string Returnnum=null;if (! ( This.bignum.charAt (0) = = '-') &&! (bigtwo.bignum.charAt (0) = = '-')) {returnnum = SUBSTRACTPN (bigtwo.bignum);} else if (this.bignum.charAt (0) = = '-' &&! ( Bigtwo.bignum.charAt (0) = = '-')} {bignum = bignum.substring (1, Bignum.length ()); returnnum = "-" + ADDPN (bigtwo.bignum);} else if (! ( This.bignum.charAt (0) = = '-') && bigtwo.bignum.charAt (0) = = '-') {bigtwo.bignum = bigtwo.bignum.substring (1, Bigtwo.bignum.length ()); returnnum = Addpn (bigtwo.bignum);} else {//two are both negative bignum = bignum.substring (1, Bignum.length ()); bigtwo.bignum = bigtwo.bignum.substring (1, Bigtwo.bignum.length ()); if (SUBSTRACTPN (bigtwo.bignum). CharAt (0) = = '-') {returnnum = SUBSTRACTPN (bigtwo.bignum). SUBSTRING (1, SUBSTRACTPN (bigtwo.bignum). Length ());} else {returnnum = "-" + SUBSTRACTPN (Bigtwo.bignum);}} return new Mybiginteger (Returnnum);} 

Multiplication:

The arithmetic idea of multiplication is simple. I used the idea of a phase-by-multiply, that is, two-digit subscript and the same number multiplied after the addition. Then the final and as a result to the corresponding number of digits. i.e. ∑ai (I bit of a) *bz-i (z-i bit of b) = Cz

If the CZ is greater than 10, it retains its single digit and carries it to cz+1, and the number of digits in the CZ is more than 10 digits, for example cz=123, then 12.

Public Mybiginteger Multiply (Mybiginteger bigtwo) {String Returnnum=null;boolean positive = false;if (big Two.bignum.charAt (0) = = '-' && this.bignum.charAt (0) = = '-') | | (! (bigtwo.bignum.charAt (0) = = '-') &&! (this.bignum.charAt (0) = = '-'))) {positive = true;} if (bigtwo.bignum.charAt (0) = = '-') {bigtwo.bignum = bigtwo.bignum.substring (1);} if (this.bignum.charAt (0) = = '-') {This.bignum =this.bignum.substring (1);} int a = This.bignum.length (); int b = Bigtwo.bignum.length (); string[] S1 = new String[a]; string[] s2 = new string[b];int[] Mulall = new Int[a + b-1];for (int i = 0; i < A; i++) {s1[a-i-1] = This.bignum. SUBSTRING (i, i + 1);} for (int i = 0; i < b; i++) {s2[b-i-1] = bigtwo.bignum.substring (i, i + 1);} if (a < b) {int temp = A;a = B;b = temp; string[] Stemp = S1;S1 = S2;s2 = stemp;} for (int i = 0, i < A; i++) {for (int j = 0; J < b; j + +) {mulall[i + j] +=integer.parseint (S1[i]) * Integer.parseint (S2[j]);}} for (int i = 0; i < muLall.length-1; i++) {if (Mulall[i] > 9) {while (Mulall[i] > 9) {mulall[i]-=10;mulall[i + 1] + = 1;}} Returnnum = ""; for (int i = mulall.length-1; I >= 0; i--) {returnnum = Returnnum + mulall[i];} if (positive) {return new MyBigInteger2 (Returnnum),} else {returnnum = "-" + Returnnum;return new Mybiginteger (Returnnum); }}

Little brother, above is I based on a large number of processing ideas written out of the code, which need to optimize a lot of places, need to constantly modify.

Implementation of large integer arithmetic based on Java (addition, subtraction, multiplication) Learning notes

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.