# Python code coverage for Python/pystrtod.c

# | count | content |
---|---|---|

1 | n/a | /* -*- Mode: C; c-file-style: "python" -*- */ |

2 | n/a | |

3 | n/a | #include <Python.h> |

4 | n/a | #include <locale.h> |

5 | n/a | |

6 | n/a | /* Case-insensitive string match used for nan and inf detection; t should be |

7 | n/a | lower-case. Returns 1 for a successful match, 0 otherwise. */ |

8 | n/a | |

9 | n/a | static int |

10 | n/a | case_insensitive_match(const char *s, const char *t) |

11 | n/a | { |

12 | n/a | while(*t && Py_TOLOWER(*s) == *t) { |

13 | n/a | s++; |

14 | n/a | t++; |

15 | n/a | } |

16 | n/a | return *t ? 0 : 1; |

17 | n/a | } |

18 | n/a | |

19 | n/a | /* _Py_parse_inf_or_nan: Attempt to parse a string of the form "nan", "inf" or |

20 | n/a | "infinity", with an optional leading sign of "+" or "-". On success, |

21 | n/a | return the NaN or Infinity as a double and set *endptr to point just beyond |

22 | n/a | the successfully parsed portion of the string. On failure, return -1.0 and |

23 | n/a | set *endptr to point to the start of the string. */ |

24 | n/a | |

25 | n/a | #ifndef PY_NO_SHORT_FLOAT_REPR |

26 | n/a | |

27 | n/a | double |

28 | n/a | _Py_parse_inf_or_nan(const char *p, char **endptr) |

29 | n/a | { |

30 | n/a | double retval; |

31 | n/a | const char *s; |

32 | n/a | int negate = 0; |

33 | n/a | |

34 | n/a | s = p; |

35 | n/a | if (*s == '-') { |

36 | n/a | negate = 1; |

37 | n/a | s++; |

38 | n/a | } |

39 | n/a | else if (*s == '+') { |

40 | n/a | s++; |

41 | n/a | } |

42 | n/a | if (case_insensitive_match(s, "inf")) { |

43 | n/a | s += 3; |

44 | n/a | if (case_insensitive_match(s, "inity")) |

45 | n/a | s += 5; |

46 | n/a | retval = _Py_dg_infinity(negate); |

47 | n/a | } |

48 | n/a | else if (case_insensitive_match(s, "nan")) { |

49 | n/a | s += 3; |

50 | n/a | retval = _Py_dg_stdnan(negate); |

51 | n/a | } |

52 | n/a | else { |

53 | n/a | s = p; |

54 | n/a | retval = -1.0; |

55 | n/a | } |

56 | n/a | *endptr = (char *)s; |

57 | n/a | return retval; |

58 | n/a | } |

59 | n/a | |

60 | n/a | #else |

61 | n/a | |

62 | n/a | double |

63 | n/a | _Py_parse_inf_or_nan(const char *p, char **endptr) |

64 | n/a | { |

65 | n/a | double retval; |

66 | n/a | const char *s; |

67 | n/a | int negate = 0; |

68 | n/a | |

69 | n/a | s = p; |

70 | n/a | if (*s == '-') { |

71 | n/a | negate = 1; |

72 | n/a | s++; |

73 | n/a | } |

74 | n/a | else if (*s == '+') { |

75 | n/a | s++; |

76 | n/a | } |

77 | n/a | if (case_insensitive_match(s, "inf")) { |

78 | n/a | s += 3; |

79 | n/a | if (case_insensitive_match(s, "inity")) |

80 | n/a | s += 5; |

81 | n/a | retval = negate ? -Py_HUGE_VAL : Py_HUGE_VAL; |

82 | n/a | } |

83 | n/a | #ifdef Py_NAN |

84 | n/a | else if (case_insensitive_match(s, "nan")) { |

85 | n/a | s += 3; |

86 | n/a | retval = negate ? -Py_NAN : Py_NAN; |

87 | n/a | } |

88 | n/a | #endif |

89 | n/a | else { |

90 | n/a | s = p; |

91 | n/a | retval = -1.0; |

92 | n/a | } |

93 | n/a | *endptr = (char *)s; |

94 | n/a | return retval; |

95 | n/a | } |

96 | n/a | |

97 | n/a | #endif |

98 | n/a | |

99 | n/a | /** |

100 | n/a | * _PyOS_ascii_strtod: |

101 | n/a | * @nptr: the string to convert to a numeric value. |

102 | n/a | * @endptr: if non-%NULL, it returns the character after |

103 | n/a | * the last character used in the conversion. |

104 | n/a | * |

105 | n/a | * Converts a string to a #gdouble value. |

106 | n/a | * This function behaves like the standard strtod() function |

107 | n/a | * does in the C locale. It does this without actually |

108 | n/a | * changing the current locale, since that would not be |

109 | n/a | * thread-safe. |

110 | n/a | * |

111 | n/a | * This function is typically used when reading configuration |

112 | n/a | * files or other non-user input that should be locale independent. |

113 | n/a | * To handle input from the user you should normally use the |

114 | n/a | * locale-sensitive system strtod() function. |

115 | n/a | * |

116 | n/a | * If the correct value would cause overflow, plus or minus %HUGE_VAL |

117 | n/a | * is returned (according to the sign of the value), and %ERANGE is |

118 | n/a | * stored in %errno. If the correct value would cause underflow, |

119 | n/a | * zero is returned and %ERANGE is stored in %errno. |

120 | n/a | * If memory allocation fails, %ENOMEM is stored in %errno. |

121 | n/a | * |

122 | n/a | * This function resets %errno before calling strtod() so that |

123 | n/a | * you can reliably detect overflow and underflow. |

124 | n/a | * |

125 | n/a | * Return value: the #gdouble value. |

126 | n/a | **/ |

127 | n/a | |

128 | n/a | #ifndef PY_NO_SHORT_FLOAT_REPR |

129 | n/a | |

130 | n/a | static double |

131 | n/a | _PyOS_ascii_strtod(const char *nptr, char **endptr) |

132 | n/a | { |

133 | n/a | double result; |

134 | n/a | _Py_SET_53BIT_PRECISION_HEADER; |

135 | n/a | |

136 | n/a | assert(nptr != NULL); |

137 | n/a | /* Set errno to zero, so that we can distinguish zero results |

138 | n/a | and underflows */ |

139 | n/a | errno = 0; |

140 | n/a | |

141 | n/a | _Py_SET_53BIT_PRECISION_START; |

142 | n/a | result = _Py_dg_strtod(nptr, endptr); |

143 | n/a | _Py_SET_53BIT_PRECISION_END; |

144 | n/a | |

145 | n/a | if (*endptr == nptr) |

146 | n/a | /* string might represent an inf or nan */ |

147 | n/a | result = _Py_parse_inf_or_nan(nptr, endptr); |

148 | n/a | |

149 | n/a | return result; |

150 | n/a | |

151 | n/a | } |

152 | n/a | |

153 | n/a | #else |

154 | n/a | |

155 | n/a | /* |

156 | n/a | Use system strtod; since strtod is locale aware, we may |

157 | n/a | have to first fix the decimal separator. |

158 | n/a | |

159 | n/a | Note that unlike _Py_dg_strtod, the system strtod may not always give |

160 | n/a | correctly rounded results. |

161 | n/a | */ |

162 | n/a | |

163 | n/a | static double |

164 | n/a | _PyOS_ascii_strtod(const char *nptr, char **endptr) |

