zoukankan      html  css  js  c++  java
  • 高精度运算

    今天模拟,很巧的是我前两天刚看过这个qwq

    高精度加法 高精度减法 高精度乘 高精度阶乘 别看了,写的没有我好

    某人为数不多的写了blog的题解 

    我麻了,这个人怎么会是我师父

    高精度运算需要使用python

    因为在十进制,int最多十位,long long最多十九位,

    要算比这个还大的数,就要把它拆成一位一位,模拟列竖式计算,也就是高精度

    输入和输出

    char s1[maxn],s2[maxn];
    int d1[maxn],d2[maxn];

    首先把两个数以字符串的形式读入,然后把它们转化成int;

    for(int i = 0; i <= len1; i++) d1[len1-i] = s1[i]-'0';

    (这么写的好处是,数组的下标由原来的0~len-1变成了1~len)

    计算;

    最后倒序输出,忽略前导0。只剩一位的时候0要保留。

    while(k>1) {
            if(ans[k])break;
            k--;
        }
    for(int i = k; i; i--) printf("%d",ans[i]);

    高精度加法

    计算时,注意判断是否进位。加法最多只能进一位,所以$ans[i+1]+1,ans[i]-10$即可。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #define MogeKo qwq
    using namespace std;
    const int maxn = 1e6+10;
    char s1[maxn],s2[maxn];
    int len1,len2,k;
    int d1[maxn],d2[maxn],ans[maxn];
    int main() {
        scanf("%s",s1);
        scanf("%s",s2);
        len1 = strlen(s1),len2 = strlen(s2);
        for(int i = 0; i <= len1; i++) d1[len1-i] = s1[i]-'0';
        for(int i = 0; i <= len2; i++) d2[len2-i] = s2[i]-'0';
        while(++k <= max(len1,len2)) {
            ans[k] += d1[k]+d2[k];
            if(ans[k]>=10) {
                ans[k+1]++;
                ans[k] -= 10;
            }
        }
        while(k>1) {
            if(ans[k])break;
            k--;
        }
        for(int i = k; i; i--)printf("%d",ans[i]);
        return 0;
    }
      +  

    高精度减法

    同理,只能借一位,$ans[i+1]-1,ans[i]+10$。

    注意:需要先判断答案的正负,先比较两个数字的位数,再一位一位比较,

    如果前面的较小,则交换两个数组并输出负号。相等则按正数算。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #define MogeKo qwq
    using namespace std;
    const int maxn = 1e6+10;
    char s1[maxn],s2[maxn];
    int len1,len2,k;
    int d1[maxn],d2[maxn],ans[maxn];
    
    bool check() {
        if(len1 > len2)return true;
        if(len1 < len2)return false;
        for(int i = len1; i; i--) {
            if(d1[i]>d2[i])return true;
            if(d1[i]<d2[i])return false;
        }
        return true;
    }
    
    int main() {
        scanf("%s",s1);
        scanf("%s",s2);
        len1 = strlen(s1),len2 = strlen(s2);
        for(int i = 0; i <= len1; i++) d1[len1-i] = s1[i]-'0';
        for(int i = 0; i <= len2; i++) d2[len2-i] = s2[i]-'0';
        if(!check()) {
            printf("-");
            swap(d1,d2);
            swap(len1,len2);
        }
        while(++k <= max(len1,len2)) {
            ans[k] += d1[k]-d2[k];
            if(ans[k]<0) {
                ans[k+1]--;
                ans[k] += 10;
            }
        }
        while(k>1) {
            if(ans[k])break;
            k--;
        }
        for(int i = k; i; i--)printf("%d",ans[i]);
        return 0;
    }
      -  

    高精度乘法

    设第一个数枚举到$d[i]$,第二个数枚举到$d[j]$,则当前算出来的的数字为$ans[i+j-1]$。

    可能进不止一位,则$ans[i+1]+ans[i]/10,ans[i] mod 10$。

    注意数据范围,数组的大小应为$n^2$

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #define MogeKo qwq
    using namespace std;
    const int maxn = 1e6+10;
    char s1[maxn],s2[maxn];
    int len1,len2,k;
    int d1[maxn],d2[maxn],ans[maxn];
    int main() {
        scanf("%s",s1);
        scanf("%s",s2);
        len1 = strlen(s1),len2 = strlen(s2);
        for(int i = 0; i <= len1; i++) d1[len1-i] = s1[i]-'0';
        for(int i = 0; i <= len2; i++) d2[len2-i] = s2[i]-'0';
        for(int i = 1;i <= len1;i++)
            for(int j = 1;j <= len2;j++){    
                int t = i+j-1;
                ans[t] += d1[i] * d2[j];
                if(ans[t]>=10){
                    ans[t+1] += ans[t]/10;
                    ans[t] %= 10;
                }
            }
        k = len1+len2+1;
        while(k>1) {
            if(ans[k])break;
            k--;
        }
        for(int i = k; i; i--)printf("%d",ans[i]);
        return 0;
    }
      *  

    高精度阶乘

    当要求一个较大数的阶乘时,需要应用到高精度乘法。

    $n! = n*(n-1)!$,

    用当前枚举到的数$n$与已经得到的数$(n-1)!$的各个数位相乘,即低精度*高精度。

    注意这里不能直接$ans[i+1]+ans[i]/10$。因为$ans[i+1]$下一步还要与$n$相乘,乘法的优先级高于加法的优先级。

    可以用一个$tem$记录进位,$ans[i+1]$完成乘法操作后再加上$tem$。

    注意,枚举答案的每一位时,每次记录答案现在的位数比较麻烦,可以每次枚举到可能的最大值。

    估算N的阶乘位数可以用斯特林公式……emm还是算了吧。

    (100!约有158位,1000!约有2568位,10000!约有35660位)

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #define MogeKo qwq
    using namespace std;
    const int maxn = 1e6+10;
    int n,k,t;
    int ans[maxn];
    int main() {
        scanf("%d",&n);
        ans[1] = 1;
        k = 10000;
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= k;j++){    
                ans[j] *= i;
                ans[j] += t;
                t = 0;
                if(ans[j]>=10){
                    t = ans[j]/10;
                    ans[j] %= 10;
                }
            }
        while(k>1) {
            if(ans[k])break;
            k--;
        }
        for(int i = k; i; i--)printf("%d",ans[i]);
        return 0;
    }
      !  

    (然而并不会写除法)

  • 相关阅读:
    SpringCloudAlibaba笔记01
    移除xlsm格式的excel中的宏密码
    CentOS7安装kairosdb并使用Cassandra作为存储(同一台机器上)
    CentOS7安装cassandra(单机模式)
    go-遍历文件夹及文件夹下文件比较工具总结
    Go学习笔记3-包管理-windows下dep工具的使用
    SpringBoot+cxf发布WebService
    显示GetLastError()的错误描述字符串
    Windows中的对象
    char* 和 wchar_t* 如何互相转换
  • 原文地址:https://www.cnblogs.com/mogeko/p/10704274.html
Copyright © 2011-2022 走看看