aboutsummaryrefslogtreecommitdiff
path: root/g_fmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'g_fmt.c')
-rw-r--r--g_fmt.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/g_fmt.c b/g_fmt.c
new file mode 100644
index 0000000..543430a
--- /dev/null
+++ b/g_fmt.c
@@ -0,0 +1,104 @@
1/****************************************************************
2 *
3 * The author of this software is David M. Gay.
4 *
5 * Copyright (c) 1991, 1996 by Lucent Technologies.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose without fee is hereby granted, provided that this entire notice
9 * is included in all copies of any software which is or includes a copy
10 * or modification of this software and in all copies of the supporting
11 * documentation for such software.
12 *
13 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
14 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
15 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
16 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
17 *
18 ***************************************************************/
19
20/* g_fmt(buf,x) stores the closest decimal approximation to x in buf;
21 * it suffices to declare buf
22 * char buf[32];
23 */
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28 extern char *dtoa(double, int, int, int *, int *, char **);
29 extern char *g_fmt(char *, double);
30 extern void freedtoa(char*);
31#ifdef __cplusplus
32 }
33#endif
34
35 char *
36g_fmt(register char *b, double x)
37{
38 register int i, k;
39 register char *s;
40 int decpt, j, sign;
41 char *b0, *s0, *se;
42
43 b0 = b;
44#ifdef IGNORE_ZERO_SIGN
45 if (!x) {
46 *b++ = '0';
47 *b = 0;
48 goto done;
49 }
50#endif
51 s = s0 = dtoa(x, 0, 0, &decpt, &sign, &se);
52 if (sign)
53 *b++ = '-';
54 if (decpt == 9999) /* Infinity or Nan */ {
55 while(*b++ = *s++);
56 goto done0;
57 }
58 if (decpt <= -4 || decpt > se - s + 5) {
59 *b++ = *s++;
60 if (*s) {
61 *b++ = '.';
62 while(*b = *s++)
63 b++;
64 }
65 *b++ = 'e';
66 /* sprintf(b, "%+.2d", decpt - 1); */
67 if (--decpt < 0) {
68 *b++ = '-';
69 decpt = -decpt;
70 }
71 else
72 *b++ = '+';
73 for(j = 2, k = 10; 10*k <= decpt; j++, k *= 10);
74 for(;;) {
75 i = decpt / k;
76 *b++ = i + '0';
77 if (--j <= 0)
78 break;
79 decpt -= i*k;
80 decpt *= 10;
81 }
82 *b = 0;
83 }
84 else if (decpt <= 0) {
85 *b++ = '.';
86 for(; decpt < 0; decpt++)
87 *b++ = '0';
88 while(*b++ = *s++);
89 }
90 else {
91 while(*b = *s++) {
92 b++;
93 if (--decpt == 0 && *s)
94 *b++ = '.';
95 }
96 for(; decpt > 0; decpt--)
97 *b++ = '0';
98 *b = 0;
99 }
100 done0:
101 freedtoa(s0);
102 done:
103 return b0;
104 }