165 | n/a | { |

166 | n/a | char *fail_pos; |

167 | n/a | double val; |

168 | n/a | struct lconv *locale_data; |

169 | n/a | const char *decimal_point; |

170 | n/a | size_t decimal_point_len; |

171 | n/a | const char *p, *decimal_point_pos; |

172 | n/a | const char *end = NULL; /* Silence gcc */ |

173 | n/a | const char *digits_pos = NULL; |

174 | n/a | int negate = 0; |

175 | n/a | |

176 | n/a | assert(nptr != NULL); |

177 | n/a | |

178 | n/a | fail_pos = NULL; |

179 | n/a | |

180 | n/a | locale_data = localeconv(); |

181 | n/a | decimal_point = locale_data->decimal_point; |

182 | n/a | decimal_point_len = strlen(decimal_point); |

183 | n/a | |

184 | n/a | assert(decimal_point_len != 0); |

185 | n/a | |

186 | n/a | decimal_point_pos = NULL; |

187 | n/a | |

188 | n/a | /* Parse infinities and nans */ |

189 | n/a | val = _Py_parse_inf_or_nan(nptr, endptr); |

190 | n/a | if (*endptr != nptr) |

191 | n/a | return val; |

192 | n/a | |

193 | n/a | /* Set errno to zero, so that we can distinguish zero results |

194 | n/a | and underflows */ |

195 | n/a | errno = 0; |

196 | n/a | |

197 | n/a | /* We process the optional sign manually, then pass the remainder to |

198 | n/a | the system strtod. This ensures that the result of an underflow |

199 | n/a | has the correct sign. (bug #1725) */ |

200 | n/a | p = nptr; |

201 | n/a | /* Process leading sign, if present */ |

202 | n/a | if (*p == '-') { |

203 | n/a | negate = 1; |

204 | n/a | p++; |

205 | n/a | } |

206 | n/a | else if (*p == '+') { |

207 | n/a | p++; |

208 | n/a | } |

209 | n/a | |

210 | n/a | /* Some platform strtods accept hex floats; Python shouldn't (at the |

211 | n/a | moment), so we check explicitly for strings starting with '0x'. */ |

212 | n/a | if (*p == '0' && (*(p+1) == 'x' || *(p+1) == 'X')) |

213 | n/a | goto invalid_string; |

214 | n/a | |

215 | n/a | /* Check that what's left begins with a digit or decimal point */ |

216 | n/a | if (!Py_ISDIGIT(*p) && *p != '.') |

217 | n/a | goto invalid_string; |

218 | n/a | |

219 | n/a | digits_pos = p; |

220 | n/a | if (decimal_point[0] != '.' || |

221 | n/a | decimal_point[1] != 0) |

222 | n/a | { |

223 | n/a | /* Look for a '.' in the input; if present, it'll need to be |

224 | n/a | swapped for the current locale's decimal point before we |

225 | n/a | call strtod. On the other hand, if we find the current |

226 | n/a | locale's decimal point then the input is invalid. */ |

227 | n/a | while (Py_ISDIGIT(*p)) |

228 | n/a | p++; |

229 | n/a | |

230 | n/a | if (*p == '.') |

231 | n/a | { |

232 | n/a | decimal_point_pos = p++; |

233 | n/a | |

234 | n/a | /* locate end of number */ |

235 | n/a | while (Py_ISDIGIT(*p)) |

236 | n/a | p++; |

237 | n/a | |

238 | n/a | if (*p == 'e' || *p == 'E') |

239 | n/a | p++; |

240 | n/a | if (*p == '+' || *p == '-') |

241 | n/a | p++; |

242 | n/a | while (Py_ISDIGIT(*p)) |

243 | n/a | p++; |

244 | n/a | end = p; |

245 | n/a | } |

246 | n/a | else if (strncmp(p, decimal_point, decimal_point_len) == 0) |

247 | n/a | /* Python bug #1417699 */ |

248 | n/a | goto invalid_string; |

249 | n/a | /* For the other cases, we need not convert the decimal |

250 | n/a | point */ |

251 | n/a | } |

252 | n/a | |

253 | n/a | if (decimal_point_pos) { |

254 | n/a | char *copy, *c; |

255 | n/a | /* Create a copy of the input, with the '.' converted to the |

256 | n/a | locale-specific decimal point */ |

257 | n/a | copy = (char *)PyMem_MALLOC(end - digits_pos + |

258 | n/a | 1 + decimal_point_len); |

259 | n/a | if (copy == NULL) { |

260 | n/a | *endptr = (char *)nptr; |

261 | n/a | errno = ENOMEM; |

262 | n/a | return val; |

263 | n/a | } |

264 | n/a | |

265 | n/a | c = copy; |

266 | n/a | memcpy(c, digits_pos, decimal_point_pos - digits_pos); |

267 | n/a | c += decimal_point_pos - digits_pos; |

268 | n/a | memcpy(c, decimal_point, decimal_point_len); |

269 | n/a | c += decimal_point_len; |

270 | n/a | memcpy(c, decimal_point_pos + 1, |

271 | n/a | end - (decimal_point_pos + 1)); |

272 | n/a | c += end - (decimal_point_pos + 1); |

273 | n/a | *c = 0; |

274 | n/a | |

275 | n/a | val = strtod(copy, &fail_pos); |

276 | n/a | |

277 | n/a | if (fail_pos) |

278 | n/a | { |

279 | n/a | if (fail_pos > decimal_point_pos) |

280 | n/a | fail_pos = (char *)digits_pos + |

281 | n/a | (fail_pos - copy) - |

282 | n/a | (decimal_point_len - 1); |

283 | n/a | else |

284 | n/a | fail_pos = (char *)digits_pos + |

285 | n/a | (fail_pos - copy); |

286 | n/a | } |

287 | n/a | |

288 | n/a | PyMem_FREE(copy); |

289 | n/a | |

290 | n/a | } |

291 | n/a | else { |

292 | n/a | val = strtod(digits_pos, &fail_pos); |

293 | n/a | } |

294 | n/a | |

295 | n/a | if (fail_pos == digits_pos) |

296 | n/a | goto invalid_string; |

297 | n/a | |

298 | n/a | if (negate && fail_pos != nptr) |

299 | n/a | val = -val; |

300 | n/a | *endptr = fail_pos; |

301 | n/a | |

302 | n/a | return val; |

303 | n/a | |

304 | n/a | invalid_string: |

305 | n/a | *endptr = (char*)nptr; |

306 | n/a | errno = EINVAL; |

307 | n/a | return -1.0; |

308 | n/a | } |

309 | n/a | |

310 | n/a | #endif |

311 | n/a | |

312 | n/a | /* PyOS_string_to_double converts a null-terminated byte string s (interpreted |

313 | n/a | as a string of ASCII characters) to a float. The string should not have |

314 | n/a | leading or trailing whitespace. The conversion is independent of the |

315 | n/a | current locale. |

316 | n/a | |

317 | n/a | If endptr is NULL, try to convert the whole string. Raise ValueError and |

318 | n/a | return -1.0 if the string is not a valid representation of a floating-point |

319 | n/a | number. |

320 | n/a | |

321 | n/a | If endptr is non-NULL, try to convert as much of the string as possible. |

322 | n/a | If no initial segment of the string is the valid representation of a |

323 | n/a | floating-point number then *endptr is set to point to the beginning of the |

324 | n/a | string, -1.0 is returned and again ValueError is raised. |

325 | n/a | |

326 | n/a | On overflow (e.g., when trying to convert '1e500' on an IEEE 754 machine), |

327 | n/a | if overflow_exception is NULL then +-Py_HUGE_VAL is returned, and no Python |

328 | n/a | exception is raised. Otherwise, overflow_exception should point to |

329 | n/a | a Python exception, this exception will be raised, -1.0 will be returned, |

330 | n/a | and *endptr will point just past the end of the converted value. |

331 | n/a | |

332 | n/a | If any other failure occurs (for example lack of memory), -1.0 is returned |

333 | n/a | and the appropriate Python exception will have been set. |

334 | n/a | */ |

335 | n/a | |

336 | n/a | double |

337 | n/a | PyOS_string_to_double(const char *s, |

338 | n/a | char **endptr, |

339 | n/a | PyObject *overflow_exception) |

