首页 > 其他分享 >关于高精度计算的研究(1)——高精度加、减运算(2023-07-21)

关于高精度计算的研究(1)——高精度加、减运算(2023-07-21)

时间:2023-07-21 22:44:08浏览次数:56  
标签:lenb 21 高精度 int printf 加法 2023 include

1、引入

在C++中,我们常会需要做加减乘除等等运算

首先我们来熟悉一下c++的计算符号:

+ (加号)                        - (减号、负号)                                   * (乘号)                                      / (除号)

() (括号)                        % (取余符)//例如5%2=1                   =    (赋值)                                   ==    (等于)//用于判断

 

特别注意:a/b如果a,b是整数,a/b系统会保留整数部分。

For example:

 

 #include <bits/stdc++.h>
 using namespace std;
 int main(){
     int a=3,b=2;
     cout<<"a="<<3<<"  "<<"b="<<2<<endl;
     cout<<"a-b="<<a-b<<endl;
     cout<<"a*b="<<a*b<<endl;
     cout<<"a/b="<<a
}

 

 

 

运行结果:

看起来很简单?

那如果a,b是几千亿的数呢?

这就行不通了!(不信自己试)

2、数据类型的极大值、极小值

首先,在讲高精度以前,我们先来认识一下比较常见的几种类型的最大值、最小值。

 

 正是因此,我们需要高精度计算。

加法

现在,我们来看看如何加。

 

我们想啊,题中给了一个条件:
image
那它肯定、肯定是不能使用常规的手法储存的,它的最大长度(501位)为远远超过 long long 类型的最大值。
我们要使用一些奇怪的东西,来储存它,比如说——字符串

前面我们有说过,string类型没有长度限制,那我们可以怎么操作呢?

思路

通用的思路,我们来模拟一下如何进行加法运算。

我们可以知道,加法可能会有进位
那进位能不能判断还不好说,所以我们考虑在数组中逆序存储,这样如果有进位会在结果的后面存储,最后输出时再逆序输出 ,就实现了存储。
为了方便,我建议大家把数组的每一位设置为0,可能会方便些。

 

如图示:

image

接下来,处理进位,逢十进一,当前的位取个位,后面的一位增加 1 。
imageimage

 

加法的代码实现

#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;

int a[506], b[506];
int lena, lenb;
int m;
string a1, b1;

int main(){
    cin>>a1>>b1;//定义的字符串读入只可以用gets和cin,不能用scanf
    lena = a1.length();
    lenb = b1.length();
    for (int i = 0; i <= lena - 1; i++){
        a[lena - i - 1] = a1[i] -'0';
    }
    for(int i = 0; i <= lenb - 1; i++){
        b[lenb - i - 1] = b1[i] - '0';
    }
    if(lena >= lenb){
        for(int i = 0; i <= lena - 1; i++){
            int ss = a[i];
            a[i] = (b[i] + a[i] + m)%10;
            m = (ss + b[i] + m)/10;
        }
        if(m) a[lena] = m;
        else lena--;
        for(int i = lena; i >= 0; i--) printf("%d",a[i]);
        return 0;
    }
    else{
        for(int i = 0; i <= lenb-1; i++){
            int ss = b[i];
            b[i] = (b[i] + a[i] + m)%10;
            m = (ss + a[i] + m) /10;
        }
        if(m) b[lenb] = m;
        else lenb--;
        for(int i = lenb; i >= 0; i--) printf("%d",b[i]);
        return 0;
    }
    return 0;
}

减法

 

 

 

减法和加法的算法差不太多

代码如下:

#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
const int N=205;
int main(){
    int i;
    int a[N],b[N],lena,lenb,x;
    char t[N],t1[N];
    scanf("%s %s",t,t1);
    lena=strlen(t);
    lenb=strlen(t1);
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    for(i=0;i<lena;i++)a[lena-i]=t[i]-48;
    for(i=0;i<lenb;i++)b[lenb-i]=t1[i]-48;
    i=1;x=0;
    while((i<=lena) or (i<=lenb)){
        a[i]=a[i]-b[i]-x;
        if(a[i]<0){
            a[i]+=10;
            x=1;
        }
         else x=0;
        i++;
    }
    bool f=false;
    for(i=N-1;i>=1;--i){
        if(a[i]!=0){
            printf("%d",a[i]);
            if(!f)f=true;
        }
         else if(f)printf("%d",a[i]);
    }
    if(!f)printf("0");
    return 0;
}

 

 《关于高精度计算的研究(2)——高精度乘、除运算》将于不久后写出

 

 

 

 

 

