大数求和

       我们现有的编程语言提供的数据类型都是有范围限制的。例如在C/C++语言,基于VC编译器,int类型是4个字节。表示数的有效范围是

-2,147,483,648 到 2,147,483,647。所以如果要计算的很大的时候,例如要计算的数的位数是50位以上的。那么用编程语言提供的内部数据类型是不能进行运算的,因为数太大,存储不下。解决这种问题我们一般是借助字符数组进行存储。将大数的每一位看出是一个数字字符,存储到一个字符数组中。计算的过程中需要将数字字符和数字之间进行转换。这个很容易实现。因为数字0对应的数字字符'0'的ASCII码是48,之后的数字对应的数字字符的ASCII依次加1。将数字转换为字符,只需进行加上48即可。例如 int a=9;转换为字符‘9’ ,char c = a+48;

为了提高效率可以考虑用位操作,采用异或(^)也可以的。c = a^(0x30);48的十六进制是0x30。与之相反的是将数字字符转换为数字,只需在数字字符的ASCII码上减去48即可。char c='9';int a = c-48。也可以通过位操作实现,a=c^0x30。现在的问题是如何通过数字字符串进行求和的问题。我们这个时候就按照小学时候学的加法运算法则进行了。先是各位相加,然后依次十位……,在每一位相加的过程中要考虑到进位,所以下一位的求和是带进位的求和。例如 a=9876;b=23234;先是6+4=10,这个时候有进位,计算结果是0,进位是1。在用数字字符数数组存放大数的时候,计算的时候跟我们日常生活中正好相反,所以需要进行顺序的调整。才能进行由低位到高位进行求和运算。两个数求和的情况一般有以下几种情况:

case1:两个数的位数相同,没有进位,结果的位数与两个数相同。例如56+12 = 68

case2:两个数的位数相同,有进位,结果的位数与两个数相同。例如56+29 = 85

case3:两个数的位数相同,有进位,结果的位数比两个数多一位。例如56+62=118

case4:两个数的位数不相同,没有进位,结果与最大数的位数相同。例如235+53=288

case5:两个数的位数不相同,有进位,结果与最大数的位数相同。例如235+76=311

case6:两个数的位数不相同,有进位,结果与最大数的位数多一位。例如935+76=1011

有了以上的分析,很容易就编写出程序来。采用C++语言进行实现。

#include <iostream>
using namespace std;
#define ARRAY_SIZE 50
//Enter a big number, and store it as a string into an array ch,
//the size is the numbers of char.
void inputNumbers(char ch[], int& size);
//Reverse the elements of the array ch.
void reverseArray(char ch[], int size);
//Adding two big numbers, and the result will be stored in the array ch3,
//and return the size of the array ch3.
void computeAdding(char ch1[], int size1, char ch2[], int size2, char ch3[], int& size3);
//show the adding result.
void displayResult(char ch[], int size);
int main()
{
    while(true)
    {
        char ch1[ARRAY_SIZE], ch2[ARRAY_SIZE], result[ARRAY_SIZE];
        int size1 = 0, size2 = 0, resultSize = 0;
        cout << "Enter the first big number, ending with an enter:" << endl;
        inputNumbers(ch1, size1);
        cout << "Enter the second big number, ending with an enter:" << endl;
        inputNumbers(ch2, size2);
        reverseArray(ch1, size1);
        reverseArray(ch2, size2);
        computeAdding(ch1, size1, ch2, size2, result, resultSize);
        displayResult(result, resultSize);
    }
    system("pause");
    return 0;
}
//Function inputNumbers
void inputNumbers(char ch[], int& size)
{
    char next;
    cin.get(next);
    while (next != '\n' && size < ARRAY_SIZE)
    {
        ch[size++] = next;
        cin.get(next);
    }
}//inputNumbers

//Function reverseArray
void reverseArray(char ch[], int size)
{
    int i = 0, j = size-1;
    char temp;
    
    while (i <= j)
    {
        temp = ch[i];
        ch[i] = ch[j];
        ch[j] = temp;
        i ++;
        j --;
    }
}//end reverseArray function
//function computeAdding
void computeAdding(char ch1[], int size1, char ch2[], int size2, char ch3[], int& size3)
{
    int i = 0, j = 0;
    int result = 0;
    int carry = 0;//初始进位为0
    while(i < size1 && j < size2)
    {
        //计算两个数对应位的和,带进位的计算
        result = (ch1[i]^0x30) + (ch2[j]^0x30)+carry;  
        //取其最低位
        ch3[size3++] = (result%10)^0x30;
        //进位
        carry = result/10;
        i++;
        j++;
    }
    //第一个数位数大于第二个位数
    while(i<size1)
    {
        int ret = (ch1[i]^0x30) +carry;  
        ch3[size3++] = (ret%10)^0x30;
        carry = ret/10;
        i++;
    }
    //第二个数的位数大于第一个位数
    while(j<size2)
    {
        int ret = (ch2[j]^0x30) +carry;  
        ch3[size3++] = (ret%10)^0x30;
        carry = ret/10;
        j++;
    }
    //所以计算完成看是否有进位
    if(i==size1 &&j==size2 && carry!=0)
        ch3[size3++] = carry^0x30;
    ch3[size3] = '\0';
}
//function displayResult
void displayResult(char ch[], int size)
{
    reverseArray(ch, size);//make the number to be normal
    cout << "The adding result is:" ;
    puts(ch);
    cout << endl;
}

测试结果如下:



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值