340 | n/a | { |

341 | n/a | double x, result=-1.0; |

342 | n/a | char *fail_pos; |

343 | n/a | |

344 | n/a | errno = 0; |

345 | n/a | PyFPE_START_PROTECT("PyOS_string_to_double", return -1.0) |

346 | n/a | x = _PyOS_ascii_strtod(s, &fail_pos); |

347 | n/a | PyFPE_END_PROTECT(x) |

348 | n/a | |

349 | n/a | if (errno == ENOMEM) { |

350 | n/a | PyErr_NoMemory(); |

351 | n/a | fail_pos = (char *)s; |

352 | n/a | } |

353 | n/a | else if (!endptr && (fail_pos == s || *fail_pos != '\0')) |

354 | n/a | PyErr_Format(PyExc_ValueError, |

355 | n/a | "could not convert string to float: " |

356 | n/a | "%.200s", s); |

357 | n/a | else if (fail_pos == s) |

358 | n/a | PyErr_Format(PyExc_ValueError, |

359 | n/a | "could not convert string to float: " |

360 | n/a | "%.200s", s); |

361 | n/a | else if (errno == ERANGE && fabs(x) >= 1.0 && overflow_exception) |

362 | n/a | PyErr_Format(overflow_exception, |

363 | n/a | "value too large to convert to float: " |

364 | n/a | "%.200s", s); |

365 | n/a | else |

366 | n/a | result = x; |

367 | n/a | |

368 | n/a | if (endptr != NULL) |

369 | n/a | *endptr = fail_pos; |

370 | n/a | return result; |

371 | n/a | } |

372 | n/a | |

373 | n/a | /* Remove underscores that follow the underscore placement rule from |

374 | n/a | the string and then call the `innerfunc` function on the result. |

375 | n/a | It should return a new object or NULL on exception. |

376 | n/a | |

377 | n/a | `what` is used for the error message emitted when underscores are detected |

378 | n/a | that don't follow the rule. `arg` is an opaque pointer passed to the inner |

379 | n/a | function. |

380 | n/a | |

381 | n/a | This is used to implement underscore-agnostic conversion for floats |

382 | n/a | and complex numbers. |

383 | n/a | */ |

384 | n/a | PyObject * |

385 | n/a | _Py_string_to_number_with_underscores( |

386 | n/a | const char *s, Py_ssize_t orig_len, const char *what, PyObject *obj, void *arg, |

387 | n/a | PyObject *(*innerfunc)(const char *, Py_ssize_t, void *)) |

388 | n/a | { |

389 | n/a | char prev; |

390 | n/a | const char *p, *last; |

391 | n/a | char *dup, *end; |

392 | n/a | PyObject *result; |

393 | n/a | |

394 | n/a | if (strchr(s, '_') == NULL) { |

395 | n/a | return innerfunc(s, orig_len, arg); |

396 | n/a | } |

397 | n/a | |

398 | n/a | dup = PyMem_Malloc(orig_len + 1); |

399 | n/a | end = dup; |

400 | n/a | prev = '\0'; |

401 | n/a | last = s + orig_len; |

402 | n/a | for (p = s; *p; p++) { |

403 | n/a | if (*p == '_') { |

404 | n/a | /* Underscores are only allowed after digits. */ |

405 | n/a | if (!(prev >= '0' && prev <= '9')) { |

406 | n/a | goto error; |

407 | n/a | } |

408 | n/a | } |

409 | n/a | else { |

410 | n/a | *end++ = *p; |

411 | n/a | /* Underscores are only allowed before digits. */ |

412 | n/a | if (prev == '_' && !(*p >= '0' && *p <= '9')) { |

413 | n/a | goto error; |

414 | n/a | } |

415 | n/a | } |

416 | n/a | prev = *p; |

417 | n/a | } |

418 | n/a | /* Underscores are not allowed at the end. */ |

419 | n/a | if (prev == '_') { |

420 | n/a | goto error; |

421 | n/a | } |

422 | n/a | /* No embedded NULs allowed. */ |

423 | n/a | if (p != last) { |

424 | n/a | goto error; |

425 | n/a | } |

426 | n/a | *end = '\0'; |

427 | n/a | result = innerfunc(dup, end - dup, arg); |

428 | n/a | PyMem_Free(dup); |

429 | n/a | return result; |

430 | n/a | |

431 | n/a | error: |

432 | n/a | PyMem_Free(dup); |

433 | n/a | PyErr_Format(PyExc_ValueError, |

434 | n/a | "could not convert string to %s: " |

435 | n/a | "%R", what, obj); |

436 | n/a | return NULL; |

437 | n/a | } |

438 | n/a | |

439 | n/a | #ifdef PY_NO_SHORT_FLOAT_REPR |

440 | n/a | |

441 | n/a | /* Given a string that may have a decimal point in the current |

442 | n/a | locale, change it back to a dot. Since the string cannot get |

443 | n/a | longer, no need for a maximum buffer size parameter. */ |

444 | n/a | Py_LOCAL_INLINE(void) |

445 | n/a | change_decimal_from_locale_to_dot(char* buffer) |

446 | n/a | { |

447 | n/a | struct lconv *locale_data = localeconv(); |

448 | n/a | const char *decimal_point = locale_data->decimal_point; |

449 | n/a | |

450 | n/a | if (decimal_point[0] != '.' || decimal_point[1] != 0) { |

451 | n/a | size_t decimal_point_len = strlen(decimal_point); |

452 | n/a | |

453 | n/a | if (*buffer == '+' || *buffer == '-') |

454 | n/a | buffer++; |

455 | n/a | while (Py_ISDIGIT(*buffer)) |

456 | n/a | buffer++; |

457 | n/a | if (strncmp(buffer, decimal_point, decimal_point_len) == 0) { |

458 | n/a | *buffer = '.'; |

459 | n/a | buffer++; |

460 | n/a | if (decimal_point_len > 1) { |

461 | n/a | /* buffer needs to get smaller */ |

462 | n/a | size_t rest_len = strlen(buffer + |

463 | n/a | (decimal_point_len - 1)); |

464 | n/a | memmove(buffer, |

465 | n/a | buffer + (decimal_point_len - 1), |

466 | n/a | rest_len); |

467 | n/a | buffer[rest_len] = 0; |

468 | n/a | } |

469 | n/a | } |

470 | n/a | } |

471 | n/a | } |

472 | n/a | |

473 | n/a | |

474 | n/a | /* From the C99 standard, section 7.19.6: |

475 | n/a | The exponent always contains at least two digits, and only as many more digits |

476 | n/a | as necessary to represent the exponent. |

477 | n/a | */ |

478 | n/a | #define MIN_EXPONENT_DIGITS 2 |

479 | n/a | |

480 | n/a | /* Ensure that any exponent, if present, is at least MIN_EXPONENT_DIGITS |

481 | n/a | in length. */ |

482 | n/a | Py_LOCAL_INLINE(void) |

483 | n/a | ensure_minimum_exponent_length(char* buffer, size_t buf_size) |

