• 高精度加法


    呐!众所周知,数据是有范围的

    (Python && Java:) sorry,高精度真的可以为所欲为

    高精度真的可以为所欲为

    本文为博客园 ShyButHandsome的原创作品,转载请注明出处

    注:右边有目录,方便快速浏览

    需求原因

    C++中的数据类型是有范围的

    实现思路

    虽然内置数据类型范围不大

    但是字符串能很长啊!

    我们将加数的每一位都看作是一个字符的话

    那我们就得到了两个字符串

    代码实现

    解释都在代码里了

    #include <iostream>
    
    // EXIT_SUCCESS在stdlib库中
    #include <cstdlib>
    
    // strlen函数需要cstring库
    #include <cstring>
    
    using namespace std;
    
    // 500+6防止数组越界
    const int LENGTH_LIMIT = 5e2 + 6;
    
    // char表示的整数 减去一个‘0’就可以得到响应整数的ascii
    const int INT_CHANGER = '0';
    
    // 个位数不能超过10
    const int SINGLE_LIMIT = 10;
    
    char stringA[LENGTH_LIMIT];
    char stringB[LENGTH_LIMIT];
    
    int invertedA[LENGTH_LIMIT];
    int invertedB[LENGTH_LIMIT];
    int sum[LENGTH_LIMIT];
    
    int main(void)
    {
    
        cin >> stringA >> stringB;
    
        // 倒序储存
        int lengthA = strlen(stringA);
        for (int i = 0; i < lengthA; i++)
        {
            // 由于strlen返回的长度是符合正常思维(从1开始)
            // 但我们是从0开始,所以要额外 - 1
            invertedA[i] = stringA[lengthA - i - 1] - INT_CHANGER;
        }
    
        int lenghtB = strlen(stringB);
        for (int i = 0; i < lenghtB; i++)
        {
            invertedB[i] = stringB[lenghtB - i - 1] - INT_CHANGER;
        }
    
        // 和的最大长度是a,b最大值+1
        const int MAX_LENGTH = ((lengthA < lenghtB) ? lenghtB : lengthA) + 1;
    
        // 进位
        int carry = 0;
    
        // 模拟计算
        for (int i = 0; i < MAX_LENGTH; i++)
        {
            // 对应位相加
            sum[i] = invertedA[i] + invertedB[i] + carry;
            // 记录下进位
            carry = sum[i] / SINGLE_LIMIT;
            // 进位操作
            sum[i] %= SINGLE_LIMIT;
        }
    
        // 这里length选择放在循环外,因为两个循环都会用到它
        // +1是因为strlen返回的数组长度是从1开始计数的
        int length = MAX_LENGTH;
    
        // 删除前导零(确定数字实际长度)
        // 这里取length>0,因为
        // 如果删到最后一位就必须得保留,不管它是不是0
        for (length; length > 0; length--)
        {
            if (sum[length] == 0)
            {
                // 接着处理下一位
                continue;
            }
            else
            {
                // 如果遇到一位非零就说明前导零删干净了
                // 接着删就会删去数字中的0了
                break;
            }
        }
    
        // 正序输出
        for (length; length >= 0; length--)
        {
            cout << sum[length];
        }
    
        // 额外输出一个换行
        cout << endl;
    
        // EXIT_SUCCESS means 0
        return EXIT_SUCCESS;
    }
    

    再给出一份用STL写的:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int main(void)
    {
        string strA, strB;
        cin >> strA >> strB;
    
        vector<int> numA, numB, sum;
        
        for (int i = strA.size() - 1; i >= 0; i--)
        {
            numA.push_back(strA[i] - '0');
        }
        for (int i = strB.size() - 1; i >= 0; i--)
        {
            numB.push_back(strB[i] - '0');
        }
    
        int carry = 0;
        for (int i = 0; i < (max(numA.size(), numB.size())); i++)
        {
            sum.push_back(carry);
            // If lenA != lenB
            sum[i] += (i > (numA.size() - 1) ? 0 : numA[i]) + (i > (numB.size() - 1) ? 0 : numB[i]);
            carry = (sum[i]) / 10;
            sum[i] %= 10;
        }
    
        if (carry != 0)
        {
            cout << carry;
        }
    
        for (int i = sum.size() - 1; i >= 0; i--)
        {
            cout << sum[i];
        }
    
        cout << endl;
    
        return 0;
    }
    

    易错点

    下面是我总结出的几个易错点

    每个易错点都给出了测试数据

    可以利用右上角的复制按钮快速复制

    没有处理进位

    包括

    • 每次没有计算上次的进位啊
    • 每次没有加上上次的进位啊
    • 边界没有进位啊
    • 等等

    测试数据:

    输入:

    56546876443156448001
    56453168410002134684
    

    输出:

    113000044853158582685
    

    删除前导零错误

    测试数据:

    输入 1:

    11111111111111111111111111
    9999999999999999999999999999999999
    

    输出 1:

    10000000011111111111111111111111110
    

    输入 2:

    0
    0
    

    输出 2:

    0
    

    STL还要注意长度不一样

    输入:

    350204156568812004512541458715942878921069349854678
    5120132301230048014584016540526804565814706519846494321001345794503242112976563432120
    

    输出:

    5120132301230048014584016540526804916018863088658498833542804510446121034045913286798
    
  • 相关阅读:
    #在蓝懿学习iOS的日子#Day10
    #在蓝懿学习iOS的日子#Day9
    #在蓝懿学习iOS的日子#第三个练习日
    #在蓝懿学习iOS的日子#Day8
    WCF基础:绑定(二)
    WCF基础:绑定(三)
    WCF基础:绑定(一)
    MVC框架中的值提供机制(三)
    MVC框架中的值提供机制(二)
    MVC框架中的值提供机制(一)
  • 原文地址:https://www.cnblogs.com/ShyButHandsome/p/12809662.html
Copyright © 2020-2023  润新知