我怕不是用了假的Markdown哦......算了不管了。
Kevin_K edited 6 年,7 月前
渣渣我曾经励志与高精度拼了,我今天就来证明一下本渣已经迈出了关键的一小步~~(其实是因为XXXX的Java作业才写的)~~。为了方便打包使用,使用Java编写。~~(我实在是编不下去了233)~~
祖传源代码:
package BigInt;
import java.util.*;
public final class BigInt{
//变量
private boolean neg=false;
private ArrayList<Integer> num=new ArrayList<Integer>();
//构造
public BigInt(){
num.add(0);
}
public BigInt(String s){
neg=reading(s,num);
if (num.size()==1&&num.get(0)==0){
neg=false;
}
}
//性质
public int length(){
return num.size();
}
public boolean negative(){
return neg;
}
//辅助
private void leadingZeroSuppress(ArrayList<Integer> x){
for (int i=x.size()-1;i>0;i--){
if (x.get(i)!=0){
return;
}
x.remove(i);
}
}
private void leadingZeroAdd(ArrayList<Integer> x,int y){
for (int i=0;i<y;i++){
x.add(0);
}
}
private boolean reading(String x,ArrayList<Integer> y){
boolean z=false;
y.clear();
int end=0;
if (x.charAt(0)=='-'){
end=1;
z=true;
}
for (int i=x.length()-1;i>=end;i--){
y.add((int)x.charAt(i)-(int)'0');
}
leadingZeroSuppress(y);
return z;
}
private ArrayList<Integer> copyList(ArrayList<Integer> x){
ArrayList<Integer> y=new ArrayList<Integer>();
for (int i=0;i<x.size();i++){
y.add(x.get(i));
}
return y;
}
private void multiplyTen(ArrayList<Integer> x,int y){
for (int i=0;i<y;i++){
x.add(0,0);
}
}
private ArrayList<Integer> multiplyBasic(ArrayList<Integer> x,int y){
int temp=0,p=0;
ArrayList<Integer> res=new ArrayList<Integer>();
leadingZeroAdd(x,1);
leadingZeroAdd(res,x.size());
for (int i=0;i<x.size();i++){
p=x.get(i)*y+temp;
res.set(i,p%10);
temp=(p-p%10)/10;
}
leadingZeroSuppress(x);
leadingZeroSuppress(res);
return res;
}
private BigInt divideBasicAbs(BigInt x){
ArrayList<Integer> tnum=new ArrayList<Integer>();
ArrayList<Integer> res=new ArrayList<Integer>();
boolean tneg=reading(x.toString(),tnum);
ArrayList<BigInt> group=new ArrayList<BigInt>();
BigInt ten=new BigInt("10");
for (int i=1;i<=10;i++){
BigInt temp=new BigInt(String.valueOf(i));
temp=temp.multiply(x);
BigInt tem=new BigInt(temp.toStringAbs());
group.add(tem);
}
BigInt abs=new BigInt(toStringAbs());
for (int i=abs.length()-1;i>=0;i--){
BigInt comp=new BigInt(abs.toStringHigherPartAbs(i));
for (int j=0;j<10;j++){
if (group.get(j).compareAbs(comp)>0){
res.add(0,j);
if (j==0){
break;
}
comp=group.get(j-1);
for (int k=0;k<i;k++){
comp=comp.multiply(ten);
}
abs=abs.subtract(comp);
break;
}
}
}
leadingZeroSuppress(res);
BigInt ans=new BigInt(toStringAbs(res));
return ans;
}
//输出
private String toStringAbs(ArrayList<Integer> x){
String res="";
for (int i=x.size()-1;i>=0;i--){
res+=String.valueOf(x.get(i));
}
return res;
}
private String toString(ArrayList<Integer> x,boolean y){
if (y==true){
return "-"+toStringAbs(x);
}
return toStringAbs(x);
}
private String toStringOpposite(ArrayList<Integer> x,boolean y){
if (y==true){
return toString(x,false);
}
return toString(x,true);
}
private String toStringHigherPartAbs(ArrayList<Integer> x,int y){
ArrayList<Integer> temp=new ArrayList<Integer>();
leadingZeroSuppress(x);
if (y<0){
y=0;
}
if (y>=x.size()){
temp.add(0);
}
for (int i=y;i<x.size();i++){
temp.add(x.get(i));
}
return toStringAbs(temp);
}
public String toStringAbs(){
return toStringAbs(num);
}
public String toString(){
return toString(num,neg);
}
public String toStringOpposite(){
return toStringOpposite(num,neg);
}
public String toStringHigherPartAbs(int x){
return toStringHigherPartAbs(num,x);
}
//比较
public boolean equals(BigInt x){
if (toString().equals(x.toString())){
return true;
}
return false;
}
public int compareAbs(BigInt x){
boolean cneg=false;
ArrayList<Integer> cnum=new ArrayList<Integer>();
cneg=reading(x.toStringAbs(),cnum);
int l=Math.max(num.size(),cnum.size());
leadingZeroAdd(num,l-num.size());
leadingZeroAdd(cnum,l-cnum.size());
int jud=toStringAbs(num).compareTo(toStringAbs(cnum));
leadingZeroSuppress(num);
if (jud>0){
return 1;
}
if (jud<0){
return -1;
}
return 0;
}
public int compare(BigInt x){
if (neg!=x.negative()){
if (neg){
return -1;
}
return 1;
}
if (neg){
return -compareAbs(x);
}
return compareAbs(x);
}
//运算
public BigInt add(BigInt x){
ArrayList<Integer> tnum=new ArrayList<Integer>();
boolean tneg=reading(x.toString(),tnum);
int temp=0;
if (neg==tneg){
temp=0;
int l=Math.max(tnum.size(),num.size())+1;
leadingZeroAdd(num,l-num.size());
leadingZeroAdd(tnum,l-tnum.size());
for (int i=0;i<l;i++){
int p=tnum.get(i)+num.get(i)+temp;
tnum.set(i,p%10);
temp=(p-tnum.get(i))/10;
}
leadingZeroSuppress(num);
leadingZeroSuppress(tnum);
BigInt res=new BigInt(toString(tnum,tneg));
tnum.clear();
tneg=false;
return res;
}
if (compareAbs(x)==0){
BigInt res=new BigInt();
tnum.clear();
tneg=false;
return res;
}
boolean bneg,sneg;
ArrayList<Integer> bnum=new ArrayList<Integer>();
ArrayList<Integer> snum=new ArrayList<Integer>();
if (compareAbs(x)==1){
bnum=copyList(num);
snum=copyList(tnum);
bneg=neg;
sneg=tneg;
}
else{
snum=copyList(num);
bnum=copyList(tnum);
bneg=tneg;
sneg=neg;
}
temp=0;
leadingZeroAdd(snum,bnum.size()-snum.size());
for (int i=0;i<bnum.size();i++){
int bit=bnum.get(i)-snum.get(i)-temp;
if (bit<0){
temp=1;
bit+=10;
}
else{
temp=0;
}
bnum.set(i,bit);
}
temp=0;
tnum.clear();
snum.clear();
tneg=false;
sneg=false;
leadingZeroSuppress(bnum);
if (bneg==true){
BigInt res=new BigInt("-"+toStringAbs(bnum));
bneg=false;
bnum.clear();
return res;
}
BigInt res=new BigInt(toStringAbs(bnum));
bneg=false;
bnum.clear();
return res;
}
public BigInt subtract(BigInt x){
BigInt res=new BigInt(x.toStringOpposite());
return add(res);
}
public BigInt multiply(BigInt x){
ArrayList<Integer> tnum=new ArrayList<Integer>();
boolean tneg=reading(x.toString(),tnum);
if (neg==tneg){
tneg=false;
}
else{
tneg=true;
}
BigInt res=new BigInt();
for(int i=0;i<num.size();i++){
ArrayList<Integer> temp=new ArrayList<Integer>();
temp=multiplyBasic(tnum,num.get(i));
multiplyTen(temp,i);
BigInt part=new BigInt(toStringAbs(temp));
res=res.add(part);
}
if (tneg){
BigInt resReal=new BigInt(res.toStringOpposite());
return resReal;
}
return res;
}
public BigInt divide(BigInt x){
if (x.negative()==neg){
return divideBasicAbs(x);
}
BigInt res=new BigInt(divideBasicAbs(x).toStringOpposite());
return res;
}
public BigInt mod(BigInt x){
BigInt y=new BigInt(toString());
return y.subtract(x.multiply(y.divide(x)));
}
public BigInt absFact(){
BigInt i=new BigInt(toStringAbs());
BigInt unit=new BigInt("1");
BigInt res=new BigInt("1");
while (!i.equals(unit)){
res=res.multiply(i);
i=i.subtract(unit);
}
return res;
}
public BigInt intPowAbs(int x){
if (x<0){
x=-x;
}
BigInt res=new BigInt("1");
BigInt unit=new BigInt(toString());
for (int i=0;i<x;i++){
res=res.multiply(unit);
}
return res;
}
}
完成及初步检查完成时间:2018年4月21日15:56:48。
现在看起来那时候还是太年轻了,写的冗长又低效,但是即使现在让我重写,我大概也只能写的不怎么冗长,所以就没有改动。~~(其实是我懒啦!几百行的代码改起来超级累的呢!)~~
包含的API(懒得写,自己过去看吧,虽然还实现了一些杂七杂八的API~~(其实你可以当彩蛋看QwQ)~~,但核心就这些了)。
与Java自带的长整数类BigInteger的性能差异大概长这样:
如你所见,粗略估计比BigInteger快了十倍不止,恐怖如斯!
(其实我也很绝望的啊T_T)
注:
1.求大佬不要笑话和嘲讽,本渣的小心脏会受不了的。
2.其实本文还有个起誓的作用:我Kevin_K就是WA、RE、CE,也不会再用Java刷OJ了!(Java,与我ArrayList,降我模力,使我无故TLE,非英雄也!)
3.祝God West明天码运昌隆,AK全场!
轩爷牛逼!