484 | n/a | { |

485 | n/a | char *p = strpbrk(buffer, "eE"); |

486 | n/a | if (p && (*(p + 1) == '-' || *(p + 1) == '+')) { |

487 | n/a | char *start = p + 2; |

488 | n/a | int exponent_digit_cnt = 0; |

489 | n/a | int leading_zero_cnt = 0; |

490 | n/a | int in_leading_zeros = 1; |

491 | n/a | int significant_digit_cnt; |

492 | n/a | |

493 | n/a | /* Skip over the exponent and the sign. */ |

494 | n/a | p += 2; |

495 | n/a | |

496 | n/a | /* Find the end of the exponent, keeping track of leading |

497 | n/a | zeros. */ |

498 | n/a | while (*p && Py_ISDIGIT(*p)) { |

499 | n/a | if (in_leading_zeros && *p == '0') |

500 | n/a | ++leading_zero_cnt; |

501 | n/a | if (*p != '0') |

502 | n/a | in_leading_zeros = 0; |

503 | n/a | ++p; |

504 | n/a | ++exponent_digit_cnt; |

505 | n/a | } |

506 | n/a | |

507 | n/a | significant_digit_cnt = exponent_digit_cnt - leading_zero_cnt; |

508 | n/a | if (exponent_digit_cnt == MIN_EXPONENT_DIGITS) { |

509 | n/a | /* If there are 2 exactly digits, we're done, |

510 | n/a | regardless of what they contain */ |

511 | n/a | } |

512 | n/a | else if (exponent_digit_cnt > MIN_EXPONENT_DIGITS) { |

513 | n/a | int extra_zeros_cnt; |

514 | n/a | |

515 | n/a | /* There are more than 2 digits in the exponent. See |

516 | n/a | if we can delete some of the leading zeros */ |

517 | n/a | if (significant_digit_cnt < MIN_EXPONENT_DIGITS) |

518 | n/a | significant_digit_cnt = MIN_EXPONENT_DIGITS; |

519 | n/a | extra_zeros_cnt = exponent_digit_cnt - |

520 | n/a | significant_digit_cnt; |

521 | n/a | |

522 | n/a | /* Delete extra_zeros_cnt worth of characters from the |

523 | n/a | front of the exponent */ |

524 | n/a | assert(extra_zeros_cnt >= 0); |

525 | n/a | |

526 | n/a | /* Add one to significant_digit_cnt to copy the |

527 | n/a | trailing 0 byte, thus setting the length */ |

528 | n/a | memmove(start, |

529 | n/a | start + extra_zeros_cnt, |

530 | n/a | significant_digit_cnt + 1); |

531 | n/a | } |

532 | n/a | else { |

533 | n/a | /* If there are fewer than 2 digits, add zeros |

534 | n/a | until there are 2, if there's enough room */ |

535 | n/a | int zeros = MIN_EXPONENT_DIGITS - exponent_digit_cnt; |

536 | n/a | if (start + zeros + exponent_digit_cnt + 1 |

537 | n/a | < buffer + buf_size) { |

538 | n/a | memmove(start + zeros, start, |

539 | n/a | exponent_digit_cnt + 1); |

540 | n/a | memset(start, '0', zeros); |

541 | n/a | } |

542 | n/a | } |

543 | n/a | } |

544 | n/a | } |

545 | n/a | |

546 | n/a | /* Remove trailing zeros after the decimal point from a numeric string; also |

547 | n/a | remove the decimal point if all digits following it are zero. The numeric |

548 | n/a | string must end in '\0', and should not have any leading or trailing |

549 | n/a | whitespace. Assumes that the decimal point is '.'. */ |

550 | n/a | Py_LOCAL_INLINE(void) |

551 | n/a | remove_trailing_zeros(char *buffer) |

552 | n/a | { |

553 | n/a | char *old_fraction_end, *new_fraction_end, *end, *p; |

554 | n/a | |

555 | n/a | p = buffer; |

556 | n/a | if (*p == '-' || *p == '+') |

557 | n/a | /* Skip leading sign, if present */ |

558 | n/a | ++p; |

559 | n/a | while (Py_ISDIGIT(*p)) |

560 | n/a | ++p; |

561 | n/a | |

562 | n/a | /* if there's no decimal point there's nothing to do */ |

563 | n/a | if (*p++ != '.') |

564 | n/a | return; |

565 | n/a | |

566 | n/a | /* scan any digits after the point */ |

567 | n/a | while (Py_ISDIGIT(*p)) |

568 | n/a | ++p; |

569 | n/a | old_fraction_end = p; |

570 | n/a | |

571 | n/a | /* scan up to ending '\0' */ |

572 | n/a | while (*p != '\0') |

573 | n/a | p++; |

574 | n/a | /* +1 to make sure that we move the null byte as well */ |

575 | n/a | end = p+1; |

576 | n/a | |

577 | n/a | /* scan back from fraction_end, looking for removable zeros */ |

578 | n/a | p = old_fraction_end; |

579 | n/a | while (*(p-1) == '0') |

580 | n/a | --p; |

581 | n/a | /* and remove point if we've got that far */ |

582 | n/a | if (*(p-1) == '.') |

583 | n/a | --p; |

584 | n/a | new_fraction_end = p; |

585 | n/a | |

586 | n/a | memmove(new_fraction_end, old_fraction_end, end-old_fraction_end); |

587 | n/a | } |

588 | n/a | |

589 | n/a | /* Ensure that buffer has a decimal point in it. The decimal point will not |

590 | n/a | be in the current locale, it will always be '.'. Don't add a decimal point |

591 | n/a | if an exponent is present. Also, convert to exponential notation where |

592 | n/a | adding a '.0' would produce too many significant digits (see issue 5864). |

593 | n/a | |

594 | n/a | Returns a pointer to the fixed buffer, or NULL on failure. |

595 | n/a | */ |

596 | n/a | Py_LOCAL_INLINE(char *) |

597 | n/a | ensure_decimal_point(char* buffer, size_t buf_size, int precision) |

598 | n/a | { |

599 | n/a | int digit_count, insert_count = 0, convert_to_exp = 0; |

600 | n/a | char *chars_to_insert, *digits_start; |

601 | n/a | |

602 | n/a | /* search for the first non-digit character */ |

603 | n/a | char *p = buffer; |

604 | n/a | if (*p == '-' || *p == '+') |

605 | n/a | /* Skip leading sign, if present. I think this could only |

606 | n/a | ever be '-', but it can't hurt to check for both. */ |

607 | n/a | ++p; |

608 | n/a | digits_start = p; |

609 | n/a | while (*p && Py_ISDIGIT(*p)) |

610 | n/a | ++p; |

611 | n/a | digit_count = Py_SAFE_DOWNCAST(p - digits_start, Py_ssize_t, int); |

612 | n/a | |

613 | n/a | if (*p == '.') { |

614 | n/a | if (Py_ISDIGIT(*(p+1))) { |

615 | n/a | /* Nothing to do, we already have a decimal |

616 | n/a | point and a digit after it */ |

617 | n/a | } |

618 | n/a | else { |

619 | n/a | /* We have a decimal point, but no following |

620 | n/a | digit. Insert a zero after the decimal. */ |

621 | n/a | /* can't ever get here via PyOS_double_to_string */ |

622 | n/a | assert(precision == -1); |

623 | n/a | ++p; |

624 | n/a | chars_to_insert = "0"; |

625 | n/a | insert_count = 1; |

626 | n/a | } |

627 | n/a | } |

628 | n/a | else if (!(*p == 'e' || *p == 'E')) { |

629 | n/a | /* Don't add ".0" if we have an exponent. */ |

630 | n/a | if (digit_count == precision) { |

631 | n/a | /* issue 5864: don't add a trailing .0 in the case |

632 | n/a | where the '%g'-formatted result already has as many |

633 | n/a | significant digits as were requested. Switch to |

634 | n/a | exponential notation instead. */ |

635 | n/a | convert_to_exp = 1; |

636 | n/a | /* no exponent, no point, and we shouldn't land here |

637 | n/a | for infs and nans, so we must be at the end of the |

638 | n/a | string. */ |

639 | n/a | assert(*p == '\0'); |

640 | n/a | } |

641 | n/a | else { |

642 | n/a | assert(precision == -1 || digit_count < precision); |

643 | n/a | chars_to_insert = ".0"; |

644 | n/a | insert_count = 2; |

645 | n/a | } |

646 | n/a | } |

647 | n/a | if (insert_count) { |

648 | n/a | size_t buf_len = strlen(buffer); |

649 | n/a | if (buf_len + insert_count + 1 >= buf_size) { |

650 | n/a | /* If there is not enough room in the buffer |

651 | n/a | for the additional text, just skip it. It's |

652 | n/a | not worth generating an error over. */ |

653 | n/a | } |

654 | n/a | else { |

655 | n/a | memmove(p + insert_count, p, |

656 | n/a | buffer + strlen(buffer) - p + 1); |

657 | n/a | memcpy(p, chars_to_insert, insert_count); |

658 | n/a | } |

659 | n/a | } |

660 | n/a | if (convert_to_exp) { |

661 | n/a | int written; |

662 | n/a | size_t buf_avail; |

663 | n/a | p = digits_start; |

664 | n/a | /* insert decimal point */ |

665 | n/a | assert(digit_count >= 1); |

666 | n/a | memmove(p+2, p+1, digit_count); /* safe, but overwrites nul */ |

667 | n/a | p[1] = '.'; |

668 | n/a | p += digit_count+1; |

669 | n/a | assert(p <= buf_size+buffer); |

670 | n/a | buf_avail = buf_size+buffer-p; |

671 | n/a | if (buf_avail == 0) |

672 | n/a | return NULL; |

673 | n/a | /* Add exponent. It's okay to use lower case 'e': we only |

674 | n/a | arrive here as a result of using the empty format code or |

675 | n/a | repr/str builtins and those never want an upper case 'E' */ |

676 | n/a | written = PyOS_snprintf(p, buf_avail, "e%+.02d", digit_count-1); |

677 | n/a | if (!(0 <= written && |

678 | n/a | written < Py_SAFE_DOWNCAST(buf_avail, size_t, int))) |

679 | n/a | /* output truncated, or something else bad happened */ |

680 | n/a | return NULL; |

681 | n/a | remove_trailing_zeros(buffer); |

682 | n/a | } |

683 | n/a | return buffer; |

684 | n/a | } |

