高精度算法集锦

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

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

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

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

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

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

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

[cpp]  view plain copy print ?
  1. #include "iostream"  
  2. #include "stack"  
  3. using namespace std;  
  4.   
  5. stack<int>s1;  
  6. stack<int>s2;  
  7. stack<int>s3;  
  8. char c1[100];  
  9. char c2[100];  
  10.   
  11. int main(void)  
  12. {  
  13.     printf("请输入第一个加数:");  
  14.     cin>>c1;  
  15.     printf("请输入第二个加数:");  
  16.     cin>>c2;  
  17.     int len1=strlen(c1);  
  18.     int len2=strlen(c2);  
  19.     for(int i=0;i<len1;i++)  
  20.     {  
  21.         s1.push(c1[i]-'0');            //按输入顺序(高位到低位)入栈1,此时栈顶为最低位  
  22.     }  
  23.     for(int i=0;i<len2;i++)  
  24.     {  
  25.         s2.push(c2[i]-'0');            //按输入顺序(高位到低位)入栈2,此时栈顶为最低位  
  26.     }  
  27.   
  28.     int tmp=0;  
  29.     while(!s1.empty() && !s2.empty())  
  30.     {  
  31.         tmp += s1.top()+s2.top();   // 将栈1、栈2均pop出栈顶做加法,并考虑进位,结果入栈3,这时栈3正好是低位入栈  
  32.         s1.pop();  
  33.         s2.pop();  
  34.         s3.push(tmp%10);  
  35.         tmp = tmp/10;  
  36.     }  
  37.     while(!s1.empty())   //处理多余的栈1  
  38.     {  
  39.         tmp += s1.top();  
  40.         s1.pop();  
  41.         s3.push(tmp%10);  
  42.         tmp = tmp/10;  
  43.     }  
  44.     while(!s2.empty())   //处理多余的栈2  
  45.     {  
  46.         tmp += s2.top();  
  47.         s2.pop();  
  48.         s3.push(tmp%10);  
  49.         tmp = tmp/10;  
  50.     }  
  51.     if(tmp)        //处理多余的进位  
  52.     {  
  53.         s3.push(tmp);  
  54.     }  
  55.   
  56.     printf("两个数相加的结果为:");  
  57.     while(!s3.empty())    //直接pop出栈3,即正好的从高位到低位的结果  
  58.     {  
  59.         cout<<s3.top();  
  60.         s3.pop();  
  61.     }  
  62.     cout<<endl;  
  63.     system("pause");  
  64.     return 0;  
  65. }  

二. 任意长度的高精度大整数乘法
[cpp]  view plain copy print ?
  1. <span style="font-size:14px">#include "iostream"  
  2. #include "string"  
  3. using namespace std;  
  4. int main(void)  
  5. {  
  6.     char str1[1000],str2[1000];  
  7.     int i,j,len1,len2,len;  
  8.     bool flag=false;  
  9.     cout<<"任意两个大数的乘法(用数组来模拟小学三年级的乘法竖式计算过程):"<<endl;  
  10.     cout<<"请输入被乘数:";  
  11.     gets(str1);  
  12.     cout<<"请输入乘数:";  
  13.     gets(str2);  
  14.     len1=strlen(str1);  
  15.     len2=strlen(str2);  
  16.     int *a=new int[len1];  
  17.     int *b=new int[len2];  
  18.     len=len1*len2+1;  
  19.     int *result= new int[len];  
  20.     for(i=0;i<len;i++)  
  21.         result[i]=0;  
  22.     for(i=0;i<len1;i++) //将字符串转换为整数,并倒置过来  
  23.         a[i]=str1[len1-1-i]-'0';  
  24.     for(i=0;i<len2;i++)  
  25.         b[i]=str2[len2-1-i]-'0';  
  26.     for(i=0;i<len1;i++)  //用数组来模拟小学三年级的乘法竖式计算过程  
  27.     {  
  28.         for(j=0;j<len2;j++)  
  29.             result[i+j]+=a[i]*b[j];  
  30.     }  
  31.     for(i=0;i<len;i++)   //处理进位的情况  
  32.     {  
  33.         if(result[i]>9)  
  34.         {  
  35.             result[i+1]+=result[i]/10;  
  36.             result[i]%=10;  
  37.         }  
  38.     }  
  39.     cout<<"两个大整数相乘的结果为:";  
  40.     for(i=len-1;i>=0;i--)  
  41.     {  
  42.         if(flag)  
  43.             cout<<result[i];  
  44.         else if(result[i]!=0)  
  45.         {  
  46.             cout<<result[i];  
  47.             flag=true;  
  48.         }  
  49.     }  
  50.     cout<<endl;  
  51.     delete []a;  
  52.     delete []b;  
  53.     delete []result;  
  54.     system("pause");  
  55.     return 0;  
  56. }</span>  

三. 两个数相加,小数点后位数没有限制,请写一个高精度算法(要进行小数点对齐)
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();//用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;  
			nAddOn = sum>=10?1:0; 
            sb.append(sum % 10);  
        }  
        if (len1 > len2){  
            for (; i >= 0; --i){  
                n1 = num1.charAt(i) - '0';  
                sum = n1 + nAddOn;  
				nAddOn = sum>=10?1:0; 
                sb.append(sum % 10);  
            } 
        }  
        else if (len2 > len1){  
            for (; j >= 0; --j) {  
                n2 = num2.charAt(j) - '0';  
                sum = n2 + nAddOn;  
                nAddOn = sum>=10?1: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)

个人觉得(lsj):跟整数乘法算法没什么区别,乘完的时候把小数点加上去就行了

整数减法:这哥们没有贴出代码,参考本博客http://blog.csdn.net/lsjseu/article/details/9812501

你可能感兴趣的:(高精度)