1: #include "lint.h" 2: #ifndef lint 3: static char sccs_id[] = "@(#)mout.c 2.2 8/13/82"; 4: #endif lint 5: #include <ctype.h> 6: #include <stdio.h> 7: #include <ape.h> 8: m_out(a,b,f) /* output a base b onto file f */ 9: MINT *a; FILE *f; 10: { int sign,xlen,i,outlen; 11: short r; 12: MINT x; 13: char *obuf, *malloc(), *sprintf(), tempeh[7]; 14: register char *bp; 15: 16: sign=1; 17: xlen=a->len; 18: if(xlen<0) 19: { xlen= -xlen; 20: sign= -1; 21: } 22: if (xlen==0) 23: { fprintf(f,"0"); 24: return; 25: } 26: x.len=0; 27: move(a,&x); 28: x.len=xlen; /* now x is the absolute value of a */ 29: outlen=outlength(a,b); 30: obuf = malloc((unsigned)outlen); 31: /* Advance bp to the end of the buffer 32: * and start (end) with a null: */ 33: bp=obuf+outlen-1; 34: *bp--='\0'; 35: /* Now generate the digits in reverse 36: * order by taking remainders from 37: * successive divisions by the base b: */ 38: while(x.len>0) 39: { 40: sdiv(&x,b,&x,&r); 41: /* For bases greater than 16, the number 42: * is printed in "hybrid" notation as 43: * "clumps" of (base 10) numbers. 44: * For bases between 10 and 16, the 45: * letters abcdef are used for 10 through 15 46: */ 47: if (b>16) *bp-- = ' '; 48: if (r<10) *bp--=r+'0'; 49: else if (b<17) *bp-- = r+'a'-10; 50: else { 51: ignors(sprintf(tempeh,"%d",r)); 52: for (i=strlen(tempeh); i >0; --i) 53: *bp-- = tempeh[i-1]; 54: } 55: } 56: if (sign == -1) *bp-- = '-'; 57: fprintf(f,"%s",bp+1); 58: free(obuf); 59: xfree(&x); 60: return; 61: } 62: 63: sm_out(a,b,s) 64: PMINT a; 65: int b; 66: char *s; 67: { 68: int sign,xlen,i,outlen; 69: short r; 70: MINT x; 71: char *sprintf(), tempeh[7]; 72: register char *bp; 73: 74: sign=1; 75: xlen=a->len; 76: if(xlen<0) 77: { xlen= -xlen; 78: sign= -1; 79: } 80: if (xlen==0) 81: { 82: *s='0'; 83: *(s+1)='\0'; 84: return; 85: } 86: x.len=0; 87: move(a,&x); 88: x.len=xlen; /* now x is the absolute value of a */ 89: outlen = outlength(a,b); 90: /* Advance bp to the end of the string required 91: * and start (end) with a null: */ 92: bp = s+outlen-1; 93: *bp--='\0'; 94: /* Now generate the digits in reverse 95: * order by taking remainders from 96: * successive divisions by the base b: */ 97: while(x.len>0) 98: { 99: sdiv(&x,b,&x,&r); 100: /* For bases greater than 16, the number 101: * is printed in "hybrid" notation as 102: * "clumps" of (base 10) numbers. 103: * For bases between 10 and 16, the 104: * letters abcdef are used for 10 through 15 105: */ 106: if (b>16) *bp-- = ' '; 107: if (r<10) *bp--=r+'0'; 108: else if (b<17) *bp-- = r+'a'-10; 109: else { 110: ignors(sprintf(tempeh,"%d",r)); 111: for (i=strlen(tempeh); i >0; --i) 112: *bp-- = tempeh[i-1]; 113: } 114: } 115: if (sign == -1) *bp-- = '-'; 116: if ((++bp) != s) /* do we have to adjust the string? */ 117: { 118: if (bp < s) fprintf(stderr,"outlength estimate %d off by %d", 119: outlen,s-bp); /* OOPS! */ 120: else while (*bp != '\0') 121: *s++ = *bp++; /* move the string into the right 122: * place */ 123: } 124: xfree(&x); 125: return; 126: } 127: 128: outlength(a,b) 129: PMINT a; /* determine an approximation for the number of characters 130: * required to represent a base b. */ 131: int b; 132: { 133: int wordlen, alen; 134: 135: /* Determine the length of a single short int: 136: * Magic numbers are [log base b TOPSHORT] + 1 */ 137: switch(b) { 138: case 2: wordlen=15; break; 139: case 3: wordlen=10; break; 140: case 4: wordlen=8; break; 141: case 5: wordlen=7; break; 142: case 6: case 7: wordlen=6; 143: default: if (b<13) wordlen=5; 144: else if (b<17) wordlen=4; 145: else wordlen=12; /* ?? */ 146: break; 147: } 148: alen = (a->len > 0 ? a->len : -a->len); 149: return(wordlen*alen + 1); 150: } 151: 152: om_out(a,f) /* Output a base 8 onto file f; this is about 153: * thirty times faster than m_out(a,8,f) since 154: * sdiv needn't be invoked (numbers are stored 155: * base 2^15= 8^5, so conversion can be done 156: * word by word.) 157: */ 158: MINT *a; 159: FILE *f; 160: { 161: int alen; 162: 163: if (a->len <0) 164: { 165: putc('-',f); 166: alen = -a->len; 167: } 168: else alen = a->len; 169: if (alen == 0) 170: { 171: putc('0',f); 172: return; 173: } 174: --alen; 175: fprintf(f,"%o",a->val[alen--]); 176: while (alen >= 0) 177: fprintf(f,"%05o",a->val[alen--]); 178: } 179: 180: /* The following are some useful "special cases" for 181: the I/O routines: */ 182: 183: minput(a) MINT *a; 184: { 185: return(m_in(a,10,stdin)); 186: } 187: omin(a) MINT *a; 188: { 189: return(m_in(a,8,stdin)); 190: } 191: mout(a) MINT *a; 192: { 193: m_out(a,10,stdout); 194: } 195: omout(a) MINT *a; 196: { 197: om_out(a,stdout); 198: } 199: fmout(a,f) MINT *a; FILE *f; 200: { m_out(a,10,f); 201: } 202: fmin(a,f) MINT *a; FILE *f; 203: { 204: return(m_in(a,10,f)); 205: }