685 | n/a | |

686 | n/a | /* see FORMATBUFLEN in unicodeobject.c */ |

687 | n/a | #define FLOAT_FORMATBUFLEN 120 |

688 | n/a | |

689 | n/a | /** |

690 | n/a | * _PyOS_ascii_formatd: |

691 | n/a | * @buffer: A buffer to place the resulting string in |

692 | n/a | * @buf_size: The length of the buffer. |

693 | n/a | * @format: The printf()-style format to use for the |

694 | n/a | * code to use for converting. |

695 | n/a | * @d: The #gdouble to convert |

696 | n/a | * @precision: The precision to use when formatting. |

697 | n/a | * |

698 | n/a | * Converts a #gdouble to a string, using the '.' as |

699 | n/a | * decimal point. To format the number you pass in |

700 | n/a | * a printf()-style format string. Allowed conversion |

701 | n/a | * specifiers are 'e', 'E', 'f', 'F', 'g', 'G', and 'Z'. |

702 | n/a | * |

703 | n/a | * 'Z' is the same as 'g', except it always has a decimal and |

704 | n/a | * at least one digit after the decimal. |

705 | n/a | * |

706 | n/a | * Return value: The pointer to the buffer with the converted string. |

707 | n/a | * On failure returns NULL but does not set any Python exception. |

708 | n/a | **/ |

709 | n/a | static char * |

710 | n/a | _PyOS_ascii_formatd(char *buffer, |

711 | n/a | size_t buf_size, |

712 | n/a | const char *format, |

713 | n/a | double d, |

714 | n/a | int precision) |

715 | n/a | { |

716 | n/a | char format_char; |

717 | n/a | size_t format_len = strlen(format); |

718 | n/a | |

719 | n/a | /* Issue 2264: code 'Z' requires copying the format. 'Z' is 'g', but |

720 | n/a | also with at least one character past the decimal. */ |

721 | n/a | char tmp_format[FLOAT_FORMATBUFLEN]; |

722 | n/a | |

723 | n/a | /* The last character in the format string must be the format char */ |

724 | n/a | format_char = format[format_len - 1]; |

725 | n/a | |

726 | n/a | if (format[0] != '%') |

727 | n/a | return NULL; |

728 | n/a | |

729 | n/a | /* I'm not sure why this test is here. It's ensuring that the format |

730 | n/a | string after the first character doesn't have a single quote, a |

731 | n/a | lowercase l, or a percent. This is the reverse of the commented-out |

732 | n/a | test about 10 lines ago. */ |

733 | n/a | if (strpbrk(format + 1, "'l%")) |

734 | n/a | return NULL; |

735 | n/a | |

736 | n/a | /* Also curious about this function is that it accepts format strings |

737 | n/a | like "%xg", which are invalid for floats. In general, the |

738 | n/a | interface to this function is not very good, but changing it is |

739 | n/a | difficult because it's a public API. */ |

740 | n/a | |

741 | n/a | if (!(format_char == 'e' || format_char == 'E' || |

742 | n/a | format_char == 'f' || format_char == 'F' || |

743 | n/a | format_char == 'g' || format_char == 'G' || |

744 | n/a | format_char == 'Z')) |

745 | n/a | return NULL; |

746 | n/a | |

747 | n/a | /* Map 'Z' format_char to 'g', by copying the format string and |

748 | n/a | replacing the final char with a 'g' */ |

749 | n/a | if (format_char == 'Z') { |

750 | n/a | if (format_len + 1 >= sizeof(tmp_format)) { |

751 | n/a | /* The format won't fit in our copy. Error out. In |

752 | n/a | practice, this will never happen and will be |

753 | n/a | detected by returning NULL */ |

754 | n/a | return NULL; |

755 | n/a | } |

756 | n/a | strcpy(tmp_format, format); |

757 | n/a | tmp_format[format_len - 1] = 'g'; |

758 | n/a | format = tmp_format; |

759 | n/a | } |

760 | n/a | |

761 | n/a | |

762 | n/a | /* Have PyOS_snprintf do the hard work */ |

763 | n/a | PyOS_snprintf(buffer, buf_size, format, d); |

764 | n/a | |

765 | n/a | /* Do various fixups on the return string */ |

766 | n/a | |

767 | n/a | /* Get the current locale, and find the decimal point string. |

768 | n/a | Convert that string back to a dot. */ |

769 | n/a | change_decimal_from_locale_to_dot(buffer); |

770 | n/a | |

771 | n/a | /* If an exponent exists, ensure that the exponent is at least |

772 | n/a | MIN_EXPONENT_DIGITS digits, providing the buffer is large enough |

773 | n/a | for the extra zeros. Also, if there are more than |

774 | n/a | MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get |

775 | n/a | back to MIN_EXPONENT_DIGITS */ |

776 | n/a | ensure_minimum_exponent_length(buffer, buf_size); |

777 | n/a | |

778 | n/a | /* If format_char is 'Z', make sure we have at least one character |

779 | n/a | after the decimal point (and make sure we have a decimal point); |

780 | n/a | also switch to exponential notation in some edge cases where the |

781 | n/a | extra character would produce more significant digits that we |

782 | n/a | really want. */ |

783 | n/a | if (format_char == 'Z') |

784 | n/a | buffer = ensure_decimal_point(buffer, buf_size, precision); |

785 | n/a | |

786 | n/a | return buffer; |

787 | n/a | } |

788 | n/a | |

789 | n/a | /* The fallback code to use if _Py_dg_dtoa is not available. */ |

790 | n/a | |

791 | n/a | PyAPI_FUNC(char *) PyOS_double_to_string(double val, |

792 | n/a | char format_code, |

793 | n/a | int precision, |

794 | n/a | int flags, |

795 | n/a | int *type) |

