]>
git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/m2/gm2-libs-ch/dtoa.cc
1 /* dtoa.c provide floating point string conversion routines.
3 Copyright (C) 2009-2024 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius@glam.ac.uk>.
6 This file is part of GNU Modula-2.
8 GNU Modula-2 is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GNU Modula-2 is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
31 #include "gm2-libs-host.h"
34 #define LIBNAME "m2pim"
40 #define MAX_FP_DIGITS 500
42 typedef enum Mode
{ maxsignicant
, decimaldigits
} Mode
;
44 /* maxsignicant: return a string containing max(1,ndigits)
45 significant digits. The return string contains the string
46 produced by ecvt. decimaldigits: return a string produced by
47 fcvt. The string will contain ndigits past the decimal point
48 (ndigits may be negative). */
51 dtoa_strtod (const char *s
, bool *error
)
57 d
= strtod (s
, &endp
);
58 if (endp
!= NULL
&& (*endp
== '\0'))
59 *error
= (errno
!= 0);
65 /* dtoa_calcmaxsig - calculates the position of the decimal point it
66 also removes the decimal point and exponent from string, p. */
69 dtoa_calcmaxsig (char *p
, int ndigits
)
86 return strlen (p
) + x
;
89 memmove (o
, o
+ 1, ndigits
- (o
- p
));
94 /* dtoa_calcdecimal - calculates the position of the decimal point it
95 also removes the decimal point and exponent from string, p. It
96 truncates the digits in p accordingly to ndigits. Ie ndigits is
97 the number of digits after the '.' */
100 dtoa_calcdecimal (char *p
, int str_size
, int ndigits
)
123 memmove (o
, o
+ 1, l
- (o
- p
));
128 if ((x
+ ndigits
>= 0) && (x
+ ndigits
< str_size
))
129 p
[x
+ ndigits
] = (char)0;
134 dtoa_calcsign (char *p
, int str_size
)
138 memmove (p
, p
+ 1, str_size
- 1);
146 dtoa_dtoa (double d
, int mode
, int ndigits
, int *decpt
, int *sign
)
155 ndigits
+= 20; /* enough for exponent. */
156 p
= (char *) malloc (ndigits
);
157 snprintf (format
, 50, "%s%d%s", "%.", ndigits
- 20, "E");
158 snprintf (p
, ndigits
, format
, d
);
159 *sign
= dtoa_calcsign (p
, ndigits
);
160 *decpt
= dtoa_calcmaxsig (p
, ndigits
);
163 p
= (char *) malloc (MAX_FP_DIGITS
+ 20);
164 snprintf (format
, 50, "%s%d%s", "%.", MAX_FP_DIGITS
, "E");
165 snprintf (p
, MAX_FP_DIGITS
+ 20, format
, d
);
166 *sign
= dtoa_calcsign (p
, MAX_FP_DIGITS
+ 20);
167 *decpt
= dtoa_calcdecimal (p
, MAX_FP_DIGITS
+ 20, ndigits
);
174 /* GNU Modula-2 hooks */
177 _M2_dtoa_init (int, char **, char **)
182 _M2_dtoa_finish (int, char **, char **)
194 extern "C" void __attribute__((__constructor__
))
197 M2RTS_RegisterModule ("dtoa", LIBNAME
, _M2_dtoa_init
, _M2_dtoa_finish
,