栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

高精度计算程序——个人学习记录

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

高精度计算程序——个人学习记录

高精度计算程序报告

问题描述

高精度计算

涉及知识点:数组、流程控制、函数等

要求:用整型数组表示10进制大整数(超过2^32的整数),数组的每个元素存储大整数的一位数字,实现大整数的加减法。

问题分析

高精度计算问题是由c语言中整型变量所占字节数有限导致的

因此,想定义更大的数的加减法,我们需要借助数组来储存一个较大的数,问题即在于:

1.将输入的数存入数组

2.对存储于数组中的数进行计算

3.输出存储于数组中的结果

数据类型

整型数组x[1001],y[1001],z[1001]分别用于存储输入的数1,输入的数2,输出结果;

整型变量xl,yl分别表示两个输入的数的位数;

字符变量c表示键入的字符,用于将输入数字转化为数组存储;

字符变量o表示运算符,用于记录运算符;

整型变量a,b分别表示x、y数组中最后一个输入的数字的序数;

整型变量sum表示在某一位计算中加和的得到的结果;

整型变量i,j均为计数符;

处理方法设计

根据数字的十进制基本定义进行计算;

  • 将输入的数字存入数组并记录运算符;

    因为scanf函数无法区分数字符和运算符,所以我采用单个字符的方式录入数字,并通过isdigit函数来区分数字符与运算符,并用o来记录运算符,这样,我们计算所需的信息就都录入了。

  • 对数组所代表的数字进行计算;

    根据加法的基本定义,对每一位的数字进行加和,大于等于10时进1,小于0时退1,其原理即是科学计数法,将一个大数字拆分为每一位进行运算,如若遇到负数时,最终结果将记录为-1abcdefg的形式,其代表数字为-10000000+abcdefg,我们只需对负数进行整理即可;

  • 整理计算结果并输出结果

    对于整数结果,我们直接输出;

    对于0结果,我们也直接输出;

    对于负数结果,我们对每一位进行计算,正数位退1成为负数,最后输出;

    最终即可得到计算结果。

    上述程序可适用于加减运算,经过变形也可转化为乘法运算。

    #include 
    
    #include "ctype.h"
    
    int main() {
    
        int x[10087]={0},y[10087]={0},z[10087]={0};                                                                            //1.首先定义用于存储输入数字的数组x、y,以及用于存储结果的数组z;
    
        int xl=0,yl=0;                                                                                                      //2.xl、yl分别表示两输入数字的位数;
    
        char c,o;                                                                                                           //3.字符c用于将输入数字转化为数组;字符o表示运算符/操作符;
    
        while((c=getchar())!='n') {
    
            if (isdigit(c)) {
    
                x[xl] = c - '0';
    
                xl++;
    
            } else {
    
                o = c;
    
                break;
    
            }
    
        }                                                                                                                   //4.第一次读取用于读取第一个输入数字x,x的位数xl,及运算符号o;
    
        while((c=getchar())!='n'){
    
            if(isdigit(c)){
    
                y[yl]=c-'0';
    
                yl++;
    
            }
    
        }                                                                                                                   //5.第二次读取用于读取第二个输入数字y,y的位数yl;
    
        int a,b,sum=0;                                                                                                      //6.a、b为(数组长度-1),即数组的最后一个数的序号;
    
        a = xl-1;
    
        b = yl-1;
    
        if(o=='-'){
    
            for (int i=0;i=0||b>=0;i--){
    
            sum = 0;
    
            if(a>=0&&b<0){
    
                sum = x[a];
    
                a--;
    
            }
    
            else if(a<0&&b>=0){
    
                sum = y[b];
    
                b--;
    
            }
    
            else{
    
                sum = x[a]+y[b];
    
                a--;
    
                b--;
    
            }
    
            sum += z[i];
    
            if(sum>=10){
    
                z[i]=sum%10;
    
                z[i-1]++;
    
            }
    
            else if(sum<0){
    
                z[i]=sum+10;
    
                z[i-1]--;
    
            }
    
            else{
    
                z[i]=sum;
    
            }
    
        }                                                                                                                   //8.计算答案,并用数组z存储答案;
    
        int i=0;
    
        while(z[i]==0&&i<10087) i++;                                                                                         //9.去除数组前列的无意义的零;123456-12345
    
        if(z[i]==0) { printf("0");}
    
        else if(z[i]<0){
    
            for(int j=i+1;j<10087;j++){
    
                if(z[j]>=1){
    
                    z[j-1]++;
    
                    z[j]-=10;
    
                }
    
            }
    
            for(int k=0;k<10087;k++){
    
                for(int j=k;j<10087;j++){
    
                    if(z[j]>0) {
    
                        z[j]-=10;
    
                        z[j-1]++;
    
                    }
    
                }
    
    
    
            }
    
            while(z[i]==0&&i<10087) i++;
    
            printf("-");
    
            for(i;i<10087;i++) printf("%d",z[i]*-1);
    
        }                                                                                                                   //10.结果为负数时整理结果的结构并输出;
    
        else{
    
            while(z[i]==0&&i<10087) i++;
    
            if(i==10087) printf("0");
    
            for(i;i<10087;i++) printf("%d",z[i]);
    
        }                                                                                                                   //11.结果为非负数时直接输出;
    
        return 0;
    
    }

    测试数据及结果分析
    Test1
    2022-2022
    0
    Test2
    123456-12345
    111111
    Test3
    4984189049807980-9817263083728510678
    -9812278894678702698
    Test4
    1234567891111111+666666689410
    1235234557800521
    Test5
    21009200371+21009200371
    42018400742

    第一组数据代表相减得0的例子;

    第二组数据表示小数字一般相减;

    第三组数据表示大数字一般相减;

    第四组数据表示大数字一般相加;

    第五组数据表示小数字一般相加;

    结果均正确,推得程序无误。

  • 转载请注明:文章转载自 www.mshxw.com
    本文地址:https://www.mshxw.com/it/784743.html
    我们一直用心在做
    关于我们 文章归档 网站地图 联系我们

    版权所有 (c)2021-2022 MSHXW.COM

    ICP备案号:晋ICP备2021003244-6号