796 | n/a | { |

797 | n/a | char format[32]; |

798 | n/a | Py_ssize_t bufsize; |

799 | n/a | char *buf; |

800 | n/a | int t, exp; |

801 | n/a | int upper = 0; |

802 | n/a | |

803 | n/a | /* Validate format_code, and map upper and lower case */ |

804 | n/a | switch (format_code) { |

805 | n/a | case 'e': /* exponent */ |

806 | n/a | case 'f': /* fixed */ |

807 | n/a | case 'g': /* general */ |

808 | n/a | break; |

809 | n/a | case 'E': |

810 | n/a | upper = 1; |

811 | n/a | format_code = 'e'; |

812 | n/a | break; |

813 | n/a | case 'F': |

814 | n/a | upper = 1; |

815 | n/a | format_code = 'f'; |

816 | n/a | break; |

817 | n/a | case 'G': |

818 | n/a | upper = 1; |

819 | n/a | format_code = 'g'; |

820 | n/a | break; |

821 | n/a | case 'r': /* repr format */ |

822 | n/a | /* Supplied precision is unused, must be 0. */ |

823 | n/a | if (precision != 0) { |

824 | n/a | PyErr_BadInternalCall(); |

825 | n/a | return NULL; |

826 | n/a | } |

827 | n/a | /* The repr() precision (17 significant decimal digits) is the |

828 | n/a | minimal number that is guaranteed to have enough precision |

829 | n/a | so that if the number is read back in the exact same binary |

830 | n/a | value is recreated. This is true for IEEE floating point |

831 | n/a | by design, and also happens to work for all other modern |

832 | n/a | hardware. */ |

833 | n/a | precision = 17; |

834 | n/a | format_code = 'g'; |

835 | n/a | break; |

836 | n/a | default: |

837 | n/a | PyErr_BadInternalCall(); |

838 | n/a | return NULL; |

839 | n/a | } |

840 | n/a | |

841 | n/a | /* Here's a quick-and-dirty calculation to figure out how big a buffer |

842 | n/a | we need. In general, for a finite float we need: |

843 | n/a | |

844 | n/a | 1 byte for each digit of the decimal significand, and |

845 | n/a | |

846 | n/a | 1 for a possible sign |

847 | n/a | 1 for a possible decimal point |

848 | n/a | 2 for a possible [eE][+-] |

849 | n/a | 1 for each digit of the exponent; if we allow 19 digits |

850 | n/a | total then we're safe up to exponents of 2**63. |

851 | n/a | 1 for the trailing nul byte |

852 | n/a | |

853 | n/a | This gives a total of 24 + the number of digits in the significand, |

854 | n/a | and the number of digits in the significand is: |

855 | n/a | |

856 | n/a | for 'g' format: at most precision, except possibly |

857 | n/a | when precision == 0, when it's 1. |

858 | n/a | for 'e' format: precision+1 |

859 | n/a | for 'f' format: precision digits after the point, at least 1 |

860 | n/a | before. To figure out how many digits appear before the point |

861 | n/a | we have to examine the size of the number. If fabs(val) < 1.0 |

862 | n/a | then there will be only one digit before the point. If |

863 | n/a | fabs(val) >= 1.0, then there are at most |

864 | n/a | |

865 | n/a | 1+floor(log10(ceiling(fabs(val)))) |

866 | n/a | |

867 | n/a | digits before the point (where the 'ceiling' allows for the |

868 | n/a | possibility that the rounding rounds the integer part of val |

869 | n/a | up). A safe upper bound for the above quantity is |

870 | n/a | 1+floor(exp/3), where exp is the unique integer such that 0.5 |

871 | n/a | <= fabs(val)/2**exp < 1.0. This exp can be obtained from |

872 | n/a | frexp. |

873 | n/a | |

874 | n/a | So we allow room for precision+1 digits for all formats, plus an |

875 | n/a | extra floor(exp/3) digits for 'f' format. |

876 | n/a | |

877 | n/a | */ |

878 | n/a | |

879 | n/a | if (Py_IS_NAN(val) || Py_IS_INFINITY(val)) |

880 | n/a | /* 3 for 'inf'/'nan', 1 for sign, 1 for '\0' */ |

881 | n/a | bufsize = 5; |

882 | n/a | else { |

883 | n/a | bufsize = 25 + precision; |

884 | n/a | if (format_code == 'f' && fabs(val) >= 1.0) { |

885 | n/a | frexp(val, &exp); |

886 | n/a | bufsize += exp/3; |

887 | n/a | } |

888 | n/a | } |

889 | n/a | |

890 | n/a | buf = PyMem_Malloc(bufsize); |

891 | n/a | if (buf == NULL) { |

892 | n/a | PyErr_NoMemory(); |

893 | n/a | return NULL; |

894 | n/a | } |

895 | n/a | |

896 | n/a | /* Handle nan and inf. */ |

897 | n/a | if (Py_IS_NAN(val)) { |

898 | n/a | strcpy(buf, "nan"); |

899 | n/a | t = Py_DTST_NAN; |

900 | n/a | } else if (Py_IS_INFINITY(val)) { |

901 | n/a | if (copysign(1., val) == 1.) |

902 | n/a | strcpy(buf, "inf"); |

903 | n/a | else |

904 | n/a | strcpy(buf, "-inf"); |

905 | n/a | t = Py_DTST_INFINITE; |

906 | n/a | } else { |

907 | n/a | t = Py_DTST_FINITE; |

908 | n/a | if (flags & Py_DTSF_ADD_DOT_0) |

909 | n/a | format_code = 'Z'; |

910 | n/a | |

911 | n/a | PyOS_snprintf(format, sizeof(format), "%%%s.%i%c", |

912 | n/a | (flags & Py_DTSF_ALT ? "#" : ""), precision, |

913 | n/a | format_code); |

914 | n/a | _PyOS_ascii_formatd(buf, bufsize, format, val, precision); |

915 | n/a | } |

916 | n/a | |

917 | n/a | /* Add sign when requested. It's convenient (esp. when formatting |

918 | n/a | complex numbers) to include a sign even for inf and nan. */ |

919 | n/a | if (flags & Py_DTSF_SIGN && buf[0] != '-') { |

920 | n/a | size_t len = strlen(buf); |

921 | n/a | /* the bufsize calculations above should ensure that we've got |

922 | n/a | space to add a sign */ |

923 | n/a | assert((size_t)bufsize >= len+2); |

924 | n/a | memmove(buf+1, buf, len+1); |

925 | n/a | buf[0] = '+'; |

926 | n/a | } |

927 | n/a | if (upper) { |

928 | n/a | /* Convert to upper case. */ |

929 | n/a | char *p1; |

930 | n/a | for (p1 = buf; *p1; p1++) |

931 | n/a | *p1 = Py_TOUPPER(*p1); |

932 | n/a | } |

933 | n/a | |

934 | n/a | if (type) |

935 | n/a | *type = t; |

936 | n/a | return buf; |

937 | n/a | } |

938 | n/a | |

939 | n/a | #else |

940 | n/a | |

941 | n/a | /* _Py_dg_dtoa is available. */ |

942 | n/a | |

943 | n/a | /* I'm using a lookup table here so that I don't have to invent a non-locale |

944 | n/a | specific way to convert to uppercase */ |

945 | n/a | #define OFS_INF 0 |

946 | n/a | #define OFS_NAN 1 |

947 | n/a | #define OFS_E 2 |

948 | n/a | |

949 | n/a | /* The lengths of these are known to the code below, so don't change them */ |

950 | n/a | static const char * const lc_float_strings[] = { |

951 | n/a | "inf", |

952 | n/a | "nan", |

953 | n/a | "e", |

954 | n/a | }; |

955 | n/a | static const char * const uc_float_strings[] = { |

956 | n/a | "INF", |

957 | n/a | "NAN", |

958 | n/a | "E", |

959 | n/a | }; |

960 | n/a | |

961 | n/a | |

962 | n/a | /* Convert a double d to a string, and return a PyMem_Malloc'd block of |

963 | n/a | memory contain the resulting string. |

964 | n/a | |

965 | n/a | Arguments: |

966 | n/a | d is the double to be converted |

967 | n/a | format_code is one of 'e', 'f', 'g', 'r'. 'e', 'f' and 'g' |

968 | n/a | correspond to '%e', '%f' and '%g'; 'r' corresponds to repr. |

969 | n/a | mode is one of '0', '2' or '3', and is completely determined by |

970 | n/a | format_code: 'e' and 'g' use mode 2; 'f' mode 3, 'r' mode 0. |

971 | n/a | precision is the desired precision |

972 | n/a | always_add_sign is nonzero if a '+' sign should be included for positive |

973 | n/a | numbers |

974 | n/a | add_dot_0_if_integer is nonzero if integers in non-exponential form |

975 | n/a | should have ".0" added. Only applies to format codes 'r' and 'g'. |

976 | n/a | use_alt_formatting is nonzero if alternative formatting should be |

977 | n/a | used. Only applies to format codes 'e', 'f' and 'g'. For code 'g', |

978 | n/a | at most one of use_alt_formatting and add_dot_0_if_integer should |

979 | n/a | be nonzero. |

980 | n/a | type, if non-NULL, will be set to one of these constants to identify |

981 | n/a | the type of the 'd' argument: |

982 | n/a | Py_DTST_FINITE |

983 | n/a | Py_DTST_INFINITE |

984 | n/a | Py_DTST_NAN |

985 | n/a | |

986 | n/a | Returns a PyMem_Malloc'd block of memory containing the resulting string, |

987 | n/a | or NULL on error. If NULL is returned, the Python error has been set. |

988 | n/a | */ |

989 | n/a | |

990 | n/a | static char * |

