1: /*
   2:  * Copyright (c) 1982 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: static char sccsid[] = "@(#)natof.c	5.1 (Berkeley) 4/30/85";
   9: #endif not lint
  10: 
  11: #include <stdio.h>
  12: #include <ctype.h>
  13: #include <errno.h>
  14: 
  15: #include "as.h"
  16: 
  17: Bignum bigatof(str, radix)
  18:     reg char    *str;       /* r11 */
  19:         int radix;      /* TYPF ... TYPH */
  20: {
  21:         int msign;
  22:         int esign;
  23:         int decpt;
  24:     reg chptr   temp;       /* r10 */
  25:     reg u_int   quotient;   /* r9 */    /* must be here */
  26:     reg u_int   remainder;  /* r8 */    /* must be here */
  27:     reg chptr   acc;
  28:     reg int dividend;   /* for doing division */
  29:     reg u_int   i;
  30:         short   *sptr;      /* for doing division */
  31:         int ch;
  32:         int dexponent;  /* decimal exponent */
  33:         int bexponent;  /* binary exponent */
  34:         Bignum  Acc;
  35:         Bignum  Temp;
  36:     static  Bignum  znumber;
  37:         Ovf ovf;
  38:         u_int   j;
  39:     extern  int errno;
  40:         u_int   ediv();
  41: 
  42: #ifdef lint
  43:     quotient = 0;
  44:     remainder = 0;
  45: #endif lint
  46:     msign = 0;
  47:     esign = 0;
  48:     decpt = 0;
  49:     dexponent = 0;
  50:     Acc = znumber;
  51:     Acc.num_tag = radix;
  52:     acc = CH_FIELD(Acc);
  53:     temp = CH_FIELD(Temp);
  54: 
  55:     do{
  56:         ch = *str++;
  57:     } while(isspace(ch));
  58: 
  59:     switch(ch){
  60:     case '-':
  61:         msign = -1;
  62:         /* FALLTHROUGH */
  63:     case '+':
  64:         ch = *str++;
  65:         break;
  66:     }
  67:   dofract:
  68:     for(; isdigit(ch); ch = *str++){
  69:         assert(((acc[HOC] & SIGNBIT) == 0), "Negative HOC");
  70:         if (acc[HOC] < MAXINT_10){
  71:             ovf = numshift(3, temp, acc);
  72:             ovf |= numshift(1, acc, acc);
  73:             ovf |= numaddv(acc, temp, acc);
  74:             ovf |= numaddd(acc, acc, ch - '0');
  75:             assert(ovf == 0, "Overflow building mantissa");
  76:         } else {
  77:             /*
  78: 			 *	Then, the number is too large anyway
  79: 			 */
  80:             dexponent++;
  81:         }
  82:         if (decpt)
  83:             dexponent--;
  84:     }
  85:     switch(ch){
  86:     case '.':
  87:         if (decpt == 0){
  88:             decpt++;
  89:             ch = *str++;
  90:             goto dofract;
  91:         }
  92:         break;
  93:     /*
  94: 	 *	only 'e' and 'E' are recognized by atof()
  95: 	 */
  96:     case 'e':
  97:     case 'E':
  98:     /*
  99: 	 *	we include the remainder for compatability with as formats
 100: 	 *	in as, the radix actual paramater agrees with the character
 101: 	 *	we expect; consequently, no checking is done.
 102: 	 */
 103:     case 'd':
 104:     case 'D':
 105:     case 'g':
 106:     case 'G':
 107:     case 'h':
 108:     case 'H':
 109:         j = 0;
 110:         ch = *str++;
 111:         esign = 0;
 112:         switch(ch){
 113:         case '-':
 114:             esign = 1;
 115:             /* FALLTHROUGH */
 116:         case '+':
 117:             ch = *str++;
 118:         }
 119:         for(; isdigit(ch); ch = *str++){
 120:             if (j < MAXINT_10){
 121:                 j *= 10;
 122:                 j += ch - '0';
 123:             } else {
 124:                 /*
 125: 				 *	outrageously large exponent
 126: 				 */
 127:                  /*VOID*/
 128:             }
 129:         }
 130:         if (esign)
 131:             dexponent -= j;
 132:         else
 133:             dexponent += j;
 134:         /*
 135: 		 *	There should be a range check on dexponent here
 136: 		 */
 137:     }
 138:     /*
 139: 	 *	The number has now been reduced to a mantissa
 140: 	 *	and an exponent.
 141: 	 *	The mantissa is an n bit number (to the precision
 142: 	 *	of the extended words) in the acc.
 143: 	 *	The exponent is a signed power of 10 in dexponent.
 144: 	 *	msign is on if the resulting number will eventually
 145: 	 *	be negative.
 146: 	 *
 147: 	 *	We now must convert the number to standard format floating
 148: 	 *	number, which will be done by accumulating
 149: 	 *	a binary exponent in bexponent, as we gradually
 150: 	 *	drive dexponent towards zero, one count at a time.
 151: 	 */
 152:     if (isclear(acc)){
 153:         return(Acc);
 154:     }
 155:     bexponent = 0;
 156: 
 157:     /*
 158: 	 *	Scale the number down.
 159: 	 *	We must divide acc by 10 as many times as needed.
 160: 	 */
 161:     for (; dexponent < 0; dexponent++){
 162:         /*
 163: 		 *	Align the number so that the most significant
 164: 		 *	bits are aligned in the most significant
 165: 		 *	bits of the accumulator, adjusting the
 166: 		 *	binary exponent as we shift.
 167: 		 *	The goal is to get the high order bit (NOT the
 168: 		 *	sign bit) set.
 169: 		 */
 170:         assert(((acc[HOC] & SIGNBIT) == 0), "Negative HOC");
 171:         ovf = 0;
 172: 
 173:         for (j = 5; j >= 1; --j){
 174:             i = 1 << (j - 1);       /* 16, 8, 4, 2, 1 */
 175:             quotient = ONES(i);
 176:             quotient <<= (CH_BITS - 1) - i;
 177:             while((acc[HOC] & quotient) == 0){
 178:                 ovf |= numshift((int)i, acc, acc);
 179:                 bexponent -= i;
 180:             }
 181:         }
 182:         /*
 183: 		 *	Add 2 to the accumulator to effect rounding,
 184: 		 *	and get set up to divide by 5.
 185: 		 */
 186:         ovf = numaddd(acc, acc, 2);
 187:         assert(ovf == 0, "Carry out of left rounding up by 2");
 188:         /*
 189: 		 *	Divide the high order chunks by 5;
 190: 		 *	The last chunk will be divided by 10,
 191: 		 *	(to see what the remainder is, also to effect rounding)
 192: 		 *	and then multipiled by 2 to effect division by 5.
 193: 		 */
 194:         remainder = 0;
 195: #if DEBUGNATOF
 196:         printf("Dividing: ");
 197:         bignumprint(Acc);
 198:         printf("\n");
 199: #endif DEBUGNATOF
 200:         sptr = (short *)acc;
 201:         for (i = (CH_N * 2 - 1); i >= 1; --i){
 202:             /*
 203: 			 *	Divide (remainder:16).(acc[i]:16)
 204: 			 *	by 5, putting the quotient back
 205: 			 *	into acc[i]:16, and save the remainder
 206: 			 *	for the next iteration.
 207: 			 */
 208:             dividend = (remainder << 16) | (sptr[i] & ONES(16));
 209:             assert(dividend >= 0, "dividend < 0");
 210:             quotient = dividend / 5;
 211:             remainder = dividend - (quotient * 5);
 212:             sptr[i] = quotient;
 213:             remainder = remainder;
 214:         }
 215:         /*
 216: 		 *	Divide the lowest order chunk by 10,
 217: 		 *	saving the remainder to decide how to round.
 218: 		 *	Then, multiply by 2, making it look as
 219: 		 *	if we divided by 10.
 220: 		 *	This multiply fills in a 0 on the least sig bit.
 221: 		 */
 222:         dividend = (remainder << 16) | (sptr[0] & ONES(16));
 223:         assert(dividend >= 0, "dividend < 0");
 224:         quotient = dividend / 10;
 225:         remainder = dividend - (quotient * 10);
 226:         sptr[0] = quotient + quotient;
 227: 
 228:         if (remainder >= 5)
 229:             ovf = numaddd(acc, acc, 1);
 230:         /*
 231: 		 *	Now, divide by 2, effecting division by 10,
 232: 		 *	merely by adjusting the binary exponent.
 233: 		 */
 234:         bexponent--;
 235:     }
 236:     /*
 237: 	 *	Scale the number up by multiplying by 10 as
 238: 	 *	many times as necessary
 239: 	 */
 240:     for (; dexponent > 0; dexponent--){
 241:         /*
 242: 		 *	Compare high word to (2**31)/5,
 243: 		 *	and scale accordingly
 244: 		 */
 245:         while ( ((unsigned)acc[HOC]) > MAXINT_5){
 246:             (void)numshift(-1, acc, acc);
 247:             bexponent++;
 248:         }
 249:         /*
 250: 		 *	multiply the mantissa by 5,
 251: 		 *	and scale the binary exponent by 2
 252: 		 */
 253:         ovf = numshift(2, temp, acc);
 254:         ovf |= numaddv(acc, acc, temp);
 255:         assert(ovf == 0, "Scaling * 10 of manitissa");
 256:         bexponent++;
 257:     }
 258:     /*
 259: 	 *	We now have:
 260: 	 *	a CH_N chunk length binary integer, right
 261: 	 *		justified (in native format).
 262: 	 *	a binary exponent.
 263: 	 *
 264: 	 *	Now, we treat this large integer as an octa word
 265: 	 *	number, and unpack it into standard unpacked
 266: 	 *	format.  That unpacking will give us yet
 267: 	 *	another binary exponent, which we adjust with
 268: 	 *	the accumulated binary exponent.
 269: 	 */
 270:     Acc.num_tag = TYPO;
 271: #if DEBUGNATOF
 272:     printf("Octal number: ");
 273:     bignumprint(Acc);
 274:     printf("\n");
 275: #endif DEBUGNATOF
 276:     Acc = bignumunpack(Acc, &ovf);
 277: 
 278:     if (ovf)
 279:         errno = ERANGE;
 280: #if DEBUGNATOF
 281:     printf("Unpacked octal number: ");
 282:     bignumprint(Acc);
 283:     printf("bexponent == %d\n", bexponent);
 284: #endif DEBUGNATOF
 285:     Acc.num_exponent += bexponent;
 286:     assert(Acc.num_sign == 0, "unpacked integer is < 0");
 287:     Acc.num_sign = msign;
 288:     /*
 289: 	 *	We now pack the number back into a radix format number.
 290: 	 *	This checks for overflow, underflow,
 291: 	 *	and rounds by 1/2 ulp.
 292: 	 */
 293:     ovf = 0;
 294:     Acc = bignumpack(Acc, radix, &ovf);
 295:     if (ovf)
 296:         errno = ERANGE;
 297: #if DEBUGNATOF
 298:     printf("packed number: ");
 299:     bignumprint(Acc);
 300:     printf("\n");
 301: #endif DEBUGNATOF
 302:     return(Acc);
 303: }
 304: #if 0
 305: /*
 306:  *	Unfortunately, one can't use the ediv instruction to do
 307:  *	division on numbers with > 64 bits.
 308:  *	This is because ediv returns signed quantities;
 309:  *	if the quotient is an unsigned number > 2^31,
 310:  *	ediv sets integer overflow.
 311:  */
 312: unsigned int ediv(high, low, divisor, qp, i)
 313:     register    unsigned int    high;       /* r11 */
 314:     register    unsigned int    low;        /* r10 */
 315:     register    unsigned int    divisor;    /* r9 */
 316:             unsigned int    *qp;
 317: {
 318:     register    unsigned int    remainder;  /* r8 */
 319:     register    unsigned int    quotient;   /* r7 */
 320: 
 321:     asm("ediv r9, r10, r7, r8	# Divide.  q->r7, r->r8 (discarded)");
 322:     *qp = quotient;
 323:     return(remainder);
 324: }
 325: #endif 0

Defined functions

bigatof defined in line 17; used 2 times
ediv defined in line 312; used 1 times
  • in line 40

Defined variables

sccsid defined in line 8; never used
Last modified: 1985-04-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1212
Valid CSS Valid XHTML 1.0 Strict