任意长度的高精度大整数和浮点数的加法和乘法

任意长度的高精度大整数和浮点数的加法和乘法

一. 任意长度的高精度大整数加法
方法:这里用了数据结构栈,实际上栈更方便实现高精度加法。

步骤:1、第一个数据加数按输入顺序(高位到低位)入栈1。此时栈顶为最低位

            2、‍第二个数据加数按输入顺序(高位到低位)入栈2。此时栈顶为最低位

            3、将栈1、栈2均pop出栈顶做加法,并考虑进位,结果入栈3,这时栈3正好是低位入栈。

            4、处理多余的栈1、栈2。

            5、直接pop出栈3,即正好的从高位到低位的结果。

#include "iostream"
#include "stack"
using namespace std;

stack<int>s1;
stack<int>s2;
stack<int>s3;
char c1[100];
char c2[100];

int main(void)
{
	printf("请输入第一个加数:");
	cin>>c1;
	printf("请输入第二个加数:");
	cin>>c2;
	int len1=strlen(c1);
	int len2=strlen(c2);
	for(int i=0;i<len1;i++)
	{
		s1.push(c1[i]-'0');            //按输入顺序(高位到低位)入栈1,此时栈顶为最低位
	}
	for(int i=0;i<len2;i++)
	{
		s2.push(c2[i]-'0');            //按输入顺序(高位到低位)入栈2,此时栈顶为最低位
	}

	int tmp=0;
	while(!s1.empty() && !s2.empty())
	{
		tmp += s1.top()+s2.top();   // 将栈1、栈2均pop出栈顶做加法,并考虑进位,结果入栈3,这时栈3正好是低位入栈
		s1.pop();
		s2.pop();
		s3.push(tmp%10);
		tmp = tmp/10;
	}
	while(!s1.empty())   //处理多余的栈1
	{
		tmp += s1.top();
		s1.pop();
		s3.push(tmp%10);
		tmp = tmp/10;
	}
	while(!s2.empty())   //处理多余的栈2
	{
		tmp += s2.top();
		s2.pop();
		s3.push(tmp%10);
		tmp = tmp/10;
	}
	if(tmp)        //处理多余的进位
	{
		s3.push(tmp);
	}

	printf("两个数相加的结果为:");
	while(!s3.empty())    //直接pop出栈3,即正好的从高位到低位的结果
	{
		cout<<s3.top();
		s3.pop();
	}
	cout<<endl;
	system("pause");
	return 0;
}

二. 任意长度的高精度大整数乘法
#include "iostream"
#include "string"
using namespace std;
int main(void)
{
	char str1[1000],str2[1000];
	int i,j,len1,len2,len;
	bool flag=false;
	cout<<"任意两个大数的乘法(用数组来模拟小学三年级的乘法竖式计算过程):"<<endl;
	cout<<"请输入被乘数:";
	gets(str1);
	cout<<"请输入乘数:";
	gets(str2);
	len1=strlen(str1);
	len2=strlen(str2);
	int *a=new int[len1];
	int *b=new int[len2];
	len=len1*len2+1;
	int *result= new int[len];
	for(i=0;i<len;i++)
		result[i]=0;
	for(i=0;i<len1;i++) //将字符串转换为整数,并倒置过来
		a[i]=str1[len1-1-i]-'0';
	for(i=0;i<len2;i++)
		b[i]=str2[len2-1-i]-'0';
	for(i=0;i<len1;i++)  //用数组来模拟小学三年级的乘法竖式计算过程
	{
		for(j=0;j<len2;j++)
			result[i+j]+=a[i]*b[j];
	}
	for(i=0;i<len;i++)   //处理进位的情况
	{
		if(result[i]>9)
		{
			result[i+1]+=result[i]/10;
			result[i]%=10;
		}
	}
	cout<<"两个大整数相乘的结果为:";
	for(i=len-1;i>=0;i--)
	{
		if(flag)
			cout<<result[i];
		else if(result[i]!=0)
		{
			cout<<result[i];
			flag=true;
		}
	}
	cout<<endl;
	delete []a;
	delete []b;
	delete []result;
	system("pause");
	return 0;
}

三. 两个数相加,小数点后位数没有限制,请写一个高精度算法
public class test 

{

    private static String addFloatNum(String num1, String num2)

    {//两个浮点大数相加,小数点位数任意

        String result = "";

        int pos1,pos2,len1,len2;

        len1 = num1.length();

        len2 = num2.length();

        pos1 = num1.indexOf('.');

        pos2 = num2.indexOf('.');

        //分别剥离两个数的整数和小数部分

        String num1a = num1.substring(0, pos1);

        String num1b = num1.substring(pos1+1, len1);

        String num2a = num2.substring(0, pos2);

        String num2b = num2.substring(pos2+1, len2);

        //整数部分相加

        String rsOne = add(num1a, num2a);

        //小数位对齐,不足的补0

        int i,nZeroes,maxLen;

        maxLen = (num1b.length()>num2b.length()) ? num1b.length() : num2b.length();

        if (num1b.length()>num2b.length()) 

        {//第一个数的小数部分长,则第二个补不足的0

            nZeroes = num1b.length() - num2b.length();//待补的0的个数

            for (i = 0; i < nZeroes; ++i)

            {

                num2b += '0';

            }

        }

        else if(num2b.length() > num1b.length())

        {//第二个数的小数部分长,则第一个补不足的0

            nZeroes = num2b.length() - num1b.length();//待补的0的个数

            for (i = 0; i < nZeroes; ++i)

            {

                num1b += '0';

            }

        }

        //小数位对齐准备完毕,进行小数部分相加

        String rsTwo = add(num1b, num2b);

        if (rsTwo.length() > maxLen)

        {//说明有进位, 剥离第一位进位,加到整数部分去

             String nAddOn = rsTwo.substring(0,1);

             rsOne = add(rsOne, nAddOn);

             rsTwo = rsTwo.substring(1,rsTwo.length());

        }

        //两部分结果拼凑起来

        StringBuilder sb = new StringBuilder(rsOne);

        sb.append(".");

        sb.append(rsTwo);

        result = sb.toString();

        return result;

    }