991 | n/a | format_float_short(double d, char format_code, |

992 | n/a | int mode, int precision, |

993 | n/a | int always_add_sign, int add_dot_0_if_integer, |

994 | n/a | int use_alt_formatting, const char * const *float_strings, |

995 | n/a | int *type) |

996 | n/a | { |

997 | n/a | char *buf = NULL; |

998 | n/a | char *p = NULL; |

999 | n/a | Py_ssize_t bufsize = 0; |

1000 | n/a | char *digits, *digits_end; |

1001 | n/a | int decpt_as_int, sign, exp_len, exp = 0, use_exp = 0; |

1002 | n/a | Py_ssize_t decpt, digits_len, vdigits_start, vdigits_end; |

1003 | n/a | _Py_SET_53BIT_PRECISION_HEADER; |

1004 | n/a | |

1005 | n/a | /* _Py_dg_dtoa returns a digit string (no decimal point or exponent). |

1006 | n/a | Must be matched by a call to _Py_dg_freedtoa. */ |

1007 | n/a | _Py_SET_53BIT_PRECISION_START; |

1008 | n/a | digits = _Py_dg_dtoa(d, mode, precision, &decpt_as_int, &sign, |

1009 | n/a | &digits_end); |

1010 | n/a | _Py_SET_53BIT_PRECISION_END; |

1011 | n/a | |

1012 | n/a | decpt = (Py_ssize_t)decpt_as_int; |

1013 | n/a | if (digits == NULL) { |

1014 | n/a | /* The only failure mode is no memory. */ |

1015 | n/a | PyErr_NoMemory(); |

1016 | n/a | goto exit; |

1017 | n/a | } |

1018 | n/a | assert(digits_end != NULL && digits_end >= digits); |

1019 | n/a | digits_len = digits_end - digits; |

1020 | n/a | |

1021 | n/a | if (digits_len && !Py_ISDIGIT(digits[0])) { |

1022 | n/a | /* Infinities and nans here; adapt Gay's output, |

1023 | n/a | so convert Infinity to inf and NaN to nan, and |

1024 | n/a | ignore sign of nan. Then return. */ |

1025 | n/a | |

1026 | n/a | /* ignore the actual sign of a nan */ |

1027 | n/a | if (digits[0] == 'n' || digits[0] == 'N') |

1028 | n/a | sign = 0; |

1029 | n/a | |

1030 | n/a | /* We only need 5 bytes to hold the result "+inf\0" . */ |

1031 | n/a | bufsize = 5; /* Used later in an assert. */ |

1032 | n/a | buf = (char *)PyMem_Malloc(bufsize); |

1033 | n/a | if (buf == NULL) { |

1034 | n/a | PyErr_NoMemory(); |

1035 | n/a | goto exit; |

1036 | n/a | } |

1037 | n/a | p = buf; |

1038 | n/a | |

1039 | n/a | if (sign == 1) { |

1040 | n/a | *p++ = '-'; |

1041 | n/a | } |

1042 | n/a | else if (always_add_sign) { |

1043 | n/a | *p++ = '+'; |

1044 | n/a | } |

1045 | n/a | if (digits[0] == 'i' || digits[0] == 'I') { |

1046 | n/a | strncpy(p, float_strings[OFS_INF], 3); |

1047 | n/a | p += 3; |

1048 | n/a | |

1049 | n/a | if (type) |

1050 | n/a | *type = Py_DTST_INFINITE; |

1051 | n/a | } |

1052 | n/a | else if (digits[0] == 'n' || digits[0] == 'N') { |

1053 | n/a | strncpy(p, float_strings[OFS_NAN], 3); |

1054 | n/a | p += 3; |

1055 | n/a | |

1056 | n/a | if (type) |

1057 | n/a | *type = Py_DTST_NAN; |

1058 | n/a | } |

1059 | n/a | else { |

1060 | n/a | /* shouldn't get here: Gay's code should always return |

1061 | n/a | something starting with a digit, an 'I', or 'N' */ |

1062 | n/a | strncpy(p, "ERR", 3); |

1063 | n/a | /* p += 3; */ |

1064 | n/a | assert(0); |

1065 | n/a | } |

1066 | n/a | goto exit; |

1067 | n/a | } |

1068 | n/a | |

1069 | n/a | /* The result must be finite (not inf or nan). */ |

1070 | n/a | if (type) |

1071 | n/a | *type = Py_DTST_FINITE; |

1072 | n/a | |

1073 | n/a | |

1074 | n/a | /* We got digits back, format them. We may need to pad 'digits' |

1075 | n/a | either on the left or right (or both) with extra zeros, so in |

1076 | n/a | general the resulting string has the form |

1077 | n/a | |

1078 | n/a | [<sign>]<zeros><digits><zeros>[<exponent>] |

1079 | n/a | |

1080 | n/a | where either of the <zeros> pieces could be empty, and there's a |

1081 | n/a | decimal point that could appear either in <digits> or in the |

1082 | n/a | leading or trailing <zeros>. |

1083 | n/a | |

1084 | n/a | Imagine an infinite 'virtual' string vdigits, consisting of the |

1085 | n/a | string 'digits' (starting at index 0) padded on both the left and |

1086 | n/a | right with infinite strings of zeros. We want to output a slice |

1087 | n/a | |

1088 | n/a | vdigits[vdigits_start : vdigits_end] |

1089 | n/a | |

1090 | n/a | of this virtual string. Thus if vdigits_start < 0 then we'll end |

1091 | n/a | up producing some leading zeros; if vdigits_end > digits_len there |

1092 | n/a | will be trailing zeros in the output. The next section of code |

1093 | n/a | determines whether to use an exponent or not, figures out the |

1094 | n/a | position 'decpt' of the decimal point, and computes 'vdigits_start' |

1095 | n/a | and 'vdigits_end'. */ |

1096 | n/a | vdigits_end = digits_len; |

1097 | n/a | switch (format_code) { |

1098 | n/a | case 'e': |

1099 | n/a | use_exp = 1; |

1100 | n/a | vdigits_end = precision; |

1101 | n/a | break; |

1102 | n/a | case 'f': |

1103 | n/a | vdigits_end = decpt + precision; |

1104 | n/a | break; |

1105 | n/a | case 'g': |

1106 | n/a | if (decpt <= -4 || decpt > |

1107 | n/a | (add_dot_0_if_integer ? precision-1 : precision)) |

1108 | n/a | use_exp = 1; |

1109 | n/a | if (use_alt_formatting) |

1110 | n/a | vdigits_end = precision; |

1111 | n/a | break; |

1112 | n/a | case 'r': |

1113 | n/a | /* convert to exponential format at 1e16. We used to convert |

1114 | n/a | at 1e17, but that gives odd-looking results for some values |

1115 | n/a | when a 16-digit 'shortest' repr is padded with bogus zeros. |

1116 | n/a | For example, repr(2e16+8) would give 20000000000000010.0; |

1117 | n/a | the true value is 20000000000000008.0. */ |

1118 | n/a | if (decpt <= -4 || decpt > 16) |

1119 | n/a | use_exp = 1; |

1120 | n/a | break; |

1121 | n/a | default: |

1122 | n/a | PyErr_BadInternalCall(); |

1123 | n/a | goto exit; |

1124 | n/a | } |

1125 | n/a | |

1126 | n/a | /* if using an exponent, reset decimal point position to 1 and adjust |

1127 | n/a | exponent accordingly.*/ |

1128 | n/a | if (use_exp) { |

1129 | n/a | exp = (int)decpt - 1; |

1130 | n/a | decpt = 1; |

1131 | n/a | } |

1132 | n/a | /* ensure vdigits_start < decpt <= vdigits_end, or vdigits_start < |

1133 | n/a | decpt < vdigits_end if add_dot_0_if_integer and no exponent */ |

1134 | n/a | vdigits_start = decpt <= 0 ? decpt-1 : 0; |

1135 | n/a | if (!use_exp && add_dot_0_if_integer) |

1136 | n/a | vdigits_end = vdigits_end > decpt ? vdigits_end : decpt + 1; |

1137 | n/a | else |

1138 | n/a | vdigits_end = vdigits_end > decpt ? vdigits_end : decpt; |

1139 | n/a | |

1140 | n/a | /* double check inequalities */ |

1141 | n/a | assert(vdigits_start <= 0 && |

1142 | n/a | 0 <= digits_len && |

1143 | n/a | digits_len <= vdigits_end); |

1144 | n/a | /* decimal point should be in (vdigits_start, vdigits_end] */ |

1145 | n/a | assert(vdigits_start < decpt && decpt <= vdigits_end); |

1146 | n/a | |

1147 | n/a | /* Compute an upper bound how much memory we need. This might be a few |

1148 | n/a | chars too long, but no big deal. */ |

1149 | n/a | bufsize = |

1150 | n/a | /* sign, decimal point and trailing 0 byte */ |

1151 | n/a | 3 + |

1152 | n/a | |

1153 | n/a | /* total digit count (including zero padding on both sides) */ |

1154 | n/a | (vdigits_end - vdigits_start) + |

1155 | n/a | |

1156 | n/a | /* exponent "e+100", max 3 numerical digits */ |

1157 | n/a | (use_exp ? 5 : 0); |

1158 | n/a | |

1159 | n/a | /* Now allocate the memory and initialize p to point to the start of |

1160 | n/a | it. */ |

1161 | n/a | buf = (char *)PyMem_Malloc(bufsize); |

1162 | n/a | if (buf == NULL) { |

1163 | n/a | PyErr_NoMemory(); |

1164 | n/a | goto exit; |

1165 | n/a | } |

1166 | n/a | p = buf; |

1167 | n/a | |

1168 | n/a | /* Add a negative sign if negative, and a plus sign if non-negative |

1169 | n/a | and always_add_sign is true. */ |

1170 | n/a | if (sign == 1) |

1171 | n/a | *p++ = '-'; |

1172 | n/a | else if (always_add_sign) |

1173 | n/a | *p++ = '+'; |

1174 | n/a | |

1175 | n/a | /* note that exactly one of the three 'if' conditions is true, |

1176 | n/a | so we include exactly one decimal point */ |

1177 | n/a | /* Zero padding on left of digit string */ |

1178 | n/a | if (decpt <= 0) { |

1179 | n/a | memset(p, '0', decpt-vdigits_start); |

1180 | n/a | p += decpt - vdigits_start; |

1181 | n/a | *p++ = '.'; |

1182 | n/a | memset(p, '0', 0-decpt); |

1183 | n/a | p += 0-decpt; |

1184 | n/a | } |

1185 | n/a | else { |

1186 | n/a | memset(p, '0', 0-vdigits_start); |

1187 | n/a | p += 0 - vdigits_start; |

1188 | n/a | } |

1189 | n/a | |

1190 | n/a | /* Digits, with included decimal point */ |

1191 | n/a | if (0 < decpt && decpt <= digits_len) { |

1192 | n/a | strncpy(p, digits, decpt-0); |

1193 | n/a | p += decpt-0; |

1194 | n/a | *p++ = '.'; |

1195 | n/a | strncpy(p, digits+decpt, digits_len-decpt); |

1196 | n/a | p += digits_len-decpt; |

1197 | n/a | } |

1198 | n/a | else { |

1199 | n/a | strncpy(p, digits, digits_len); |

1200 | n/a | p += digits_len; |

1201 | n/a | } |

1202 | n/a | |

1203 | n/a | /* And zeros on the right */ |

1204 | n/a | if (digits_len < decpt) { |

1205 | n/a | memset(p, '0', decpt-digits_len); |

1206 | n/a | p += decpt-digits_len; |

1207 | n/a | *p++ = '.'; |

1208 | n/a | memset(p, '0', vdigits_end-decpt); |

1209 | n/a | p += vdigits_end-decpt; |

1210 | n/a | } |

1211 | n/a | else { |

1212 | n/a | memset(p, '0', vdigits_end-digits_len); |

1213 | n/a | p += vdigits_end-digits_len; |

1214 | n/a | } |

1215 | n/a | |

1216 | n/a | /* Delete a trailing decimal pt unless using alternative formatting. */ |

1217 | n/a | if (p[-1] == '.' && !use_alt_formatting) |

1218 | n/a | p--; |

1219 | n/a | |

1220 | n/a | /* Now that we've done zero padding, add an exponent if needed. */ |

1221 | n/a | if (use_exp) { |

1222 | n/a | *p++ = float_strings[OFS_E][0]; |

1223 | n/a | exp_len = sprintf(p, "%+.02d", exp); |

1224 | n/a | p += exp_len; |

1225 | n/a | } |

1226 | n/a | exit: |

1227 | n/a | if (buf) { |

1228 | n/a | *p = '\0'; |

1229 | n/a | /* It's too late if this fails, as we've already stepped on |

1230 | n/a | memory that isn't ours. But it's an okay debugging test. */ |

1231 | n/a | assert(p-buf < bufsize); |

1232 | n/a | } |

1233 | n/a | if (digits) |

1234 | n/a | _Py_dg_freedtoa(digits); |

1235 | n/a | |

1236 | n/a | return buf; |

1237 | n/a | } |

