]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/m2/gm2-libs-ch/dtoa.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / gm2-libs-ch / dtoa.cc
CommitLineData
1eee94d3
GM
1/* dtoa.c provide floating point string conversion routines.
2
83ffe9cd 3Copyright (C) 2009-2023 Free Software Foundation, Inc.
1eee94d3
GM
4Contributed by Gaius Mulley <gaius@glam.ac.uk>.
5
6This file is part of GNU Modula-2.
7
8GNU Modula-2 is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GNU Modula-2 is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16General Public License for more details.
17
18Under Section 7 of GPL version 3, you are granted additional
19permissions described in the GCC Runtime Library Exception, version
203.1, as published by the Free Software Foundation.
21
22You should have received a copy of the GNU General Public License and
23a copy of the GCC Runtime Library Exception along with this program;
24see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25<http://www.gnu.org/licenses/>. */
26
27#include "config.h"
28#include "system.h"
29#include "ansidecl.h"
30
31#include "gm2-libs-host.h"
32#include "m2rts.h"
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38#define MAX_FP_DIGITS 500
39
40typedef enum Mode { maxsignicant, decimaldigits } Mode;
41
42/* maxsignicant: return a string containing max(1,ndigits)
43 significant digits. The return string contains the string
44 produced by ecvt. decimaldigits: return a string produced by
45 fcvt. The string will contain ndigits past the decimal point
46 (ndigits may be negative). */
47
48double
49dtoa_strtod (const char *s, int *error)
50{
51 char *endp;
52 double d;
53
54 errno = 0;
55 d = strtod (s, &endp);
56 if (endp != NULL && (*endp == '\0'))
57 *error = (errno != 0);
58 else
59 *error = TRUE;
60 return d;
61}
62
63/* dtoa_calcmaxsig - calculates the position of the decimal point it
64 also removes the decimal point and exponent from string, p. */
65
66int
67dtoa_calcmaxsig (char *p, int ndigits)
68{
69 char *e;
70 char *o;
71 int x;
72
73 e = index (p, 'E');
74 if (e == NULL)
75 x = 0;
76 else
77 {
78 *e = (char)0;
79 x = atoi (e + 1);
80 }
81
82 o = index (p, '.');
83 if (o == NULL)
84 return strlen (p) + x;
85 else
86 {
87 memmove (o, o + 1, ndigits - (o - p));
88 return o - p + x;
89 }
90}
91
92/* dtoa_calcdecimal - calculates the position of the decimal point it
93 also removes the decimal point and exponent from string, p. It
94 truncates the digits in p accordingly to ndigits. Ie ndigits is
95 the number of digits after the '.' */
96
97int
98dtoa_calcdecimal (char *p, int str_size, int ndigits)
99{
100 char *e;
101 char *o;
102 int x;
103 int l;
104
105 e = index (p, 'E');
106 if (e == NULL)
107 x = 0;
108 else
109 {
110 *e = (char)0;
111 x = atoi (e + 1);
112 }
113
114 l = strlen (p);
115 o = index (p, '.');
116 if (o == NULL)
117 x += strlen (p);
118 else
119 {
120 int m = strlen (o);
121 memmove (o, o + 1, l - (o - p));
122 if (m > 0)
123 o[m - 1] = '0';
124 x += o - p;
125 }
126 if ((x + ndigits >= 0) && (x + ndigits < str_size))
127 p[x + ndigits] = (char)0;
128 return x;
129}
130
131int
132dtoa_calcsign (char *p, int str_size)
133{
134 if (p[0] == '-')
135 {
136 memmove (p, p + 1, str_size - 1);
137 return TRUE;
138 }
139 else
140 return FALSE;
141}
142
143char *
144dtoa_dtoa (double d, int mode, int ndigits, int *decpt, int *sign)
145{
146 char format[50];
147 char *p;
148 int r;
149 switch (mode)
150 {
151
152 case maxsignicant:
153 ndigits += 20; /* enough for exponent. */
154 p = (char *) malloc (ndigits);
155 snprintf (format, 50, "%s%d%s", "%.", ndigits - 20, "E");
156 snprintf (p, ndigits, format, d);
157 *sign = dtoa_calcsign (p, ndigits);
158 *decpt = dtoa_calcmaxsig (p, ndigits);
159 return p;
160 case decimaldigits:
161 p = (char *) malloc (MAX_FP_DIGITS + 20);
162 snprintf (format, 50, "%s%d%s", "%.", MAX_FP_DIGITS, "E");
163 snprintf (p, MAX_FP_DIGITS + 20, format, d);
164 *sign = dtoa_calcsign (p, MAX_FP_DIGITS + 20);
165 *decpt = dtoa_calcdecimal (p, MAX_FP_DIGITS + 20, ndigits);
166 return p;
167 default:
168 abort ();
169 }
170}
171
172/* GNU Modula-2 hooks */
173
174void
175_M2_dtoa_init (int, char **, char **)
176{
177}
178
179void
180_M2_dtoa_finish (int, char **, char **)
181{
182}
183
184void
185_M2_dtoa_dep (void)
186{
187}
188
189#ifdef __cplusplus
190}
191
ec6d1fc0
IS
192extern "C" void __attribute__((__constructor__))
193_M2_dtoa_ctor (void)
1eee94d3
GM
194{
195 M2RTS_RegisterModule ("dtoa", _M2_dtoa_init, _M2_dtoa_finish,
196 _M2_dtoa_dep);
197}
198
199#else
200void
201_M2_dtoa_ctor (void)
202{
203}
204
205#endif