    private static String add(String num1, String num2)

    { //大数相加

        String result = "";

        int len1 = num1.length();

        int len2 = num2.length();

        int nAddOn = 0;

        int i,j,n1,n2,sum;

        StringBuilder sb = new StringBuilder();

        for (i = len1 - 1,j = len2 - 1 ; i >= 0 && j >= 0; --i,--j)

        {

            n1 = num1.charAt(i) - '0';

            n2 = num2.charAt(j) - '0';

            sum = n1 + n2 + nAddOn;

            

            if (sum >= 10)

            {

                nAddOn = 1;

            }

            else

            {

                nAddOn = 0;

            }

            sb.append(sum % 10);

        }

        if (len1 > len2)

        {

            for (; i >= 0; --i)

            {

                n1 = num1.charAt(i) - '0';

                sum = n1 + nAddOn;

                if (sum >= 10)

                {

                    nAddOn = 1;

                }

                else

                {

                    nAddOn = 0;

                }

                sb.append(sum % 10);

            }

        }

        else if (len2 > len1)

        {

            for (; j >= 0; --j)

            {

                n2 = num2.charAt(j) - '0';

                sum = n2 + nAddOn;

                if (sum >= 10)

                {

                    nAddOn = 1;

                }

                else

                {

                    nAddOn = 0;

                }

                sb.append(sum % 10);

            }

        }

        

        if (nAddOn > 0)

        {

            sb.append(nAddOn);

        }

        

        sb.reverse();

        result = sb.toString();

        return result;

    }

    public static void main(String[] args) throws Exception

    {

        String num1 = "13454354352454545454354354354354543.9999999999993545624524435245425435435435";

        String num2 = "3415545435435435435435435434525435245245454252.999999999999999994535435435435252245426";

        String result = addFloatNum(num1, num2);//大浮点数相加

        System.out.println(result);

    }

}

四.两个数相乘,小数点后位数没有限制,请写一个高精度算法。

算法分析:

输入 string a, string b; 计算string c=a*b; 返回 c;

1,    纪录小数点在a,b中的位置l1,l2, 则需要小数点后移动位置数为l=length(a)+length(b)-l1-l2-2;

2,    去掉a,b中的小数点,(a,b小数点后移,使a,b变为整数)

3,    计算c=a*b; (同整数的大数相乘算法)

4,    输出c,(注意在输出倒数第l个数时,输出一个小数点。若是输出的数少于l个,就补0)

代码为:
#include<iostream> 
using namespace std; 
#define MAX 10000 
struct Node{ 
   int data; 
   Node *next; 
}; 
void output(Node *head,int pos) 
{ 
   if(!head->next&&!head->data)return; 
   output(head->next,pos-1); 
   cout<<head->data;
   if(!pos)cout<<".";
} 
void Mul(char *a,char *b,int pos)         
{ 
   char *ap=a,*bp=b; 
   Node *head=0; 
   head=new Node;head->data=0,head->next=0;   //头 
   Node *p,*q=head,*p1; 
   int temp=0,temp1,bbit; 
   while(*bp)                //若乘数不为空 ,继续. 
   { 
       p=q->next;p1=q; 
       bbit=*bp-48;          //把当前位转为整型 
       while(*ap||temp)            //若被乘数不空,继续 
       { 
           if(!p)            //若要操作的结点为空,申请之 
           { 
               p=new Node; 
               p->data=0; 
               p->next=0; 
               p1->next=p; 
           } 
           if(*ap==0)temp1=temp; 
           else { temp1=(p1->data)+(*ap-48)*bbit+temp;ap++; } 
           p1->data=temp1%10;    //留当前位 
           temp=temp1/10;    //进位以int的形式留下. 
           p1=p;p=p->next;                 //被乘数到下一位 
       } 
       ap=a;bp++;q=q->next;                //q进下一位 
   } 
   p=head; 
   output(p,pos);                   //显示 
   cout<<endl; 
   while(head)                 //释放空间 
   { 
           p=head->next; 
           delete head; 
           head=p; 
   } 
} 
int main() 
{ 
   cout<<"请输入两个数"<<endl; 
   char test1[MAX],test2[MAX],*p; 
   int pos=0;
   cin.getline(test1,MAX,'\n'); 
   cin.getline(test2,MAX,'\n');
   if(p=strchr(test1,'.'))
   {
       pos+=strlen(test1)-(p-test1)-1; 
       do
       {
           p++;
           *(p-1)=*p;
       }while(*p);
   }        
   if(p=strchr(test2,'.'))
   {
       pos+=strlen(test2)-(p-test2)-1;
       do
       {
           p++;
           *(p-1)=*p;
       }while(*p);
   }    
   Mul(strrev(test1),strrev(test2),pos); 
   system("PAUSE"); 
   return 0; 
}

参考:
1. http://blog.csdn.net/Hackbuteer1?viewmode=contents
2. http://www.cppblog.com/dotaqop/articles/148190.html

你可能感兴趣的:(任意长度的高精度大整数和浮点数的加法和乘法)