|
|
1.1 ! root 1: # include <sccs.h> ! 2: ! 3: SCCSID(@(#)ftoa.c 8.1 12/31/84) ! 4: ! 5: # define MAXDIG 25 ! 6: ! 7: /* ! 8: ** FLOATING POINT TO ASCII CONVERSION ! 9: ** ! 10: ** 'Value' is converted to an ascii character string and stored ! 11: ** into 'ascii'. Ascii should have room for at least 'width' + 1 ! 12: ** characters. 'Width' is the width of the output field (max). ! 13: ** 'Prec' is the number of characters to put after the decimal ! 14: ** point. The format of the output string is controlled by ! 15: ** 'format'. ! 16: ** ! 17: ** 'Format' can be: ! 18: ** e or E: "E" format output ! 19: ** f or F: "F" format output ! 20: ** g or G: "F" format output if it will fit, otherwise ! 21: ** use "E" format. ! 22: ** n or N: same as G, but decimal points will not always ! 23: ** be aligned. ! 24: ** ! 25: ** If 'format' is upper case, the "E" comes out in upper case; ! 26: ** otherwise it comes out in lower case. ! 27: ** ! 28: ** When the field width is not big enough, it fills the field with ! 29: ** stars ("*****") and returns zero. Normal return is the width ! 30: ** of the output field (sometimes shorter than 'width'). ! 31: */ ! 32: ! 33: ftoa(value, ascii, width, prec1, format) ! 34: double value; ! 35: char *ascii; ! 36: int width; ! 37: int prec1; ! 38: char format; ! 39: { ! 40: auto int expon; ! 41: auto int sign; ! 42: register int avail; ! 43: register char *a; ! 44: register char *p; ! 45: char mode; ! 46: int lowercase; ! 47: int prec; ! 48: extern char *ecvt(), *fcvt(); ! 49: ! 50: prec = prec1; ! 51: mode = format; ! 52: lowercase = 'a' - 'A'; ! 53: if (mode >= 'a') ! 54: mode -= 'a' - 'A'; ! 55: else ! 56: lowercase = 0; ! 57: ! 58: if (mode != 'E') ! 59: { ! 60: /* try 'F' style output */ ! 61: p = fcvt(value, prec, &expon, &sign); ! 62: avail = width; ! 63: a = ascii; ! 64: ! 65: /* output sign */ ! 66: if (sign) ! 67: { ! 68: avail--; ! 69: *a++ = '-'; ! 70: } ! 71: ! 72: /* output '0' before the decimal point */ ! 73: if (expon <= 0) ! 74: { ! 75: *a++ = '0'; ! 76: avail--; ! 77: } ! 78: ! 79: /* compute space length left after dec pt and fraction */ ! 80: avail -= prec + 1; ! 81: if (mode == 'G') ! 82: avail -= 4; ! 83: ! 84: if (avail >= expon) ! 85: { ! 86: ! 87: /* it fits. output */ ! 88: while (expon > 0) ! 89: { ! 90: /* output left of dp */ ! 91: expon--; ! 92: if (*p) ! 93: { ! 94: *a++ = *p++; ! 95: } ! 96: else ! 97: *a++ = '0'; ! 98: } ! 99: ! 100: /* output fraction (right of dec pt) */ ! 101: avail = expon; ! 102: goto frac_out; ! 103: } ! 104: /* won't fit; let's hope for G format */ ! 105: } ! 106: ! 107: if (mode != 'F') ! 108: { ! 109: /* try to do E style output */ ! 110: p = ecvt(value, prec + 1, &expon, &sign); ! 111: avail = width - 5; ! 112: a = ascii; ! 113: ! 114: /* output the sign */ ! 115: if (sign) ! 116: { ! 117: *a++ = '-'; ! 118: avail--; ! 119: } ! 120: } ! 121: ! 122: /* check for field too small */ ! 123: if (mode == 'F' || avail < prec) ! 124: { ! 125: /* sorry joker, you lose */ ! 126: a = ascii; ! 127: for (avail = width; avail > 0; avail--) ! 128: *a++ = '*'; ! 129: *a = 0; ! 130: return (0); ! 131: } ! 132: ! 133: /* it fits; output the number */ ! 134: mode = 'E'; ! 135: ! 136: /* output the LHS single digit */ ! 137: *a++ = *p++; ! 138: expon--; ! 139: ! 140: /* output the rhs */ ! 141: avail = 1; ! 142: ! 143: frac_out: ! 144: *a++ = '.'; ! 145: while (prec > 0) ! 146: { ! 147: prec--; ! 148: if (avail < 0) ! 149: { ! 150: avail++; ! 151: *a++ = '0'; ! 152: } ! 153: else ! 154: { ! 155: if (*p) ! 156: *a++ = *p++; ! 157: else ! 158: *a++ = '0'; ! 159: } ! 160: } ! 161: ! 162: /* output the exponent */ ! 163: if (mode == 'E') ! 164: { ! 165: *a++ = 'E' + lowercase; ! 166: if (expon < 0) ! 167: { ! 168: *a++ = '-'; ! 169: expon = -expon; ! 170: } ! 171: else ! 172: *a++ = '+'; ! 173: *a++ = (expon / 10) % 10 + '0'; ! 174: *a++ = expon % 10 + '0'; ! 175: } ! 176: ! 177: /* output spaces on the end in G format */ ! 178: if (mode == 'G') ! 179: { ! 180: *a++ = ' '; ! 181: *a++ = ' '; ! 182: *a++ = ' '; ! 183: *a++ = ' '; ! 184: } ! 185: ! 186: /* finally, we can return */ ! 187: *a = 0; ! 188: avail = a - ascii; ! 189: return (avail); ! 190: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.