zoukankan      html  css  js  c++  java
  • [复习]高精度算法

    今天又复习了一下高精度(高精度减、加、乘)

    仍然用结构体来存储

    数据结构:

    typedef struct HP{

             int w[10001]             //储存数据,0下标储存有多少位

    }HP;

    注意:高精度为了进位需要反着存储

    例如:原数             a     123   -int

           高精度数          b       3 |2|1 –int[]

    1. 加法

    先将最大的位数+1,然后按位相加,每次加完进位,最后删除前导0

    1. 减法

    和高精度加法类似,相当于就是加上一个负数,只是需要借位

    在之前需要预处理一下,一定保证用大数减小数

    1. 乘法

    虽然复习的是高精度乘单精度,但是我还是觉得直接用高精度乘比较简单

    例如下面这个竖式:

           1    2    3

      ×         1    2

    -------------------------

           2    4    6

      1    2    3

    ------------------------

      1    4    7    6

    我们可以发现当HP a与HP b相乘时,a[i]*b[j]得到的是(i + j - 1)位上的数

    下面附上源代码:

      1 /*
      2 
      3  * [输入文件] hp.in
      4 
      5  * 共三行
      6 
      7  * 第一行和第二行是两个高精度数
      8 
      9  * 第三行是一个符号(+ -或*)
     10 
     11  * [输出文件] hp.out
     12 
     13  * 仅一行,运算的结果
     14 
     15  */
     16 
     17 #include<iostream>
     18 
     19 #include<string>
     20 
     21 #include<cstring>
     22 
     23 #include<cstdio>
     24 
     25 using namespace std;
     26 
     27 FILE *fp;
     28 
     29 #ifndef _HPDEF_H_
     30 
     31 #define _HPDEF_H_
     32 
     33 typedef int HPI;
     34 
     35 //高精度类
     36 
     37 typedef struct
     38 
     39 {
     40 
     41       int w[10005];    
     42 
     43 }HP;
     44 
     45 #endif
     46 
     47 #ifndef _HP_H_
     48 
     49 #define _HP_H_
     50 
     51 //带成员函数的hp类
     52 
     53 class hp{
     54 
     55       public:
     56 
     57       static HP hps(string str);
     58 
     59       static HP add(HP *p1,HP *p2);
     60 
     61       static HPI cmp(HP *p1,HP *p2);
     62 
     63       static HP rem(HP *p1,HP *p2);
     64 
     65       static void fout(HP *p);
     66 
     67       static HP chen(HP *p1,HP *p2);
     68 
     69 }hp;
     70 
     71 /**
     72 
     73  * 将字符串转化成高精度数
     74 
     75  * @param str 要转化的字符串
     76 
     77  * @return 转化后的高精度数
     78 
     79  */
     80 
     81 HP hp::hps(string str)
     82 
     83 {
     84 
     85       HP h;
     86 
     87       memset(h.w,0,sizeof(h.w));
     88 
     89       h.w[0]=str.size();
     90 
     91       for(int i=h.w[0];i>=1;i--){
     92 
     93            h.w[i]=str[(h.w[0]-i)]-'0';
     94 
     95       }
     96 
     97       return h;
     98 
     99 }
    100 
    101 /**
    102 
    103  * 将两个高精度数相加
    104 
    105  * @param p1 第一个高精度数的地址
    106 
    107  * @param p2 第二个高精度数的地址
    108 
    109  * @return 计算的结果
    110 
    111  */
    112 
    113 HP hp::add(HP *p1,HP *p2)
    114 
    115 {
    116 
    117       HP p;
    118 
    119       memset(p.w,0,sizeof(p.w));
    120 
    121       if(p1->w[0]>p2->w[0]) p.w[0]=p1->w[0];
    122 
    123       else p.w[0]=p2->w[0];
    124 
    125       for(int i=1;i<=p.w[0];i++){
    126 
    127            p.w[i]+=p1->w[i]+p2->w[i];
    128 
    129            p.w[i+1]+=p.w[i]/10;
    130 
    131            p.w[i]%=10;
    132 
    133       }
    134 
    135       p.w[0]+=2;
    136 
    137       while(p.w[0]>1&&p.w[p.w[0]]==0) p.w[0]--;
    138 
    139       return p;
    140 
    141 }
    142 
    143 /**
    144 
    145  * 比较两个高精度数的大小
    146 
    147  * @param p1 第一个高精度数的地址
    148 
    149  * @param p2 第二个高精度数的地址
    150 
    151  * @return 当*p1大于*p2时,返回1,<br>
    152 
    153  *           当*p1小于*p2时,返回-1,<br>
    154 
    155  *         否则返回0
    156 
    157  */ 
    158 
    159 HPI hp::cmp(HP *p1,HP *p2){
    160 
    161       if(p1->w[0]>p2->w[0]) return 1;
    162 
    163       else if(p1->w[0]<p2->w[0]) return -1;
    164 
    165       for(int i=p1->w[0];i>=1;i--){
    166 
    167            if(p1->w[i]>p2->w[i])
    168 
    169                  return 1;
    170 
    171            else if(p1->w[i]<p2->w[i])
    172 
    173                  return -1;
    174 
    175       }
    176 
    177       return 0;
    178 
    179 }
    180 
    181 /**
    182 
    183  * 将高精度数输出到文件流fp中
    184 
    185  * @param p 要输出的高精度数的地址
    186 
    187  */
    188 
    189 void hp::fout(HP *p){
    190 
    191       for(int i=p->w[0];i>=1;i--)
    192 
    193       fprintf(fp,"%d",p->w[i]);
    194 
    195 }
    196 
    197 /**
    198 
    199  * 将两个高精度数相减
    200 
    201  * @param p1 被减高精度数的地址
    202 
    203  * @param p2 减高精度数的地址
    204 
    205  * @return 计算的结果
    206 
    207  */
    208 
    209 HP hp::rem(HP *p1,HP *p2){
    210 
    211       HP p;
    212 
    213       memset(p.w,0,sizeof(p.w));
    214 
    215       p.w[0]=p1->w[0];
    216 
    217       for(int i=1;i<=p.w[0];i++){
    218 
    219            if(p1->w[i]<p2->w[i]){
    220 
    221                  p1->w[i]+=10;
    222 
    223                  p1->w[i+1]--;
    224 
    225            }
    226 
    227            p.w[i]=p1->w[i]-p2->w[i];
    228 
    229       }
    230 
    231       while(p.w[0]>1&&p.w[p.w[0]]==0) p.w[0]--;
    232 
    233       return p;
    234 
    235 }
    236 
    237 /**
    238 
    239  * 将两个高精度数相乘
    240 
    241  * @param p1 第一个高精度数的地址
    242 
    243  * @param p2 第二个高精度数的地址
    244 
    245  * @return 计算的结果
    246 
    247  */
    248 
    249 HP hp::chen(HP *p1,HP *p2){
    250 
    251       HP p;
    252 
    253       memset(p.w,0,sizeof(p.w));
    254 
    255       p.w[0]=p1->w[0]+p2->w[0];
    256 
    257       for(int i=1;i<=p1->w[0];i++){
    258 
    259            for(int j=1;j<=p2->w[0];j++){
    260 
    261                  p.w[i+j-1]+=p1->w[i]*p2->w[j];
    262 
    263                  p.w[i+j]+=p.w[i+j-1]/10;
    264 
    265                  p.w[i+j-1]%=10;
    266 
    267            }
    268 
    269       }
    270 
    271       p.w[0]+=2;
    272 
    273       while(p.w[0]>1&&p.w[p.w[0]]==0) p.w[0]--;
    274 
    275       return p;
    276 
    277 }
    278 
    279 #endif
    280 
    281 int main(int argc,char* argv[])
    282 
    283 {
    284 
    285       freopen("gjc1.in","r",stdin);
    286 
    287       fp=fopen("gjc1.out","w");
    288 
    289       //局部变量定义
    290 
    291       string str1,str2;
    292 
    293       HP hp1,hp2,hp3;
    294 
    295       char fu;
    296 
    297       cin>>str1>>str2>>fu;
    298 
    299       //转化字符串
    300 
    301       hp1=hp::hps(str1);
    302 
    303       hp2=hp::hps(str2);
    304 
    305       fu = '*';
    306 
    307       //计算
    308 
    309       switch(fu){
    310 
    311            case '+':
    312 
    313                  hp3=hp::add(&hp1,&hp2);
    314 
    315                  break;
    316 
    317            case '-':
    318 
    319                  switch(hp::cmp(&hp1,&hp2)){
    320 
    321                       case 1:
    322 
    323                             hp3=hp::rem(&hp1,&hp2);
    324 
    325                             break;
    326 
    327                       case 0:
    328 
    329                             fprintf(fp,"0");
    330 
    331                             return 0;
    332 
    333                       case -1:
    334 
    335                             hp3=hp::rem(&hp2,&hp1);
    336 
    337                             fprintf(fp,"-");
    338 
    339                             break;
    340 
    341                  }
    342 
    343                  break;
    344 
    345             case '*':
    346 
    347                  hp3=hp::chen(&hp1,&hp2);
    348 
    349                  break;
    350 
    351       }
    352 
    353       hp::fout(&hp3);
    354 
    355       return 0;
    356 
    357 }
  • 相关阅读:
    Oracle Dataguard原理
    [转]TOKUDB® VS. INNODB FLASH MEMORY
    [转]什么是简约设计
    [转]DAS、NAS、SAN存储系统分析
    [转]ocp|ocm考证系列文章!
    [转]数据库范式的设计
    Block Media Recovery, BMR
    [转]开启闪回以及闪回的四种原理
    [转]Oracle DB 执行表空间时间点恢复
    Losing All Members of an Online Redo Log Group
  • 原文地址:https://www.cnblogs.com/yyf0309/p/5657304.html
Copyright © 2011-2022 走看看