1 /* Gdtoa.cc provides access to double string conversion.
3 Copyright (C) 2016-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 You should have received a copy of the GNU General Public License
19 along with GNU Modula-2; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
32 #define MAX_FP_DIGITS 500
34 typedef enum Mode
{ maxsignicant
, decimaldigits
} Mode
;
36 /* maxsignicant: return a string containing max(1,ndigits)
37 significant digits. The return string contains the string
38 produced by ecvt. decimaldigits: return a string produced by
39 fcvt. The string will contain ndigits past the decimal point
40 (ndigits may be negative). */
43 dtoa_strtod (const char *s
, int *error
)
49 d
= strtod (s
, &endp
);
50 if (endp
!= NULL
&& (*endp
== '\0'))
51 *error
= (errno
!= 0);
57 /* dtoa_calcmaxsig - calculates the position of the decimal point it
58 also removes the decimal point and exponent from string, p. */
61 dtoa_calcmaxsig (char *p
, int ndigits
)
78 return strlen (p
) + x
;
81 memmove (o
, o
+ 1, ndigits
- (o
- p
));
86 /* dtoa_calcdecimal - calculates the position of the decimal point it
87 also removes the decimal point and exponent from string, p. It
88 truncates the digits in p accordingly to ndigits. Ie ndigits is
89 the number of digits after the '.' */
92 dtoa_calcdecimal (char *p
, int str_size
, int ndigits
)
115 memmove (o
, o
+ 1, l
- (o
- p
));
120 if ((x
+ ndigits
>= 0) && (x
+ ndigits
< str_size
))
121 p
[x
+ ndigits
] = (char)0;
127 dtoa_calcsign (char *p
, int str_size
)
131 memmove (p
, p
+ 1, str_size
- 1);
140 dtoa_dtoa (double d
, int mode
, int ndigits
, int *decpt
, int *sign
)
149 ndigits
+= 20; /* enough for exponent. */
150 p
= (char *) malloc (ndigits
);
151 snprintf (format
, 50, "%s%d%s", "%.", ndigits
- 20, "E");
152 snprintf (p
, ndigits
, format
, d
);
153 *sign
= dtoa_calcsign (p
, ndigits
);
154 *decpt
= dtoa_calcmaxsig (p
, ndigits
);
157 p
= (char *) malloc (MAX_FP_DIGITS
+ 20);
158 snprintf (format
, 50, "%s%d%s", "%.", MAX_FP_DIGITS
, "E");
159 snprintf (p
, MAX_FP_DIGITS
+ 20, format
, d
);
160 *sign
= dtoa_calcsign (p
, MAX_FP_DIGITS
+ 20);
161 *decpt
= dtoa_calcdecimal (p
, MAX_FP_DIGITS
+ 20, ndigits
);
169 /* GNU Modula-2 hooks */