跳至主要內容

用c++写一个高精度计算的减法运算

程序员诚哥大约 3 分钟算法noicspsnoip

这段代码是一个用C++编写的程序,它实现了两个大整数的减法运算。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

int main(){
    int a[256],b[256],c[256],lena,lenb,lenc,i;
    char n[256],n1[256]="1001",n2[256]="2001";//n1被减数,n2减数
    memset(a,0,sizeof(a));//memset用于初始化数组或一块内存区域,将其中的每个字节都设置为指定的值。将数组a的值全部初始化为0
    memset(b,0,sizeof(b));
    memset(c,0,sizeof(c));
    //如果被减数小于减数,则交换它们的值,并输出负号表示结果将为负数。
    if(strlen(n1)<strlen(n2)||(strlen(n1)==strlen(n2)&&strcmp(n1,n2)<0)){
        strcpy(n,n1);
        strcpy(n1,n2);
        strcpy(n2,n);
        cout<<"-";
    }
    lena=strlen(n1);lenb=strlen(n2);
    for(i=0;i<=lena-1;i++){
        a[lena-i]=int(n1[i]-'0');
    }
    for(i=0;i<=lenb-1;i++){
        a[lenb-i]=int(n2[i]-'0');
    }
    i=1;
    while(i<=lena||i<=lenb){
        if(a[i]<b[i]){
            a[i]+=10;//不够减,那么想高位借1当10
            a[i+1]--;
        }
        c[i]=a[i]-b[i];//对应位相减
        i++;
    }
    lenc=i;
    while((c[lenc]==0)&&(lenc>1)) {
        lenc--;//最高位的0不输出
    }
    for(i=lenc;i>=1;i--) {
        cout<<c[i];
    }
    cout<<endl;
    return 0;
}

代码解析

  1. 字符数组的使用:这段代码使用字符数组来存储大整数。大整数通常无法用标准整数类型来表示,因此需要将其分解为字符数组,然后进行逐位操作。

  2. memset 函数memset 用于初始化数组或内存区域,将每个字节都设置为指定的值。在这里,它用来初始化abc 数组的所有元素为0。

  3. 字符转整数的转换:代码中使用 int(n1[i]-'0') 将字符数字转换为整数。这是因为字符 '0' 到 '9' 在 ASCII 编码中是连续的,所以可以通过减去 '0' 来获得对应的整数值。

  4. 大整数运算的思想:最重要的理解点是大整数运算的思想。由于大整数超出了标准整数范围,因此需要将它们分解为字符数组,并模拟手工计算的过程。这包括逐位减法和借位的概念。

逐位减法

  • 在大整数运算中,当我们需要计算两个大整数的差值时,通常需要从最低位(个位)开始逐位相减。
  • 例如,如果我们要计算 7654321 减去 1234567,我们从右向左逐位相减,从个位开始。首先是 1 减去 7,由于 1 小于 7,需要借位。这产生了一个新的问题,即借位的概念。
  • 逐位减法的关键是要确保每一位的减法操作都得到正确的结果,同时考虑到借位。

借位

  • 借位是指在执行逐位减法时,如果被减数小于减数,就必须向高位借位来执行减法。这类似于在十进制数学中,当你从某一位借位时,需要在高位的数字中减去一个。
  • 例如,在上面的示例中,1 减去 7 时,因为 1 小于 7,所以需要向高位借位。这导致 6(10 减去 7),并且高位的 6 会减去 1,以确保减法操作是正确的。
  • 借位可以一直传递到更高位,直到没有借位为止。
上次编辑于:
贡献者: zccbbg