|
|
1.1 root 1: /*
2: * Let's C Version 4.0.16.
3: * Copyright (c) 1982-1988 by Mark Williams Company, Chicago.
4: * All rights reserved. May not be copied or disclosed without permission.
5: */
6:
7: /*
8: * The picture() function is designed to give C users the same
9: * numeric formatting ability as COBOL and BASIC users.
10: *
11: * When compiled with -DTEST picture.c builds its own test stream.
12: * The various options of picture() are illustrated by the test stream
13: * in main().
14: * Who says self documenting programs are a myth?
15: */
16: #include "stdio.h"
17: #include "math.h"
18: extern char *index();
19: static int dmod10();
20:
21: /*
22: * Format double precision number. Return any overflow.
23: */
24: double
25: picture (dble, format, output )
26: double dble; /* the number to format */
27: char *format; /* the format mask */
28: char *output; /* the output area. Must be at least as large as format */
29: {
30: register int i, plus = 1;
31: register char *outp, tmp;
32: double numb = dble;
33: char *sig, *j;
34:
35: if (dble < 0.0) {
36: numb = -dble;
37: plus = 0;
38: }
39:
40: if (outp = index(format, '.')) /* if . in format adjust number */
41: for(; *outp != '\000'; outp++)
42: switch ( *outp ) {
43: case '9' :
44: case 'Z' :
45: case 'J' :
46: case 'K' :
47: case 'S' :
48: case 'T' :
49: numb *= 10.0;
50: }
51: numb += 0.5; /* round number */
52:
53: /* scan backward for slot */
54: for(i = strlen(format), output[i--] = '\000'; i >= 0; i--) {
55: outp = &output[i];
56: switch ( tmp=format[i] ) {
57: case '+' :
58: *outp = plus ? '+' : '-';
59: continue;
60: case 'T' :
61: case 'S' :
62: case 'J' :
63: case 'K' :
64: case '9' :
65: case 'Z' :
66: break;
67: default:
68: *outp = plus ? ' ' : tmp;
69: continue;
70: } /* switch */
71: break;
72: } /* for */
73:
74: /* build output string */
75: for (sig = output - 1; i >= 0; i--) {
76: outp = &output[i];
77: switch ( tmp=format[i] ) {
78: case '9' : /* slot for number */
79: *outp = dmod10(&numb);
80: sig = outp - 1;
81: break;
82: case 'Z' : /* lead zero suppress */
83: if (numb >= 1.0) {
84: *outp = dmod10(&numb);
85: sig = outp - 1;
86: }
87: else
88: *outp = ' ';
89: break;
90: case 'J' : /* lead zero shirnk */
91: if (numb >= 1.0) {
92: *outp = dmod10(&numb);
93: sig = outp - 1;
94: }
95: else {
96: sig--;
97: strcpy(outp, (outp + 1));
98: }
99: break;
100: case 'K' : /* all zero shrink */
101: *outp = dmod10(&numb);
102: if ( *outp == '0' ) {
103: sig--;
104: strcpy(outp, (outp + 1));
105: }
106: else
107: sig = outp - 1;
108: break;
109: case 'T' : /* suppress trailing zeros */
110: *outp = dmod10(&numb);
111: if(*outp != '0' || sig >= output )
112: sig = outp - 1;
113: else
114: *outp = ' ';
115: break;
116: case 'S' : /* shrink trailing zeros */
117: *outp = dmod10(&numb);
118: if(*outp != '0' || sig >= output )
119: sig = outp - 1;
120: else
121: strcpy(outp, (outp + 1));
122: break;
123: case '$' : /* floating $ */
124: *outp = ' ';
125: if (sig >= output)
126: *sig-- = '$';
127: break;
128: case '-' : /* floating lead - */
129: case '(' : /* floating lead ( */
130: *outp = ' ';
131: if (sig >= output && !plus )
132: *sig-- = tmp;
133: break;
134: case '+' : /* floating lead + or - */
135: *outp = ' ';
136: if (sig >= output)
137: *sig-- = plus ? '+' : '-';
138: break;
139: case '*' : /* * fill */
140: *outp = '*';
141: for (j = outp+1; *j == ' ';)
142: *j++ = '*';
143: break;
144: case '.' : /* decimal point */
145: *outp = '.';
146: break;
147: default :
148: *outp = (numb >= 1.0) ? tmp: ' ';
149: } /* switch */
150: } /* for */
151:
152: return (numb >= 1.0) ? (plus ? floor(numb) : -floor(numb)) : 0.0;
153: }
154:
155: /*
156: * return low order decimal number of argument.
157: * divide argument by 10.
158: */
159: static int
160: dmod10(numb)
161: register double *numb;
162: {
163: int wrk;
164: double tmp;
165:
166: if (*numb >= 10.0) {
167: wrk = *numb - (floor(tmp = (*numb / 10.0)) * 10.0 );
168: *numb = tmp;
169: }
170: else {
171: wrk = *numb;
172: *numb = 0.0;
173: }
174: return(wrk + '0');
175: }
176:
177: #ifdef TEST
178: static int test_no;
179:
180: /*
181: * Run picture and check the results.
182: */
183: verify(mask, number, expect, oflow, descr)
184: char *mask; /* format mask for picturre */
185: double number; /* number to format */
186: char *expect; /* expected result of format */
187: double oflow; /* expected overflow */
188: char *descr; /* description */
189: {
190: char result[20];
191: double ret;
192:
193: test_no++;
194: if(descr != NULL)
195: printf("\n%s\n", descr);
196: printf("%10.3f passed through a mask of '%s' gives '%s'\n",
197: number, mask, expect);
198: if((int)oflow)
199: printf(" With an overflow of %-3.1f\n", oflow);
200: ret = picture(number, mask, result);
201: if((int)(ret - oflow))
202: printf("Expected oflow\t%e\ngot\t\t%e\ttest %d\n",
203: oflow, ret, test_no);
204: if(strcmp(result, expect))
205: printf("Expected\t'%s'\ngot\t\t'%s'\ttest %d\n",
206: expect, result, test_no);
207: }
208:
209: main()
210: {
211: printf("The picture() function is designed to give C users the same\n");
212: printf("numeric formatting ability as COBOL and BASIC users. \n\n");
213: printf("double\n");
214: printf("picture (dble, format, output )\n");
215: printf("double dble; /* the number to format */\n");
216: printf("char *format; /* the format mask */\n");
217: printf("char *output; /* the output area. Must be at least as large as format */\n");
218:
219: verify("999 CR", 5.0, "005 ", 0.0,
220: "9 Provides a slot for a number.");
221: verify("999 CR", -5.0, "005 CR", 0.0, NULL);
222: printf(" Note: C & R are not special to picture. Trailing non special\n");
223: printf(" characters print only if the number is negitave\n");
224:
225: verify("ZZZ,ZZZ", 1034.0, " 1,034", 0.0,
226: "Z Provides a slot for a number but supresses lead zeros.");
227: printf(" Note: comma is not special to picture. Imbeded non special\n");
228: printf(" characters print only if preceeded by significant digits\n");
229: verify("JJJ,JJJ", 1034.0, "1,034", 0.0,
230: "J Provides a slot for a number but shrinks out lead zeros.");
231:
232: verify("K9/K9/K9", 70884.0, "7/8/84", 0.0,
233: "K Provides a slot for a number but shrinks out any zeros.");
234:
235: verify("$ZZZ,ZZZ", 105.0, " $105", 0.0,
236: "$ Floats a dollar sign to the front of the displayed number.");
237:
238: verify("Z,ZZZ.999", 105.67, " 105.670", 0.0,
239: ". Separates the number between decimal and integer portions.");
240:
241: verify("Z,ZZ9.9TT", 105.67, " 105.67 ", 0.0,
242: "T Provides a slot for a number but supresses trailing zeros.");
243:
244: verify("Z,ZZ9.9SS", 105.67, " 105.67", 0.0,
245: "S Provides a slot for a number but shrinks out trailing zeros.");
246:
247: verify("-Z,ZZZ", 105.0, " 105", 0.0,
248: "- Floats a - infront of negitive numbers");
249: verify("-Z,ZZZ", -105.0, " -105", 0.0, NULL);
250:
251: verify("(ZZZ)", 105.0, " 105 ", 0.0,
252: "( Acts like - but prints a (");
253: verify("(ZZZ)", -5.0, " (5)", 0.0, NULL);
254:
255: verify("+ZZZ", 5.0, " +5", 0.0,
256: "+ Floats a + or - infront of the number depending on its sign");
257: verify("+ZZZ", -5.0, " -5", 0.0, NULL);
258:
259: verify("*ZZZ,ZZZ.99", 104.10, "*****104.10", 0.0,
260: "* Fills all lead spaces to its right");
261: verify("*$ZZZ,ZZZ.99", 104.10, "*****$104.10", 0.0, NULL);
262:
263: verify("(ZZZ)", -1234.0, "(234)", -1.0,
264: "Any overflow is returned by picture as a double precision number.");
265: verify("99", 123.4, "23", 1.0, NULL);
266: verify("ZZ", 1200.0, "00", 12.0, NULL);
267: }
268: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.