|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <ctype.h> ! 3: #include "bc.h" ! 4: ! 5: /* ! 6: * Getnum reads in a number from standard input. It allows one ! 7: * radix point and sets the scale field of the number accordingly. ! 8: * If ibase==10, it recognizes leading '0' for octal 8 and '0x' for hex. ! 9: */ ! 10: ! 11: rvalue * ! 12: getnum(ch) ! 13: register int ch; ! 14: { ! 15: register rvalue *result; ! 16: register FILE *inf = infile; ! 17: mint dig; ! 18: int val; ! 19: int dot; ! 20: int savbase; ! 21: ! 22: result = (rvalue *)mpalc(sizeof *result); ! 23: newscalar(result); ! 24: minit(&dig); ! 25: savbase = ibase; ! 26: if (ibase <= 10 && ch == '0' && (ch = getc(inf)) != '.') { ! 27: if (ch == 'x') { ! 28: ch = getc(inf); ! 29: ibase = 16; ! 30: } else ! 31: ibase = 8; ! 32: } ! 33: for (dot = FALSE;; ch = getc(inf)) { ! 34: if ((val = digit(ch)) < ibase) { ! 35: mitom(val, &dig); ! 36: smult(&result->mantissa, ibase, &result->mantissa); ! 37: madd(&result->mantissa, &dig, &result->mantissa); ! 38: if (dot) ! 39: ++result->scale; ! 40: } else if (ch == '.' & !dot) ! 41: dot = TRUE; ! 42: else ! 43: break; ! 44: } ! 45: ungetc(ch, inf); ! 46: mvfree(&dig); ! 47: /* Rescale into decimal if necessary, losing some precision */ ! 48: if (ibase != 10) for (dot = result->scale; dot != 0; dot -= 1) { ! 49: smult(&result->mantissa, 10, &result->mantissa); ! 50: sdiv(&result->mantissa, ibase, &result->mantissa, &val); ! 51: } ! 52: ibase = savbase; ! 53: return (result); ! 54: } ! 55: ! 56: /* ! 57: * Digit maps characters to digit values. ! 58: */ ! 59: digit(c) register int c; ! 60: { ! 61: if (isascii(c)) { ! 62: if (isdigit(c)) ! 63: return c - '0'; ! 64: if (islower(c)) ! 65: return c - 'a' + 10; ! 66: if (isupper(c)) ! 67: return c - 'A' + 10; ! 68: } ! 69: return ibase; ! 70: } ! 71: ! 72: /* ! 73: * Sibase takes the rvalue pointed to by lval and set ibase ! 74: * to it if it is in range (ie. between 2 and 16). ! 75: */ ! 76: ! 77: sibase(lval) ! 78: rvalue *lval; ! 79: { ! 80: register int base; ! 81: ! 82: base = rtoint(lval); ! 83: if (2 > base || base > 16) ! 84: bcmerr("Invalid input base"); ! 85: ibase = base; ! 86: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.