大数乗算、大数加算、大数減算Javaバージョン
2つの非常に大きい数字の掛け算(加算、減算)
この問題はjavaでBigIntegerクラスのメソッドを用いて実現できる.そうでなければ、以下のように実現することができる.
大数乗算:AとBの2つの大数があると仮定し、桁数はそれぞれaとbである.通常、手動で乗算を計算する方法から、最終的な結果のビット数cはa+b以下であることがわかり、99*999=98901の簡単な例を挙げて説明することができ、最終的な結果は5ビット(a+b)である.次は98*765に基づいて = 74970結果の各ビットがどのように得られたのかを見てみましょう.最後のビット0はAの最後のビット8とBの最後のビット5の乗機が10を除いて得られたものです.結果の最下位2位7は、Aの最下位2位9とBの最下位5との積45とAの最下位8とBの最下位2位6との積48の和93と、上から1位の進位4を加えて97を得、10を除いて残りを取った7・・・の順に進めば最終結果が得られる.
次に、Aのi位とBのj位の積が最終的に結果のi+j位に格納される(iとjはいずれも後から前へ)ので、結果の各位の計算を先に行い、すべての計算を完了してから進位の計算を行うことができます.iとjを0から計算するには,まず文字列AとBを逆転し,計算を行うときに0から開始する.具体的な手順は以下の通りです.
大数加算:乗算と同様で、異なる点はresult結果セットの長さであり、その値は長い文字列の長さに1を加算します.具体的なコードは以下の通りです.
大数の減算:
大数の減算は大数の加算と似ていますが、正負を判断する必要があります.
上記の各計算では、大数加算の際に数字の正負を判断せず、いずれも正数であれば正数加算で計算でき、正負であれば大整数減算に変換でき、2つの負数は記号を保存して加算することができる.
この問題はjavaでBigIntegerクラスのメソッドを用いて実現できる.そうでなければ、以下のように実現することができる.
大数乗算:AとBの2つの大数があると仮定し、桁数はそれぞれaとbである.通常、手動で乗算を計算する方法から、最終的な結果のビット数cはa+b以下であることがわかり、99*999=98901の簡単な例を挙げて説明することができ、最終的な結果は5ビット(a+b)である.次は98*765に基づいて = 74970結果の各ビットがどのように得られたのかを見てみましょう.最後のビット0はAの最後のビット8とBの最後のビット5の乗機が10を除いて得られたものです.結果の最下位2位7は、Aの最下位2位9とBの最下位5との積45とAの最下位8とBの最下位2位6との積48の和93と、上から1位の進位4を加えて97を得、10を除いて残りを取った7・・・の順に進めば最終結果が得られる.
次に、Aのi位とBのj位の積が最終的に結果のi+j位に格納される(iとjはいずれも後から前へ)ので、結果の各位の計算を先に行い、すべての計算を完了してから進位の計算を行うことができます.iとjを0から計算するには,まず文字列AとBを逆転し,計算を行うときに0から開始する.具体的な手順は以下の通りです.
public static void bigNumberSimpleMulti(String f, String s) {
System.out.print(" :
" + f + "*" + s + "=");
// ,
char signA = f.charAt(0);
char signB = s.charAt(0);
char sign = '+';
if (signA == '+' || signA == '-') {
sign = signA;
f = f.substring(1);
}
if (signB == '+' || signB == '-') {
if (sign == signB) {
sign = '+';
} else {
sign = '-';
}
s = s.substring(1);
}
//
char[] a = new StringBuffer(f).reverse().toString().toCharArray();
char[] b = new StringBuffer(s).reverse().toString().toCharArray();
int lenA = a.length;
int lenB = b.length;
//
int len = lenA + lenB;
int[] result = new int[len];
//
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < b.length; j++) {
result[i + j] += (int) (a[i] - '0') * (int) (b[j] - '0');
}
}
// , 10 , 10
for (int i = 0; i < result.length; i++) {
if (result[i] > 10) {
result[i + 1] += result[i] / 10;
result[i] %= 10;
}
}
StringBuffer sb = new StringBuffer();
// 0, 0
boolean flag = true;
for (int i = len - 1; i >= 0; i--) {
if (result[i] == 0 && flag) {
continue;
} else {
flag = false;
}
sb.append(result[i]);
}
if (!sb.toString().equals("")) {
if (sign == '-') {
sb.insert(0, sign);
}
} else {
sb.append(0);
}
//
System.out.println(sb.toString());
}
大数加算:乗算と同様で、異なる点はresult結果セットの長さであり、その値は長い文字列の長さに1を加算します.具体的なコードは以下の通りです.
public String bigNumberAdd(String f, String s) {
// ,
char[] a = new StringBuffer(f).reverse().toString().toCharArray();
char[] b = new StringBuffer(s).reverse().toString().toCharArray();
int lenA = a.length;
int lenB = b.length;
//
int len = lenA > lenB ? lenA : lenB;
int[] result = new int[len + 1];
for (int i = 0; i < len + 1; i++) {
// i , 0 ,
int aint = i < lenA ? (a[i] - '0') : 0;
int bint = i < lenB ? (b[i] - '0') : 0;
result[i] = aint + bint;
}
// , 10 , 10
for (int i = 0; i < result.length; i++) {
if (result[i] > 10) {
result[i + 1] += result[i] / 10;
result[i] %= 10;
}
}
StringBuffer sb = new StringBuffer();
// 0,
boolean flag = true;
for (int i = len; i >= 0; i--) {
if (result[i] == 0 && flag) {
continue;
} else {
flag = false;
}
sb.append(result[i]);
}
return sb.toString();
}
大数の減算:
大数の減算は大数の加算と似ていますが、正負を判断する必要があります.
public static String bigNumberSub(String f, String s) {
System.out.print(" :" + f + "-" + s + "=");
//
char[] a = new StringBuffer(f).reverse().toString().toCharArray();
char[] b = new StringBuffer(s).reverse().toString().toCharArray();
int lenA = a.length;
int lenB = b.length;
//
int len = lenA > lenB ? lenA : lenB;
int[] result = new int[len];
//
char sign = '+';
//
if (lenA < lenB) {
sign = '-';
} else if (lenA == lenB) {
int i = lenA - 1;
while (i > 0 && a[i] == b[i]) {
i--;
}
if (a[i] < b[i]) {
sign = '-';
}
}
// , , a-b b-a
for (int i = 0; i < len; i++) {
int aint = i < lenA ? (a[i] - '0') : 0;
int bint = i < lenB ? (b[i] - '0') : 0;
if (sign == '+') {
result[i] = aint - bint;
} else {
result[i] = bint - aint;
}
}
// , , 10。
for (int i = 0; i < result.length - 1; i++) {
if (result[i] < 0) {
result[i + 1] -= 1;
result[i] += 10;
}
}
StringBuffer sb = new StringBuffer();
// , ,
if (sign == '-') {
sb.append('-');
}
// 0
boolean flag = true;
for (int i = len - 1; i >= 0; i--) {
if (result[i] == 0 && flag) {
continue;
} else {
flag = false;
}
sb.append(result[i]);
}
// , , 0
if (sb.toString().equals("")) {
sb.append("0");
}
//
System.out.println(sb.toString());
return sb.toString();
}
上記の各計算では、大数加算の際に数字の正負を判断せず、いずれも正数であれば正数加算で計算でき、正負であれば大整数減算に変換でき、2つの負数は記号を保存して加算することができる.