Exponentiation

//Main.java
//compute the exact value of R^n,0.0<R<99.999,0<n<=25
//100000^25是126位数,所以本题数组长度设为125
import java.util.Scanner;

class BigDecimal implements Cloneable{
//涉及到自己乘自己,不希望重复构建,所以用到Cloneable
	public int[] number=new int[125];
	public int length=0;
	public int precision=0;//小数点位数,可为负,比如10(-1)
	private int[] temp=new int[125];//为方便运算而设置的
	//以12.0为例,number为21,length为2,precision为0
	
	public BigDecimal(String str){
	//构造函数,输入为浮点字符串例如 1.230
	//构造的思路为:找到有效左右边界,小数点位置,算出小数点位数
		int lpos=0,rpos=0,ppos=0;
		for(int i=0;i<=str.length()-1;i++){
			if(str.charAt(i)!='0'&&str.charAt(i)!='.'){
				lpos=i;
				break;
			}
		}
		for(int i=str.length()-1;i>=0;i--){
			if(str.charAt(i)!='0'&&str.charAt(i)!='.'){
				rpos=i;
				break;
			}
		}
		ppos=str.indexOf('.');
		
		for(int i=rpos;i>=lpos;i--){
			if(str.charAt(i)=='.')continue;//小数点在中间的情况
			number[length]=str.charAt(i)-'0';
			length++;
		}
		
		if(rpos>ppos)precision=rpos-ppos;//比如1.1
		else precision=rpos-ppos+1;//比如1.0,10.0
		
	}
	
	public void Multiply(BigDecimal x){
		
		for(int i=0;i<=temp.length-1;i++)temp[i]=0;
		//将结果数组全部置为0
		
		for(int i=0;i<=length-1;i++){
			for(int j=0;j<=x.length-1;j++){
				temp[i+j]+=number[i]*x.number[j];
			}
		}//比如0.12*0.12,运算时为21*21,结果为:4,2+2,1
		length+=x.length-1;//长度为m和n的数相乘,不进位则m+n
		precision+=x.precision;

		for(int i=0;i<=length-1;i++){
			temp[i+1]+=temp[i]/10;
			temp[i]=temp[i]%10;
		}//对结果进行进位
		
		if(temp[length]!=0)length++;
		
		int[] t=temp;
		temp=number;
		number=t;
		//调换number和temp位置
		//temp不建议采用局部变量
	}
	
	public void Print(){
		//分类1.1,0.1,1.0,10.0
		if(precision>=length){
			System.out.print('.');
			for(int i=precision-1;i>=0;i--){
				System.out.print(number[i]);
			}
			System.out.println();
		}
		else if(precision<=0){
			for(int i=length-1;i>=0;i--){
				System.out.print(number[i]);
			}
			for(int i=-1;i>=precision;i--){
				System.out.print('0');
			}
			System.out.println();
		}
		else{
			for(int i=length-1;i>=0;i--){
				System.out.print(number[i]);
				if(i==precision)System.out.print('.');
			}
			System.out.println();
		}
	}
	public BigDecimal clone(){
		BigDecimal o=null;
		//浅复制
		try{
			o=(BigDecimal)super.clone();
		}catch(CloneNotSupportedException e){
			e.printStackTrace();
		}
		//深复制
		o.number=number.clone();
		o.temp=temp.clone();
		return o;	
	}
}
public class Main{

	public static void main(String[] args){
		
		Scanner cin=new Scanner(System.in);
		String r=null; 
		int n=0;

		while(cin.hasNextLine())
		{
			r=cin.next();
			BigDecimal bd=new BigDecimal(r);
			n=cin.nextInt();
			BigDecimal bd2=bd.clone();
			//由于是幂,得设置俩BigDecimal;
			//再构建一次时间开销太大,最好用clone
			//注意理解clone()中的浅复制,深复制
			
			for(int i=1;i<=n-1;i++){
			//这里为什么是n-1,一次幂不做任何运算的
				bd.Multiply(bd2);
			}

			bd.Print();
		}
		cin.close();
	}
}

猜你喜欢

转载自hfn.iteye.com/blog/2309083