标签:lenb,21,高精度,int,printf,加法,2023,include
From: https://www.cnblogs.com/Brownking/p/17571303.html

相关文章

  • 7.21 后记
    我的图逃走了考试T1瞎搞题(老师认证)T2矩阵找最大环,可以推出一个只含两个点3个坐标的式子,\(O(n^3)\)找最大值,再枚举剩下一个点\(n*m\le2e5\),说明\(n\)或\(m\)小于400,\(O(n*m+400)\)可以允许T3做法好想,但缩点+分数规划+树形dp毒瘤,改不动T4括号序列,难难难下......
  • 《摆与混》第十九章--7月21日--周五
    明天就是周末,我闻到了些许畅快1.今天做了什么:今天9点起床(好耶)。洗漱后,简单吃了个早饭(肉丝粉,比我妈做的好吃),上午正常学习,又看了会小说,下午去解救了一下电动车被拖走的哥们(笑死我了,小丑一个),5点半出发健身锻炼(坚持),晚上看比赛加上经典PTA,大计划周末篇!!!2.解决了什么问题:Java课程推进,PT......
  • 7-21打卡
    publicclassHanoiTower{publicstaticvoidmain(String[]args){intn=3;//圆盘的数量charfrom='A';//起始柱子charaux='B';//辅助柱子charto='C';//目标柱子solveHanoi(n,from,a......
  • 7月21日
    7月21日今天早上七点多起的床,起来的时候就开始下雨了,盼星星盼月亮终于下雨了。上午下雨就在家呆着了,早上歇了一会儿打了会儿游戏,然后就帮着一块包饺子了,过了一会儿刷了会儿科目一的题,然后开始吃饭,完事之后就开始午休,睡了一会儿,等醒了之后就开始写pta上的题,然后看了会儿黑马程序员......
  • 20230720练习总结
    CF1523HHoppingAroundtheArray写在前面:毒瘤翻译!!!原题面有一句"Agrasshoppercanhoparoundthesellsaccordingtothefollowingrule"翻译过来就是不能删去起点和终点,翻译题面没有这句话!!!调了一个下午,答案一直比标答小!!!先忽略询问的终点,那么从\(i\)起跳,一定是跳到\([......
  • 7.21
    今天上午建好了那个程序设计的小组群,感觉还是不太舒服睡了一上午下午睡到三点起来玩了一会就去练车去了晚上看了一会大道至简,看了一多半了马上就能写读后感了还打了一会代码#include<iostream>#include<cctype>#include<cstring>usingnamespacestd;boolisnum(string......
  • 7.21语言结构学习
    语言结构学习第一题,答案;第二题,答案写,第一题,答案多少;第二题,答案多少......
  • 2023 暑假集训模拟赛题解
    目录CSP模拟1CSP模拟2FSYOCSP模拟1来自学长的馈赠2.CSP模拟2F考虑\(x\)只能在\(a_1\oplusb_i\)里选,那么分别代入暴力检验即可.时间复杂度\(\tilde\Theta(n^2)\),可以通过.S考虑交换同色的部分一定不优,所以同色字符的相对位置一定是不变的.那么操作序列......
  • 20230721巴蜀暑期集训测试总结
    T1似乎想复杂了。搓了一个\(O(Q\sqrt{n\logn})\)的做法,成功跳过正解。结果考后发现普通分块就可以\(O(Q\sqrtn)\)。而且似乎还WA了一些点。根据题意可以发现\(b_i\)为\(1\)当且仅当\(i\)在二进制下有奇数个\(1\)。这个可以用来快速求\(b_i\)。再观察性质,发现\(......
  • 7.21
    package获取字符串信息;publicclass获取字符串长度{publicstaticvoidmain(String[]args){char[]a=newchar[10];Stringstr=newString(a);System.out.println(str.length());//获取字符串长度}}package获取字符串......