Simulate exact decimal class in JAVA using List (incomplete)
topic
Due to the "inaccuracy" of floating-point representation in computers, it cannot be used in scenarios that require precise operations (such as banking). If the integer part and fractional part of the decimal are stored in strings, and the integer part and the decimal part are calculated separately during arithmetic calculations (and the carry of the decimal to the integer part is considered), the precise decimal class can be realized. The attribute and method design of the class can refer to Java's BigDecimal class.
conception
This is a Java homework. I originally wanted to use strings for simulation. However, in order to realize the infinite precision decimal class and avoid the operation of strings, I chose to use an easy-to-add Int type List for simulation.
Because the multiplication and division part is really complicated, I am lazy, and this homework is not that big, so I only wrote addition and subtraction. If you are interested, you can write multiplication and division in a similar way to addition and subtraction.
Explain ideas
I will not talk about it for the time being, these two days are quite busy, and the code is not very complicated ( should be ), I will fill it up when I am free, or if there is a need ( it is probably impossible to fill in if there is time, all questions are asked below, I will Complete the explanation and then reply to yours ).
code part
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();
}
}