#include "lint.h" #ifndef lint static char sccs_id[] = "@(#)mout.c 2.2 8/13/82"; #endif lint #include #include #include m_out(a,b,f) /* output a base b onto file f */ MINT *a; FILE *f; { int sign,xlen,i,outlen; short r; MINT x; char *obuf, *malloc(), *sprintf(), tempeh[7]; register char *bp; sign=1; xlen=a->len; if(xlen<0) { xlen= -xlen; sign= -1; } if (xlen==0) { fprintf(f,"0"); return; } x.len=0; move(a,&x); x.len=xlen; /* now x is the absolute value of a */ outlen=outlength(a,b); obuf = malloc((unsigned)outlen); /* Advance bp to the end of the buffer * and start (end) with a null: */ bp=obuf+outlen-1; *bp--='\0'; /* Now generate the digits in reverse * order by taking remainders from * successive divisions by the base b: */ while(x.len>0) { sdiv(&x,b,&x,&r); /* For bases greater than 16, the number * is printed in "hybrid" notation as * "clumps" of (base 10) numbers. * For bases between 10 and 16, the * letters abcdef are used for 10 through 15 */ if (b>16) *bp-- = ' '; if (r<10) *bp--=r+'0'; else if (b<17) *bp-- = r+'a'-10; else { ignors(sprintf(tempeh,"%d",r)); for (i=strlen(tempeh); i >0; --i) *bp-- = tempeh[i-1]; } } if (sign == -1) *bp-- = '-'; fprintf(f,"%s",bp+1); free(obuf); xfree(&x); return; } sm_out(a,b,s) PMINT a; int b; char *s; { int sign,xlen,i,outlen; short r; MINT x; char *sprintf(), tempeh[7]; register char *bp; sign=1; xlen=a->len; if(xlen<0) { xlen= -xlen; sign= -1; } if (xlen==0) { *s='0'; *(s+1)='\0'; return; } x.len=0; move(a,&x); x.len=xlen; /* now x is the absolute value of a */ outlen = outlength(a,b); /* Advance bp to the end of the string required * and start (end) with a null: */ bp = s+outlen-1; *bp--='\0'; /* Now generate the digits in reverse * order by taking remainders from * successive divisions by the base b: */ while(x.len>0) { sdiv(&x,b,&x,&r); /* For bases greater than 16, the number * is printed in "hybrid" notation as * "clumps" of (base 10) numbers. * For bases between 10 and 16, the * letters abcdef are used for 10 through 15 */ if (b>16) *bp-- = ' '; if (r<10) *bp--=r+'0'; else if (b<17) *bp-- = r+'a'-10; else { ignors(sprintf(tempeh,"%d",r)); for (i=strlen(tempeh); i >0; --i) *bp-- = tempeh[i-1]; } } if (sign == -1) *bp-- = '-'; if ((++bp) != s) /* do we have to adjust the string? */ { if (bp < s) fprintf(stderr,"outlength estimate %d off by %d", outlen,s-bp); /* OOPS! */ else while (*bp != '\0') *s++ = *bp++; /* move the string into the right * place */ } xfree(&x); return; } outlength(a,b) PMINT a; /* determine an approximation for the number of characters * required to represent a base b. */ int b; { int wordlen, alen; /* Determine the length of a single short int: * Magic numbers are [log base b TOPSHORT] + 1 */ switch(b) { case 2: wordlen=15; break; case 3: wordlen=10; break; case 4: wordlen=8; break; case 5: wordlen=7; break; case 6: case 7: wordlen=6; default: if (b<13) wordlen=5; else if (b<17) wordlen=4; else wordlen=12; /* ?? */ break; } alen = (a->len > 0 ? a->len : -a->len); return(wordlen*alen + 1); } om_out(a,f) /* Output a base 8 onto file f; this is about * thirty times faster than m_out(a,8,f) since * sdiv needn't be invoked (numbers are stored * base 2^15= 8^5, so conversion can be done * word by word.) */ MINT *a; FILE *f; { int alen; if (a->len <0) { putc('-',f); alen = -a->len; } else alen = a->len; if (alen == 0) { putc('0',f); return; } --alen; fprintf(f,"%o",a->val[alen--]); while (alen >= 0) fprintf(f,"%05o",a->val[alen--]); } /* The following are some useful "special cases" for the I/O routines: */ minput(a) MINT *a; { return(m_in(a,10,stdin)); } omin(a) MINT *a; { return(m_in(a,8,stdin)); } mout(a) MINT *a; { m_out(a,10,stdout); } omout(a) MINT *a; { om_out(a,stdout); } fmout(a,f) MINT *a; FILE *f; { m_out(a,10,f); } fmin(a,f) MINT *a; FILE *f; { return(m_in(a,10,f)); }