1238 | n/a | |

1239 | n/a | |

1240 | n/a | PyAPI_FUNC(char *) PyOS_double_to_string(double val, |

1241 | n/a | char format_code, |

1242 | n/a | int precision, |

1243 | n/a | int flags, |

1244 | n/a | int *type) |

1245 | n/a | { |

1246 | n/a | const char * const *float_strings = lc_float_strings; |

1247 | n/a | int mode; |

1248 | n/a | |

1249 | n/a | /* Validate format_code, and map upper and lower case. Compute the |

1250 | n/a | mode and make any adjustments as needed. */ |

1251 | n/a | switch (format_code) { |

1252 | n/a | /* exponent */ |

1253 | n/a | case 'E': |

1254 | n/a | float_strings = uc_float_strings; |

1255 | n/a | format_code = 'e'; |

1256 | n/a | /* Fall through. */ |

1257 | n/a | case 'e': |

1258 | n/a | mode = 2; |

1259 | n/a | precision++; |

1260 | n/a | break; |

1261 | n/a | |

1262 | n/a | /* fixed */ |

1263 | n/a | case 'F': |

1264 | n/a | float_strings = uc_float_strings; |

1265 | n/a | format_code = 'f'; |

1266 | n/a | /* Fall through. */ |

1267 | n/a | case 'f': |

1268 | n/a | mode = 3; |

1269 | n/a | break; |

1270 | n/a | |

1271 | n/a | /* general */ |

1272 | n/a | case 'G': |

1273 | n/a | float_strings = uc_float_strings; |

1274 | n/a | format_code = 'g'; |

1275 | n/a | /* Fall through. */ |

1276 | n/a | case 'g': |

1277 | n/a | mode = 2; |

1278 | n/a | /* precision 0 makes no sense for 'g' format; interpret as 1 */ |

1279 | n/a | if (precision == 0) |

1280 | n/a | precision = 1; |

1281 | n/a | break; |

1282 | n/a | |

1283 | n/a | /* repr format */ |

1284 | n/a | case 'r': |

1285 | n/a | mode = 0; |

1286 | n/a | /* Supplied precision is unused, must be 0. */ |

1287 | n/a | if (precision != 0) { |

1288 | n/a | PyErr_BadInternalCall(); |

1289 | n/a | return NULL; |

1290 | n/a | } |

1291 | n/a | break; |

1292 | n/a | |

1293 | n/a | default: |

1294 | n/a | PyErr_BadInternalCall(); |

1295 | n/a | return NULL; |

1296 | n/a | } |

1297 | n/a | |

1298 | n/a | return format_float_short(val, format_code, mode, precision, |

1299 | n/a | flags & Py_DTSF_SIGN, |

1300 | n/a | flags & Py_DTSF_ADD_DOT_0, |

1301 | n/a | flags & Py_DTSF_ALT, |

1302 | n/a | float_strings, type); |

1303 | n/a | } |

1304 | n/a | #endif /* ifdef PY_NO_SHORT_FLOAT_REPR */ |