跳至正文
View Categories

1 min read

主要内容 #

  1. 商和余数的求法
  2. 高精度 / 单精度

1. 商和余数的求法 #

要分两种情况讨论:

  • 高精度 / 单精度
  • 高精度 / 高精度

2. 高精度 / 低精度 #

也就是说:假设 a 是一个高精度整数,b是一个普通的整数。
【算法分析】
在高精度除以单精度时,从高位到低位逐位相除。最需要注意的问题是,后一位继承前一位的余数问题。
设高精度的数位数字为a[i],单精度数为b,第i+1位除b后的余数位r,把r加到i位时,应乘以进制X,即s=X*r+a[i].

  • 注意位移处理即可
    int b = 5;
    int a[] = {8,3,6};

(1)
     _1___
    5)836
     _5___
      3

(2)
     _16__
    5)836
     _5___
      33
     _30__
       3

(3)
     _167__
    5)836
     _5___
      33
     _30__
       36
     __35_
        1

【例程】

#include < iostream >
#include < string >
using namespace std;

void assign(int a[], int a_len, int* dst, int& dst_len)
{
    for (int i = 0; i < a_len; ++i)
        dst[i] = a[i];
    dst_len = a_len;
}

void divide(int a[], int a_len, int b, int* result, int& result_len)
{
    int c[100] = { 0 }, lenc = 0; // c 用于存放临时的计算结果

    if (a[0] == 0)
    {
        result_len = 1;
        assign(c, 1, result, result_len);
        return; // 0是被除数,则商为0
    }

    int i = 0, x = 0;
    result_len = 0;

    for (int i = 0; i < a_len; ++i)
    {
        c[i] = (x * 10 + a[i]) / b;
        x = (x * 10 + a[i]) % b;
        ++lenc;
    }

    // 去除前部可能出现的 0
    int c_startID = 0;
    for (; c_startID < 100; ++c_startID)
        if (c[c_startID] != 0)
            break;

    for (int i = c_startID; i < lenc; ++i)
    {
        result[i - c_startID] = c[i];
        ++result_len;
    }
}

int main()
{
    // 从屏幕获得输入 被除数a和除数b均以字符串的形式输入
    string astr, bstr;
    cin >> astr;
    cin >> bstr;
    //获得字符串a和b的长度也就是,a和b的位数
    int lena = astr.size(), lenb = bstr.size();
   //设置数组a[100]高精度数字a
    int a[100] = { 0 }, b = 0; 
    for (int i = 0; i < lena; ++i)
        a[i] = astr[i] - '0'; // 除法不需要将数字倒过来
    for (int i = 0; i < lenb; ++i)
        b += (bstr[i] - '0') * pow(10, lenb - i - 1); // 字符串转 10 进制数
    //不能除以0
    if (b == 0)
        return -1; 

    // 设置数组c[100]存储计算结果,c[100]中存储的也是高精度的数字
    int c[100] = { 0 }, lenc(0);
    divide(a, lena, b, c, lenc); // a 是被除数,是高精度值。b是低精度值,用 int 即可存储

    // 输出
    for (int i = 0; i < lenc; ++i)
    {
        cout << c[i]; // 正向输出
    }
    cout << endl;
    return 0;
}

习题 #

请将上面的例题,独立完成一遍。要求必须掌握。下节课要求每个人都能够独立写出上面的代码。
课后练习