大数相关poj1001

// go.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <sstream>
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<algorithm>
using namespace std;


//const  long base = 10000;

class BigInteger
{
public:
	BigInteger()
	{
		memset(m_arrA,0,sizeof(m_arrA));
		m_arrA[0] = 0; m_iLength = 0;
	}
	BigInteger(int num)//构造函数
	{
		int i = 0;
		memset(m_arrA,0,sizeof(m_arrA));
		while(num)
		{
			m_arrA[i] = num%base;
			i ++;
			num/=base;
		}
		m_iLength = i;
	}
	void operator+=(BigInteger x)
	{
		long t = 0;
		m_iLength = max(m_iLength, x.m_iLength) + 5;
		for(int i=0;i<m_iLength;i++)
		{
			m_arrA[i] += x.m_arrA[i] + t;
			if(m_arrA[i] >= base) m_arrA[i] -= base, t = 1;
			else t = 0;
		}
		m_iLength = 599; while(m_arrA[m_iLength]==0 && m_iLength>0) m_iLength--;
		assert(m_arrA[599]==0);
	}
	void operator-=(BigInteger x)
	{
		long t = 0;
		m_iLength = max(m_iLength, x.m_iLength) + 5;
		for(int i=0;i<m_iLength;i++)
		{
			m_arrA[i] -= x.m_arrA[i] - t;
			if(m_arrA[i] < 0) m_arrA[i] += base, t = 1;
			else t = 0;
		}
		m_iLength = 599; while(m_arrA[m_iLength]==0 && m_iLength>0) m_iLength--;
		assert(m_arrA[599]==0);
	}
	void operator*=(BigInteger x)
	{
		long res[600], t = 0;
		memset(res,0,sizeof(res));
		for(int i=0;i<=m_iLength;i++)
		{
			t = 0;
			for(int j=0;j<=x.m_iLength || t;j++)
			{
				res[i+j] += m_arrA[i] * x.m_arrA[j] + t;//这里会溢出 然后将base 减少至相乘也不会溢出的大小
				t = res[i+j] / base;
				res[i+j] %= base;
			}
		}
		memcpy(m_arrA,res,sizeof(res));
		m_iLength = 599; while(m_arrA[m_iLength]==0 && m_iLength>0) m_iLength--;
		assert(m_arrA[599]==0);
	}

	static void Power(BigInteger &x,int iPower,BigInteger &BigIntRes)
	{
		BigIntRes = 1;
		for (int i=0; i<iPower; i++)				//大数相乘
		{
			BigIntRes *= x;
		}
	}
public:
	long max(long a,long b)
	{
		return a>b?a:b;
	}
	string longToStr(long lVal)
	{
		stringstream sstream;
		sstream << lVal;
		string strRes = sstream.str();
		int iLength = strRes.length();
		switch(iLength)
		{
		case 0:
			return string("0000");
		case 1:
			return string("000") + strRes;
		case 2:
			return string("00") + strRes;
		case 3:
			return string("0") + strRes;
		case 4:
			return strRes;
		}
		return strRes;
	}
	void output()
	{
		int u = 599; while(m_arrA[u]==0 && u>0) u--;
		printf("%ld",m_arrA[u]); u--;
		while(u>=0) printf("%04ld",m_arrA[u]), u--;
		printf("\n");
	}
	void GetStrData(string &strSumData)
	{
		strSumData = "";							//大数的总和
		for (int i = m_iLength; i >= 0; i--)
		{
			strSumData += longToStr(m_arrA[i]);
		}
	}
public:
	long m_arrA[600];
	int m_iLength;
	enum m_eData{ base = 10000 };
};


int _tmain(int argc, _TCHAR* argv[])
{
	freopen("in.txt","r",stdin);
	freopen("out.txt","w",stdout);
	string	strMulData;								//乘数
	int		iPower;									//次幂
	while(cin >> strMulData >> iPower)
	{
		int iPosIndex	= strMulData.find(".");		//小数点位置
		int iPosCount	= ( strMulData.length() -1 - iPosIndex ) * iPower;		//结果总共有几位小数
		string strTempData;							//去除小数点后的整数
		
		strMulData.replace(iPosIndex,1,"");			//iPosIndex是小数点位置,把小数点替换为空


		BigInteger	kSumData = 1;
		BigInteger	kTempData = atol(strMulData.c_str());
		BigInteger::Power(kTempData,iPower,kSumData);

		string strSumData;									//大数的总和
		kSumData.GetStrData(strSumData);
		
		int iSunDataLength = strSumData.length();			//字符串中的字符长度
		if(iSunDataLength >= iPosCount)				
		{
			strSumData.insert(iSunDataLength-iPosCount,".");//插入小数点
		}
		else 
		{
			string strZoro=".";								//小数点后补零
			for (int i=0;i<iPosCount-iSunDataLength;i++)
			{
				strZoro += "0";
			}
			strSumData = strZoro + strSumData;
		}
		string strRes;
		int iBegin	= 0;
		int iEnd	= strSumData.length();
		for (int i=0; i<strSumData.length(); i++)			//去掉整数前的零
		{
			iBegin ++;
			if(strSumData[i] == '0') continue;
			else break;
		}
		iBegin--;
		for (int i = strSumData.length()-1; i >= iBegin; i--)//去小数尾部的零
		{
			if(strSumData[i] == '0') 
			{
				continue;
			}
			else  
			{
				if(strSumData[i] == '.')					//刚好是小数点
				{
					i--;
				}
				iEnd = i;
				break;
			}
		}
		strRes = strSumData.substr(iBegin,iEnd-iBegin+1);
		cout<<strRes<<endl;
		
	}

	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值