|
3 | 3 | * numutils.c
|
4 | 4 | * utility functions for I/O of built-in numeric types.
|
5 | 5 | *
|
6 |
| - *integer:pg_itoa, pg_ltoa |
7 |
| - *floating point:ftoa, atof1 |
| 6 | + *integer:pg_atoi, pg_itoa, pg_ltoa |
8 | 7 | *
|
9 | 8 | * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
10 | 9 | * Portions Copyright (c) 1994, Regents of the University of California
|
11 | 10 | *
|
12 | 11 | *
|
13 | 12 | * IDENTIFICATION
|
14 |
| - * $PostgreSQL: pgsql/src/backend/utils/adt/numutils.c,v 1.60 2004/01/07 18:56:28 neilc Exp $ |
| 13 | + * $PostgreSQL: pgsql/src/backend/utils/adt/numutils.c,v 1.61 2004/02/18 00:01:33 neilc Exp $ |
15 | 14 | *
|
16 | 15 | *-------------------------------------------------------------------------
|
17 | 16 | */
|
@@ -147,334 +146,3 @@ pg_ltoa(int32 l, char *a)
|
147 | 146 | {
|
148 | 147 | sprintf(a,"%d",l);
|
149 | 148 | }
|
150 |
| - |
151 |
| -/* |
152 |
| - ** ftoa- FLOATING POINT TO ASCII CONVERSION |
153 |
| - ** |
154 |
| - **CODE derived from ingres, ~ingres/source/gutil/ftoa.c |
155 |
| - ** |
156 |
| - **'Value' is converted to an ascii character string and stored |
157 |
| - **into 'ascii'. Ascii should have room for at least 'width' + 1 |
158 |
| - **characters. 'Width' is the width of the output field (max). |
159 |
| - **'Prec' is the number of characters to put after the decimal |
160 |
| - **point.The format of the output string is controlled by |
161 |
| - **'format'. |
162 |
| - ** |
163 |
| - **'Format' can be: |
164 |
| - **e or E: "E" format output |
165 |
| - **f or F: "F" format output |
166 |
| - **g or G: "F" format output if it will fit, otherwise |
167 |
| - **use "E" format. |
168 |
| - **n or N: same as G, but decimal points will not always |
169 |
| - **be aligned. |
170 |
| - ** |
171 |
| - **If 'format' is upper case, the "E" comes out in upper case; |
172 |
| - **otherwise it comes out in lower case. |
173 |
| - ** |
174 |
| - **When the field width is not big enough, it fills the field with |
175 |
| - **stars ("*****") and returns zero. Normal return is the width |
176 |
| - **of the output field (sometimes shorter than 'width'). |
177 |
| - */ |
178 |
| -#ifdefNOT_USED |
179 |
| -int |
180 |
| -ftoa(doublevalue,char*ascii,intwidth,intprec1,charformat) |
181 |
| -{ |
182 |
| -#ifndefHAVE_FCVT |
183 |
| -charout[256]; |
184 |
| -charfmt[256]; |
185 |
| -intret; |
186 |
| - |
187 |
| -sprintf(fmt,"%%%d.%d%c",width,prec1,format); |
188 |
| -sprintf(out,fmt,value); |
189 |
| -if ((ret=strlen(out))>width) |
190 |
| -{ |
191 |
| -MemSet(ascii,'*',width-2); |
192 |
| -ascii[width]=0; |
193 |
| -return0; |
194 |
| -} |
195 |
| -strcpy(ascii,out); |
196 |
| -returnret; |
197 |
| -#else |
198 |
| -autointexpon; |
199 |
| -autointsign; |
200 |
| -intavail=0; |
201 |
| -char*a=NULL; |
202 |
| -char*p=NULL; |
203 |
| -charmode; |
204 |
| -intlowercase; |
205 |
| -intprec; |
206 |
| - |
207 |
| -/* extern char*ecvt(), *fcvt();*/ |
208 |
| - |
209 |
| -prec=prec1; |
210 |
| -mode=format; |
211 |
| -lowercase='a'-'A'; |
212 |
| -if (mode >='a') |
213 |
| -mode-='a'-'A'; |
214 |
| -else |
215 |
| -lowercase=0; |
216 |
| - |
217 |
| -if (mode!='E') |
218 |
| -{ |
219 |
| -/* try 'F' style output */ |
220 |
| -p=fcvt(value,prec,&expon,&sign); |
221 |
| -avail=width; |
222 |
| -a=ascii; |
223 |
| - |
224 |
| -/* output sign */ |
225 |
| -if (sign) |
226 |
| -{ |
227 |
| -avail--; |
228 |
| -*a++='-'; |
229 |
| -} |
230 |
| - |
231 |
| -/* output '0' before the decimal point */ |
232 |
| -if (expon <=0) |
233 |
| -{ |
234 |
| -*a++='0'; |
235 |
| -avail--; |
236 |
| -} |
237 |
| - |
238 |
| -/* compute space length left after dec pt and fraction */ |
239 |
| -avail-=prec+1; |
240 |
| -if (mode=='G') |
241 |
| -avail-=4; |
242 |
| - |
243 |
| -if (avail >=expon) |
244 |
| -{ |
245 |
| - |
246 |
| -/* it fits. output */ |
247 |
| -while (expon>0) |
248 |
| -{ |
249 |
| -/* output left of dp */ |
250 |
| -expon--; |
251 |
| -if (*p) |
252 |
| -*a++=*p++; |
253 |
| -else |
254 |
| -*a++='0'; |
255 |
| -} |
256 |
| - |
257 |
| -/* output fraction (right of dec pt) */ |
258 |
| -avail=expon; |
259 |
| -gotofrac_out; |
260 |
| -} |
261 |
| -/* won't fit; let's hope for G format */ |
262 |
| -} |
263 |
| - |
264 |
| -if (mode!='F') |
265 |
| -{ |
266 |
| -/* try to do E style output */ |
267 |
| -p=ecvt(value,prec+1,&expon,&sign); |
268 |
| -avail=width-5; |
269 |
| -a=ascii; |
270 |
| - |
271 |
| -/* output the sign */ |
272 |
| -if (sign) |
273 |
| -{ |
274 |
| -*a++='-'; |
275 |
| -avail--; |
276 |
| -} |
277 |
| -} |
278 |
| - |
279 |
| -/* check for field too small */ |
280 |
| -if (mode=='F'||avail<prec) |
281 |
| -{ |
282 |
| -/* sorry joker, you lose */ |
283 |
| -a=ascii; |
284 |
| -for (avail=width;avail>0;avail--) |
285 |
| -*a++='*'; |
286 |
| -*a=0; |
287 |
| -return0; |
288 |
| -} |
289 |
| - |
290 |
| -/* it fits; output the number */ |
291 |
| -mode='E'; |
292 |
| - |
293 |
| -/* output the LHS single digit */ |
294 |
| -*a++=*p++; |
295 |
| -expon--; |
296 |
| - |
297 |
| -/* output the rhs */ |
298 |
| -avail=1; |
299 |
| - |
300 |
| -frac_out: |
301 |
| -*a++='.'; |
302 |
| -while (prec>0) |
303 |
| -{ |
304 |
| -prec--; |
305 |
| -if (avail<0) |
306 |
| -{ |
307 |
| -avail++; |
308 |
| -*a++='0'; |
309 |
| -} |
310 |
| -else |
311 |
| -{ |
312 |
| -if (*p) |
313 |
| -*a++=*p++; |
314 |
| -else |
315 |
| -*a++='0'; |
316 |
| -} |
317 |
| -} |
318 |
| - |
319 |
| -/* output the exponent */ |
320 |
| -if (mode=='E') |
321 |
| -{ |
322 |
| -*a++='E'+lowercase; |
323 |
| -if (expon<0) |
324 |
| -{ |
325 |
| -*a++='-'; |
326 |
| -expon=-expon; |
327 |
| -} |
328 |
| -else |
329 |
| -*a++='+'; |
330 |
| -*a++= (expon /10) %10+'0'; |
331 |
| -*a++=expon %10+'0'; |
332 |
| -} |
333 |
| - |
334 |
| -/* output spaces on the end in G format */ |
335 |
| -if (mode=='G') |
336 |
| -{ |
337 |
| -*a++=' '; |
338 |
| -*a++=' '; |
339 |
| -*a++=' '; |
340 |
| -*a++=' '; |
341 |
| -} |
342 |
| - |
343 |
| -/* finally, we can return */ |
344 |
| -*a=0; |
345 |
| -avail=a-ascii; |
346 |
| -returnavail; |
347 |
| -#endif |
348 |
| -} |
349 |
| -#endif |
350 |
| - |
351 |
| -/* |
352 |
| - ** atof1- ASCII TO FLOATING CONVERSION |
353 |
| - ** |
354 |
| - **CODE derived from ~ingres/source/gutil/atof.c |
355 |
| - ** |
356 |
| - **Converts the string 'str' to floating point and stores the |
357 |
| - **result into the cell pointed to by 'val'. |
358 |
| - ** |
359 |
| - **The syntax which it accepts is pretty much what you would |
360 |
| - **expect. Basically, it is: |
361 |
| - **{<sp>} [+|-] {<sp>} {<digit>} [.{digit}] {<sp>} [<exp>] |
362 |
| - **where <exp> is "e" or "E" followed by an integer, <sp> is a |
363 |
| - **space character, <digit> is zero through nine, [] is zero or |
364 |
| - **one, and {} is zero or more. |
365 |
| - ** |
366 |
| - **Parameters: |
367 |
| - **str -- string to convert. |
368 |
| - **val -- pointer to place to put the result (which |
369 |
| - **must be type double). |
370 |
| - ** |
371 |
| - **Returns: |
372 |
| - **zero -- ok. |
373 |
| - **-1 -- syntax error. |
374 |
| - **+1 -- overflow (not implemented). |
375 |
| - ** |
376 |
| - **Side Effects: |
377 |
| - **clobbers *val. |
378 |
| - */ |
379 |
| -#ifdefNOT_USED |
380 |
| -int |
381 |
| -atof1(char*str,double*val) |
382 |
| -{ |
383 |
| -char*p; |
384 |
| -doublev; |
385 |
| -doublefact; |
386 |
| -intminus; |
387 |
| -charc; |
388 |
| -intexpon; |
389 |
| -intgotmant; |
390 |
| - |
391 |
| -v=0.0; |
392 |
| -p=str; |
393 |
| -minus=0; |
394 |
| - |
395 |
| -/* skip leading blanks */ |
396 |
| -while ((c=*p)!='\0') |
397 |
| -{ |
398 |
| -if (c!=' ') |
399 |
| -break; |
400 |
| -p++; |
401 |
| -} |
402 |
| - |
403 |
| -/* handle possible sign */ |
404 |
| -switch (c) |
405 |
| -{ |
406 |
| -case'-': |
407 |
| -minus++; |
408 |
| - |
409 |
| -case'+': |
410 |
| -p++; |
411 |
| -} |
412 |
| - |
413 |
| -/* skip blanks after sign */ |
414 |
| -while ((c=*p)!='\0') |
415 |
| -{ |
416 |
| -if (c!=' ') |
417 |
| -break; |
418 |
| -p++; |
419 |
| -} |
420 |
| - |
421 |
| -/* start collecting the number to the decimal point */ |
422 |
| -gotmant=0; |
423 |
| -for (;;) |
424 |
| -{ |
425 |
| -c=*p; |
426 |
| -if (c<'0'||c>'9') |
427 |
| -break; |
428 |
| -v=v*10.0+ (c-'0'); |
429 |
| -gotmant++; |
430 |
| -p++; |
431 |
| -} |
432 |
| - |
433 |
| -/* check for fractional part */ |
434 |
| -if (c=='.') |
435 |
| -{ |
436 |
| -fact=1.0; |
437 |
| -for (;;) |
438 |
| -{ |
439 |
| -c=*++p; |
440 |
| -if (c<'0'||c>'9') |
441 |
| -break; |
442 |
| -fact *=0.1; |
443 |
| -v+= (c-'0')*fact; |
444 |
| -gotmant++; |
445 |
| -} |
446 |
| -} |
447 |
| - |
448 |
| -/* skip blanks before possible exponent */ |
449 |
| -while ((c=*p)!='\0') |
450 |
| -{ |
451 |
| -if (c!=' ') |
452 |
| -break; |
453 |
| -p++; |
454 |
| -} |
455 |
| - |
456 |
| -/* test for exponent */ |
457 |
| -if (c=='e'||c=='E') |
458 |
| -{ |
459 |
| -p++; |
460 |
| -expon=pg_atoi(p,sizeof(expon),'\0'); |
461 |
| -if (!gotmant) |
462 |
| -v=1.0; |
463 |
| -fact=expon; |
464 |
| -v *=pow(10.0,fact); |
465 |
| -} |
466 |
| -else |
467 |
| -{ |
468 |
| -/* if no exponent, then nothing */ |
469 |
| -if (c!=0) |
470 |
| -return-1; |
471 |
| -} |
472 |
| - |
473 |
| -/* store the result and exit */ |
474 |
| -if (minus) |
475 |
| -v=-v; |
476 |
| -*val=v; |
477 |
| -return0; |
478 |
| -} |
479 |
| - |
480 |
| -#endif |