home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 247_01 / bnio1.c < prev    next >
Text File  |  1989-04-19  |  6KB  |  257 lines

  1. /*
  2.  *   MIRACL I/O routines 1. 
  3.  *   bnio1.c
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "miracl.h"
  8.  
  9. /* Access global variables */
  10.  
  11. extern small base;   /* number base        */
  12. extern small apbase; /* apparent base      */
  13. extern int depth;    /* error tracing ..   */
  14. extern int trace[];  /* .. mechanism       */
  15. extern int pack;     /* packing density    */
  16. extern int nib;      /* length of bigs     */
  17. extern bool check;   /* overflow check     */
  18.  
  19. extern big w1;        /* workspace variables */
  20. extern big w2;
  21. extern big w3;
  22. extern big w4;
  23. extern big w5;
  24. extern big w6;
  25. extern big w0;
  26.  
  27. int innum(x,filep)
  28. flash x;
  29. FILE *filep;
  30. {  /*  input a big number       *
  31.     *  returns length in digits */
  32.     int i,ipt,n,s,e,ch;
  33.     bool frac;
  34.     if (ERNUM) return 0;
  35.     depth++;
  36.     trace[depth]=1;
  37.     if (TRACER) track();
  38.     if (apbase>256)
  39.     {
  40.         berror(1);
  41.         depth--;
  42.         return 0;
  43.     }
  44.     zero(x);
  45.     if (INPLEN==0)
  46.     { /* inputting ASCII bytes */
  47.         if (IBUFF[0]==0) fgets(IBUFF,IBSIZ+1,filep);
  48.         forever
  49.         { /*  get input length  */
  50.             ch=IBUFF[INPLEN];
  51.             if (ch=='\0' || ch==EOF) break;
  52.             if (apbase<=60 && ch=='\n') break;
  53.             INPLEN++;
  54.             if (INPLEN>=IBSIZ)
  55.             {
  56.                 berror(17);
  57.                 depth--;
  58.                 return 0;
  59.             }
  60.         }
  61.     }
  62.     else
  63.     { /* inputting BINARY bytes */
  64.         if (INPLEN>=IBSIZ)
  65.         {
  66.             berror(17);
  67.             depth--;
  68.             return 0;
  69.         }
  70.         if (IBUFF[0]==0) for(i=0;i<INPLEN;i++) IBUFF[i]=fgetc(filep);
  71.     }
  72.     n=0;
  73.     s=PLUS;
  74.     e=0;
  75.     frac=FALSE;
  76.     if (INPLEN>0 && apbase<=60)
  77.     { /* skip leading blanks and check sign */
  78.         if (IBUFF[INPLEN-1]=='/') INPLEN--;
  79.         while (IBUFF[e]==' ') e++;
  80.         if (IBUFF[e]=='-')
  81.         { /* check sign */
  82.              s=MINUS;
  83.              e++;
  84.         }
  85.         if (IBUFF[e]=='+') e++;
  86.     }
  87.     for (i=INPLEN-1;i>=e;i--)
  88.     {
  89.         ch=IBUFF[i];
  90.         if (apbase<=60)
  91.         { /* check for slash or dot and convert character to number */
  92.             if (!frac)
  93.             {
  94.                 if (ch=='/')
  95.                 {
  96.                     frac=TRUE;
  97.                     copy(x,w0);
  98.                     zero(x);    
  99.                     n=0;
  100.                     continue;
  101.                 }
  102.                 if (ch=='.')
  103.                 {
  104.                     frac=TRUE;
  105.                     zero(w0);
  106.                     putdig(1,w0,n+1);
  107.                     continue;
  108.                 }
  109.             }
  110.             ch+=80;
  111.             if (ch>127 && ch<138) ch-=128;
  112.             if (ch>144 && ch<171) ch-=135;
  113.             if (ch>176 && ch<203) ch-=141;
  114.         }
  115.         if (ch>=apbase)
  116.         {
  117.             berror(5);
  118.             depth--;
  119.             return 0;
  120.         }
  121.         n++;
  122.         putdig(ch,x,n);
  123.     }
  124.     ipt=INPLEN;
  125.     IBUFF[0]=0;
  126.     INPLEN=0;
  127.     insign(s,x);
  128.     lzero(x);
  129.     lzero(w0);
  130.     if (frac) fpack(x,w0,x);
  131.     depth--;
  132.     return ipt;
  133. }
  134.  
  135. int otnum(x,filep)
  136. flash x;
  137. FILE *filep;
  138. {  /*  output a big number  */
  139.     int s,i,n,ch,rp,nd,m,nw,dw;
  140.     small lx;
  141.     bool done;
  142.     if (ERNUM) return 0;
  143.     depth++;
  144.     trace[depth]=2;
  145.     if (TRACER) track();
  146.     if (apbase>256)
  147.     {
  148.         berror(1);
  149.         depth--;
  150.         return 0;
  151.     }
  152.     n=0;
  153.     s=exsign(x);
  154.     insign(PLUS,x);
  155.     lx = x[0];
  156.     if (lx==0 && apbase<=60)
  157.     {
  158.         if (STROUT)
  159.         {
  160.             OBUFF[0]='0';
  161.             OBUFF[1]='\0';
  162.         }
  163.         else
  164.         {
  165.             putc('0',filep);
  166.             putc('\n',filep);
  167.         }
  168.         depth--;
  169.         return 1;
  170.     }
  171.     done=FALSE;
  172.     rp=0;
  173.     numer(x,w1);
  174.     if (s==MINUS && apbase<=60)
  175.     {
  176.         if (STROUT) OBUFF[n]='-';
  177.         else putc('-',filep);
  178.         n++;
  179.     }
  180.     if (POINT)
  181.     { /* output with radix point */
  182.         denom(x,w2);
  183.         if (size(w2)>1)
  184.         { /* multiply up numerator to get full precision in *
  185.            * the output. Remember position of radix point.  */
  186.             nw=(lx&MSK);
  187.             dw=((lx>>BTS)&MSK);
  188.             if (nw==0) nw++;
  189.             if (nw>dw) shift(w2,nw-dw,w2);
  190.             if (dw>nw) shift(w1,dw-nw,w1);
  191.             nd=nib;
  192.             if (compare(w1,w2)>=0) nd--;
  193.             check=OFF;
  194.             copy(w1,w0);
  195.             shift(w0,nd,w0);
  196.             divide(w0,w2,w1);
  197.             check=ON;
  198.             rp=pack*(nd+dw-nw);
  199.         }
  200.     }
  201.     forever
  202.     {
  203.         nd=numdig(w1);
  204.         m=nd;
  205.         if (rp>m) m=rp;
  206.         for (i=m;i>0;i--)
  207.         { 
  208.             if (STROUT && n>=OBSIZ-3)
  209.             {
  210.                 berror(17);
  211.                 depth--;
  212.                 return n;
  213.             }
  214.             if (i==rp && apbase<=60)
  215.             {
  216.                 if (STROUT) OBUFF[n]='.';
  217.                 else putc('.',filep);
  218.                 n++;
  219.             }
  220.             if (i>nd) ch='0';
  221.             else
  222.             {
  223.                 ch=getdig(w1,i);
  224.                 putdig(0,w1,i);
  225.                 if (apbase<=60)
  226.                 { /* convert number to character */
  227.                     ch+=48;
  228.                     if (ch>=58) ch+=7;
  229.                     if (ch>=91) ch+=6;
  230.                 }
  231.             }
  232.             if (i<rp && apbase<=60 && ch=='0' && size(w1)==0) break;
  233.             if (STROUT) OBUFF[n]=(char)ch;
  234.             else putc((char)ch,filep);
  235.             n++;
  236.             if (!STROUT && apbase<=60 && WRAP && (n%(LINE-2)==0))
  237.                                                        fputs("-\n",filep);
  238.         }
  239.         if (done) break;
  240.         denom(x,w1);
  241.         if (POINT || size(w1)==1) break;
  242.         if (apbase<=60)
  243.         {
  244.             if (STROUT) OBUFF[n]='/';
  245.             else putc('/',filep);
  246.             n++;
  247.         }
  248.         done=TRUE;
  249.     }
  250.     if (STROUT) OBUFF[n]='\0';
  251.     else if(apbase<=60) putc('\n',filep);
  252.     insign(s,x);
  253.     depth--;
  254.     return n;
  255. }
  256.  
  257.