• 高精度除法的实现


            这是C++算法基础-基础算法专栏的第十篇文章,专栏详情请见此处


    引入

            上次我们学习了高精度乘法的实现,这次我们要学习高精度除法的实现。

            高精度除法与高精度加法的定义、前置过程都是大致相同的,如果想了解具体内容,可以移步至我的这篇博客:高精度加法计算的实现

            在这里就不再详细讲解,只讲解主体过程qwq

    主体过程

            高精度除法的原理和小学学习的竖式除法是一样的。

            

            概括来说,假如被除数长度为la,除数长度为lb,为了减少冗余运算,我们从la-lb从后往前开始计算,将被除数与除数相对应的每一位相(整)除,实际上这一步可以看作一个逐次减法的过程,然后存进商的对应位置上,再将余数乘10并放进下一位。

              12345\div 89用高精度计算,先除百位,将123减去89一次后变为34,小于89,所以将1存入百位,将34\times 10存入十位;

            再除十位,将34\times 10+4减去89三次后变为77,小于89,所以将3存入十位,将77\times 10存入个位;

            最后除个位,将77\times 10+5减去89八次后变为63,小于89,所以将8存入个位,将63存入余数数组。

            其实,高精度除法按理来说不需要反转存储,正序存储会更方便,但大部分题目,如果需要高精度除法去做,那么很有可能也需要其他的高精度计算,为了统一,我们还是使用反转存储。

            接下来,我们这里实现一个函数,它判断了被除数以下标low为最低位,是否可以再减去除数而保持非负。这个函数分为三部分:

    1. 被除数剩余的部分比除数长,这个情况下最多多出 1 位,函数返回真。
    2. 如第一步判断为假,就说明被除数与除数一样长,那我们就从高位到低位,逐位比较:如果被除数当前位比除数当前位大,函数返回真;反之,函数返回假。
    3. 如第二步也判断为假,就说明被除数与除数相等,相等的情形下也是可行的,函数返回真。

            下面给出高精度除法的代码:

    1. bool big(int a[],int b[],int low,int L){
    2. if(a[low+L]!=0) return 1;
    3. for(int i=L-1;i>=0;--i){
    4. if(a[low+i]>b[i])
    5. return 1;
    6. if(a[low+i]
    7. return 0;
    8. }
    9. return 1;
    10. }
    11. void div(int a[],int b[],int c[],int d[]){
    12. clear(c);
    13. clear(d);
    14. int la,lb;
    15. for(la=L-1;la>0;la--){
    16. if(a[la-1]!=0)
    17. break;
    18. }
    19. for(lb=L-1;lb>0;lb--){
    20. if(b[lb-1]!=0)
    21. break;
    22. }
    23. if(lb==0) return;
    24. for(int i=0;i
    25. for(int i=la-lb;i>=0;i--){
    26. while(big(d,b,i,lb)){
    27. for(int j=0;j
    28. d[i+j]-=b[j];
    29. if(d[i+j]<0){
    30. d[i+j+1]-=1;
    31. d[i+j]+=10;
    32. }
    33. }
    34. c[i]++;
    35. }
    36. }
    37. }

    高精度计算器(总结)

            到这里,我们的高精度计算就全部完成了。

            下面给出高精度计算器的代码:

    1. const int L=10000;
    2. string s;
    3. int a[L],b[L],c[L],d[L];
    4. void clear(int a[]){
    5. for(int i=0;i
    6. a[i]=0;
    7. }
    8. void read(int a[]){
    9. cin>>s;
    10. int L=s.size();
    11. for(int i=0;i
    12. a[i]=s[L-1-i]-'0';
    13. }
    14. void print(int a[]){
    15. int i;
    16. for(i=L-1;i>=1;i--){
    17. if(a[i]!=0)
    18. break;
    19. }
    20. for(;i>=0;i--)
    21. cout<
    22. cout<
    23. }
    24. void add(int a[],int b[],int c[]){
    25. clear(c);
    26. for(int i=0;i-1;++i){
    27. c[i]+=a[i]+b[i];
    28. if(c[i]>=10){
    29. c[i+1]+=1;
    30. c[i]-=10;
    31. }
    32. }
    33. }
    34. void sub(int a[],int b[],int c[]){
    35. clear(c);
    36. for(int i=0;i-1;++i){
    37. c[i]+=a[i]-b[i];
    38. if(c[i]<0){
    39. c[i+1]-=1;
    40. c[i]+=10;
    41. }
    42. }
    43. }
    44. void mul(int a[],int b[],int c[]){
    45. clear(c);
    46. for(int i=0;i-1;i++){
    47. for(int j=0;j<=i;j++)
    48. c[i]+=a[j]*b[i-j];
    49. if(c[i]>=10){
    50. c[i+1]+=c[i]/10;
    51. c[i]%=10;
    52. }
    53. }
    54. }
    55. bool big(int a[],int b[],int low,int L){
    56. if(a[low+L]!=0) return 1;
    57. for(int i=L-1;i>=0;--i){
    58. if(a[low+i]>b[i])
    59. return 1;
    60. if(a[low+i]
    61. return 0;
    62. }
    63. return 1;
    64. }
    65. void div(int a[],int b[],int c[],int d[]){
    66. clear(c);
    67. clear(d);
    68. int la,lb;
    69. for(la=L-1;la>0;la--){
    70. if(a[la-1]!=0)
    71. break;
    72. }
    73. for(lb=L-1;lb>0;lb--){
    74. if(b[lb-1]!=0)
    75. break;
    76. }
    77. if(lb==0) return;
    78. for(int i=0;i
    79. for(int i=la-lb;i>=0;i--){
    80. while(big(d,b,i,lb)){
    81. for(int j=0;j
    82. d[i+j]-=b[j];
    83. if(d[i+j]<0){
    84. d[i+j+1]-=1;
    85. d[i+j]+=10;
    86. }
    87. }
    88. c[i]++;
    89. }
    90. }
    91. }

    上一篇-高精度乘法的实现    C++算法基础专栏文章    下一篇-一维前缀和的实现


    每周六更新一篇文章,内容一般是自己总结的经验或是在其他网站上整理的优质内容

    点个赞,关注一下呗~

  • 相关阅读:
    编译时编程(Compile-Time Programming)
    Python中将列表拆分为大小为N的块
    自定义View实现波浪荡漾效果
    C++继承
    招投标系统软件源码,招投标全流程在线化管理
    LeetCode 热题 100 | 图论(二)
    05-SA8155 QNX SPI 全双工通讯
    团建游戏大全
    代码随想录day58|739. 每日温度496. 下一个更大元素 I
    猿创征文|Redis事务问题
  • 原文地址:https://blog.csdn.net/wyuchen123/article/details/137933929