数学问题-高精度运算

Posted TQCAI

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数学问题-高精度运算相关的知识,希望对你有一定的参考价值。

模板:http://www.cnblogs.com/TQCAI/p/8410799.html


1.高精度加法训练

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 10000
#define MAX 1<<30
#define V vector<int>
#define ll long long

using namespace std;

typedef struct hp{
    int len;
    char s[LEN];
    hp(){
        len=0;
        memset(s,0,LEN);
    }
    hp(const char *ch){
        memset(s,0,LEN);
        len=strlen(ch);
        for(int i=0;i<len;i++){
            s[len-i]=ch[i]-48;
        }
    }
    void print(){
        for(int i=len;i>=1;i--){
            putchar(s[i]+48);
        }
    }
}hp;

hp add(const hp&a,const hp&b){
    int i,len=max(a.len,b.len);
    hp c;
    for(i=1;i<=len;i++){
        c.s[i]+=a.s[i]+b.s[i];
        if(c.s[i]>9){
            c.s[i+1]++;
            c.s[i]%=10;
        }
    }
    len++;
    while(len>1 && c.s[len]==0) len--;
    c.len=len;
    return c;
}

int main(){
//    freopen("A+B Problem.txt","r",stdin);
    char a[LEN];
    char b[LEN];
    scanf("%s",a);
    scanf("%s",b);
    add(hp(a),hp(b)).print();
    puts("");
    return 0; 
}
View Code

注意0的特殊情况,以及用scanf读入字符串而不能用gets读入(gets会读入空格)


2.高精度减法训练

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 1000000
#define MAX 1<<30
#define V vector<int>
#define ll long long

using namespace std;

typedef struct hp{
    int len;
    char s[LEN];
    hp(){
        len=0;
        memset(s,0,LEN);
    }
    hp(const char *ch){
        memset(s,0,LEN);
        len=strlen(ch);
        for(int i=0;i<len;i++){
            s[len-i]=ch[i]-48;
        }
    }
    void print(){
        for(int i=len;i>=1;i--){
            putchar(s[i]+48);
        }
    }
}hp;

int compare(const hp&a,const hp&b){
    int len=max(a.len,b.len);
    while(len>0 && a.s[len]==b.s[len]) len--;
    if(!len) return 0;
    return a.s[len]-b.s[len];
} 

hp subtract(const hp&a,const hp&b){    //a 大 b小 
    int i,len=max(a.len,b.len);
    hp c;
    for(i=1;i<=len;i++){
        c.s[i]+=a.s[i]-b.s[i];
        if(c.s[i]<0){
            c.s[i+1]--;
            c.s[i]+=10;
        }
    }
    while(len>1 && c.s[len]==0) len--;
    c.len=len;
    return c;
}

int main(){
//    freopen("高精度减法.txt","r",stdin);
    char a[LEN];
    char b[LEN];
    scanf("%s",a);
    scanf("%s",b);
    int d=compare(a,b);
    if(d<0){
        printf("-");
        subtract(b,a).print();
    }
    else if(d>0) subtract(a,b).print();
    else puts("0");
    return 0; 
}
View Code

注意用compare函数进行大数的大小判断。如果第一个比第二个小就b-a并且输出负号


3.高精度乘法训练

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 10000
#define MAX 1<<30
#define V vector<int>
#define ll long long

using namespace std;

typedef struct hp{
    int len;
    char s[LEN];
    hp(){
        len=0;
        memset(s,0,LEN);
    }
    hp(const char *ch){
        memset(s,0,LEN);
        len=strlen(ch);
        for(int i=0;i<len;i++){
            s[len-i]=ch[i]-48;
        }
    }
    void print(){
        for(int i=len;i>=1;i--){
            putchar(s[i]+48);
        }
    }
}hp;

hp multiply(const hp&a,const hp&b) {
    int i,j,len=a.len+b.len+1;
    hp c;
    for(i=1;i<=a.len;i++){
        for(j=1;j<=b.len;j++){
            c.s[i+j-1]+=a.s[i]*b.s[j];
            c.s[i+j]+=c.s[i+j-1]/10;
            c.s[i+j-1]%=10;
        }
    } 
    while(len>1 && c.s[len]==0 ) len--;
    c.len=len;
    return c;
}

int main(){
//    freopen("A×B Problem.txt","r",stdin);
    char a[LEN];
    char b[LEN];
    scanf("%s",a);
    scanf("%s",b);
    multiply(hp(a),hp(b)).print();
    puts("");
    return 0; 
}
View Code

这题可以说很简单,只要理解(或者熟背)高精度乘法板子,默写下来就OK了。


 

 

灵活多变的题型:

1.B进制星球:

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <string.h>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 10000
#define MAX 1<<30
#define V vector<int>
#define ll long long

using namespace std;

int radix=10;

typedef struct hp{
    int len;
    char s[LEN];
    hp(){
        len=0;
        memset(s,0,LEN);
    }
    hp(const char *ch){
        memset(s,0,LEN);
        len=strlen(ch);
        for(int i=0;i<len;i++){
            if(ch[i]>=\'0\' && ch[i]<=\'9\')
                s[len-i]=ch[i]-\'0\';
            else if(ch[i]>=\'A\' && ch[i]<=\'Z\')
                s[len-i]=ch[i]-\'A\'+10;
        }
    }
    void print(){
        for(int i=len;i>=1;i--){
            if(s[i]>=0 && s[i]<=9)
                putchar(s[i]+\'0\');
            else
                putchar(s[i]-10+\'A\');
        }
    }
}hp;

hp add(const hp&a,const hp&b){
    int i,len=max(a.len,b.len);
    hp c;
    for(i=1;i<=len;i++){
        c.s[i]+=a.s[i]+b.s[i];
        if(c.s[i]>=radix){
            c.s[i+1]++;
            c.s[i]%=radix;
        }
    }
    len++;
    while(len>1 && c.s[len]==0) len--;
    c.len=len;
    return c;
}

int main(){
//    freopen("D:\\\\CbWorkspace\\\\数学问题\\\\高精度\\\\B进制星球.txt","r",stdin);
    char a[LEN];
    char b[LEN];
    scanf("%d",&radix);
    scanf("%s",a);
    scanf("%s",b);
    add(hp(a),hp(b)).print();
    puts("");
    return 0; 
}
View Code

模拟其他进制的高精度运算。只要搞清楚10进制加法的进位原理,只要改一下radix参数就可以了。


 

以上是关于数学问题-高精度运算的主要内容,如果未能解决你的问题,请参考以下文章

数学问题-高精度运算

解决“0.1 + 0.2 = 0.30000000000000004” - uniapp中JS浮点运算精度问题 - uniapp引入decimal.jsmath.js等数学库

解决“0.1 + 0.2 = 0.30000000000000004” - uniapp中JS浮点运算精度问题 - uniapp引入decimal.jsmath.js等数学库

解决“0.1 + 0.2 = 0.30000000000000004” - uniapp中JS浮点运算精度问题 - uniapp引入decimal.jsmath.js等数学库

数学问题——大整数运算

PHP高精度数学运算函数