トピック
コンピューターの浮動小数点表現は「不正確」であるため、正確な操作が必要なシナリオ (バンキングなど) では使用できません。小数の整数部分と小数部分が文字列に格納され、算術計算中に整数部分と小数部分が別々に計算される場合 (および整数部分への小数の桁上げが考慮される場合)、正確な小数クラスは次のようになります。気がついた。クラスの属性とメソッドの設計は、Java の BigDecimal クラスを参照できます。
概念
Javaの宿題です. 本来は文字列を使ってシミュレーションしたかったのですが, 無限精度の10進数クラスを実現し, 文字列の操作を避けるために, 追加しやすい Int 型の List を使ってシミュレーションすることにしました.
掛け算と割り算の部分はとても複雑で怠け者で、この宿題はそれほど大きくないので、足し算と引き算だけを書きました. 興味がある場合は、掛け算と割り算を足し算と引き算と同じように書くことができます.
アイデアを説明する
ひとまずその話はしませんが、この二日間はかなり忙しく、コードもさほど複雑ではなく( のはずです)、暇なときに埋めるか、必要があれば (おそらく時間がある場合に記入できない場合は、すべての質問を以下に尋ねます。説明を完成させてから返信します)。
コード部分
package Matrix;
import java.util.ArrayList;
import java.util.List;
public class Exactdecimal {
private boolean minus=false;
private List<Integer> leftValue=new ArrayList<Integer>();
private List<Integer> rightValue=new ArrayList<Integer>();
private static int ten=10;
//构造函数
public Exactdecimal(String value)
{
int record=0;
String[] ipt=value.split("\\.");
char[]leftData =ipt[0].toCharArray();
if(leftData[0]=='-')
{
minus=true;
record=1;
}
for (int i=leftData.length-1;i>=record;i--)
{
var currentData= String.valueOf(leftData[i]);
leftValue.add(Integer.parseInt(currentData));
}
if(ipt.length>=2)
{
char[] rightData = ipt[1].toCharArray();
for (int i = 0; i < rightData.length; i++)
{
var currentData = String.valueOf(rightData[i]);
rightValue.add(Integer.parseInt(currentData));
}
}
}
//数加
private Exactdecimal NumAdd(Exactdecimal tmain, Exactdecimal other)
{
int i=0;
//TODO:位加
while (tmain.leftValue.size()>i||other.leftValue.size()>i)
{
if(tmain.leftValue.size()>i)
{
if(other.leftValue.size()>i)
tmain.leftValue.set(i,tmain.leftValue.get(i)+other.leftValue.get(i));
}
else tmain.leftValue.add(other.leftValue.get(i));
i++;
}
i=0;
while (tmain.rightValue.size()>i||other.rightValue.size()>i)
{
if(tmain.rightValue.size()>i)
{
if(other.rightValue.size()>i)
tmain.rightValue.set(i,tmain.rightValue.get(i)+other.rightValue.get(i));
}
else tmain.rightValue.add(other.rightValue.get(i));
i++;
}
//TODO:进位
for(i=tmain.rightValue.size()-1;i>=0;i--)
{
if(i!=0)
tmain.rightValue.set(i-1,(tmain.rightValue.get(i)/ten)+tmain.rightValue.get(i-1));
else
tmain.leftValue.set(0,(tmain.rightValue.get(i)/ten)+tmain.leftValue.get(0));
tmain.rightValue.set(i,tmain.rightValue.get(i)%ten);
}
for (i=0;i<tmain.leftValue.size();i++)
{
if(i+1<tmain.leftValue.size())
tmain.leftValue.set(i+1,(tmain.leftValue.get(i)/ten)+tmain.leftValue.get(i+1));
else
if((tmain.leftValue.get(i) / ten)>0)tmain.leftValue.add(tmain.leftValue.get(i)/ten);
tmain.leftValue.set(i,tmain.leftValue.get(i)%ten);
}
return this;
}
//数减
private Exactdecimal NumSubtract(Exactdecimal tmain,Exactdecimal other)//大数在前
{
//TODO:零的同步
while (true)
{
if(tmain.rightValue.size()>=other.rightValue.size())
break;
tmain.rightValue.add(0);
}
while (true)
{
if(tmain.rightValue.size()<=other.rightValue.size())
break;
other.rightValue.add(0);
}
//TODO:位减
for (int i=0;i<tmain.rightValue.size();i++)
{
tmain.rightValue.set(i,tmain.rightValue.get(i)-other.rightValue.get(i));
}
for (int i=0;i<tmain.leftValue.size();i++)
{
if(other.leftValue.size()-1>=i)
tmain.leftValue.set(i,tmain.leftValue.get(i)-other.leftValue.get(i));
}
//TODO:进位
for (int i=tmain.rightValue.size()-1;i>=0;i--)
{
if(tmain.rightValue.get(i)<0)
{
if(i==0)
{
tmain.leftValue.set(0,tmain.leftValue.get(0)-1);
tmain.rightValue.set(i,10+tmain.rightValue.get(i));
break;
}
tmain.rightValue.set(i-1,tmain.rightValue.get(i-1)-1);
tmain.rightValue.set(i,10+tmain.rightValue.get(i));
}
}
for (int i=0;i<tmain.leftValue.size();i++)
{
if(tmain.leftValue.get(i)<0)
{
tmain.leftValue.set(i + 1, tmain.leftValue.get(i + 1) - 1);
tmain.leftValue.set(i, 10 - tmain.leftValue.get(i));
}
}
//TODO:去零
int i=tmain.leftValue.size()-1;
if(i!=0)
{
while (tmain.leftValue.get(i)==0&&i!=0)
{
tmain.leftValue.remove(i);
i--;
}
}
return tmain;
}
//减法
public Exactdecimal Subtract(Exactdecimal other)
{
Exactdecimal resultofthis = null;
int state=ThisIsBigThenOther(other);
if (!this.minus && other.minus || !other.minus && this.minus)
{
resultofthis= NumAdd(this,other);
if(!other.minus)
resultofthis.minus = true;
}
else {
switch (state)
{
case 1:
resultofthis = NumSubtract(this,other);
break;
case -1:
resultofthis = NumSubtract(other,this);
resultofthis.minus=true;
break;
case 0:
resultofthis = new Exactdecimal("0.0");
break;
}
if(this.minus)
resultofthis.minus=!resultofthis.minus;;
}
return resultofthis;
}
//加法
public Exactdecimal Add(Exactdecimal other)
{
Exactdecimal resultofthis = null;
if (!this.minus && other.minus || !other.minus && this.minus)
{
int state=ThisIsBigThenOther(other);
switch (state)
{
case 1:
resultofthis = NumSubtract(this,other);
break;
case -1:
resultofthis = NumSubtract(other,this);
resultofthis.minus=true;
break;
case 0:
resultofthis = new Exactdecimal("0.0");
break;
}
if(this.minus)
resultofthis.minus=!resultofthis.minus;;
}
else {
resultofthis= NumAdd(this,other);
if(!other.minus)
resultofthis.minus = true;
}
return resultofthis;
}
//输出
public void ShowData()
{
if(this.minus==true)
System.out.print("-");
for (int i=leftValue.size()-1;i>=0;i--)
{
System.out.print(leftValue.get(i));
}
System.out.print(".");
for (int i=0;i<rightValue.size();i++)
{
System.out.print(rightValue.get(i));
}
}
//当前数是否大于另一个
private int ThisIsBigThenOther(Exactdecimal other)
{
if(this.leftValue.size()>other.leftValue.size())
{
return 1;
}else if(this.leftValue.size()<other.leftValue.size())
{
return -1;
}
for (int i=this.leftValue.size()-1;i>=0;i--)
{
if(this.leftValue.get(i)>other.leftValue.get(i))
{
return 1;
}
else if(this.leftValue.get(i)<other.leftValue.get(i))
{
return -1;
}
}
if(this.rightValue.size()>other.rightValue.size())
{
return 1;
}else if(this.rightValue.size()<other.rightValue.size())
{
return -1;
}else
{
for(int i=0;i<this.rightValue.size();i++)
{
if(this.rightValue.get(i)>other.rightValue.get(i))
{
return 1;
}
else if(this.rightValue.get(i)<other.rightValue.get(i))
{
return -1;
}
}
return 0;
}
}
public static String reverseTestOne(String s)
{
return new StringBuffer(s).reverse().toString();
}
}