annotate Python/dtoa.c @ 87680:02d186e3af09 2.7

Fixed JSON tests on wide build when ran from *.pyc files (issue #11489).
author Serhiy Storchaka <storchaka@gmail.com>
date Sun, 01 Dec 2013 17:30:55 +0200
parents 6d6a018a3bb0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1 /****************************************************************
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
3 * The author of this software is David M. Gay.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
4 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
5 * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
6 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
7 * Permission to use, copy, modify, and distribute this software for any
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
8 * purpose without fee is hereby granted, provided that this entire notice
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
9 * is included in all copies of any software which is or includes a copy
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
10 * or modification of this software and in all copies of the supporting
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
11 * documentation for such software.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
12 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
13 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
14 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
15 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
16 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
17 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
18 ***************************************************************/
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
19
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
20 /****************************************************************
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
21 * This is dtoa.c by David M. Gay, downloaded from
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
22 * http://www.netlib.org/fp/dtoa.c on April 15, 2009 and modified for
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
23 * inclusion into the Python core by Mark E. T. Dickinson and Eric V. Smith.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
24 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
25 * Please remember to check http://www.netlib.org/fp regularly (and especially
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
26 * before any Python release) for bugfixes and updates.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
27 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
28 * The major modifications from Gay's original code are as follows:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
29 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
30 * 0. The original code has been specialized to Python's needs by removing
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
31 * many of the #ifdef'd sections. In particular, code to support VAX and
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
32 * IBM floating-point formats, hex NaNs, hex floats, locale-aware
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
33 * treatment of the decimal point, and setting of the inexact flag have
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
34 * been removed.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
35 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
36 * 1. We use PyMem_Malloc and PyMem_Free in place of malloc and free.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
37 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
38 * 2. The public functions strtod, dtoa and freedtoa all now have
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
39 * a _Py_dg_ prefix.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
40 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
41 * 3. Instead of assuming that PyMem_Malloc always succeeds, we thread
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
42 * PyMem_Malloc failures through the code. The functions
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
43 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
44 * Balloc, multadd, s2b, i2b, mult, pow5mult, lshift, diff, d2b
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
45 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
46 * of return type *Bigint all return NULL to indicate a malloc failure.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
47 * Similarly, rv_alloc and nrv_alloc (return type char *) return NULL on
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
48 * failure. bigcomp now has return type int (it used to be void) and
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
49 * returns -1 on failure and 0 otherwise. _Py_dg_dtoa returns NULL
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
50 * on failure. _Py_dg_strtod indicates failure due to malloc failure
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
51 * by returning -1.0, setting errno=ENOMEM and *se to s00.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
52 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
53 * 4. The static variable dtoa_result has been removed. Callers of
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
54 * _Py_dg_dtoa are expected to call _Py_dg_freedtoa to free
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
55 * the memory allocated by _Py_dg_dtoa.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
56 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
57 * 5. The code has been reformatted to better fit with Python's
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
58 * C style guide (PEP 7).
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
59 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
60 * 6. A bug in the memory allocation has been fixed: to avoid FREEing memory
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
61 * that hasn't been MALLOC'ed, private_mem should only be used when k <=
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
62 * Kmax.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
63 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
64 * 7. _Py_dg_strtod has been modified so that it doesn't accept strings with
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
65 * leading whitespace.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
66 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
67 ***************************************************************/
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
68
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
69 /* Please send bug reports for the original dtoa.c code to David M. Gay (dmg
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
70 * at acm dot org, with " at " changed at "@" and " dot " changed to ".").
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
71 * Please report bugs for this modified version using the Python issue tracker
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
72 * (http://bugs.python.org). */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
73
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
74 /* On a machine with IEEE extended-precision registers, it is
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
75 * necessary to specify double-precision (53-bit) rounding precision
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
76 * before invoking strtod or dtoa. If the machine uses (the equivalent
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
77 * of) Intel 80x87 arithmetic, the call
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
78 * _control87(PC_53, MCW_PC);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
79 * does this with many compilers. Whether this or another call is
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
80 * appropriate depends on the compiler; for this to work, it may be
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
81 * necessary to #include "float.h" or another system-dependent header
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
82 * file.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
83 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
84
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
85 /* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
86 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
87 * This strtod returns a nearest machine number to the input decimal
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
88 * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
89 * broken by the IEEE round-even rule. Otherwise ties are broken by
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
90 * biased rounding (add half and chop).
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
91 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
92 * Inspired loosely by William D. Clinger's paper "How to Read Floating
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
93 * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
94 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
95 * Modifications:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
96 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
97 * 1. We only require IEEE, IBM, or VAX double-precision
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
98 * arithmetic (not IEEE double-extended).
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
99 * 2. We get by with floating-point arithmetic in a case that
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
100 * Clinger missed -- when we're computing d * 10^n
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
101 * for a small integer d and the integer n is not too
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
102 * much larger than 22 (the maximum integer k for which
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
103 * we can represent 10^k exactly), we may be able to
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
104 * compute (d*10^k) * 10^(e-k) with just one roundoff.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
105 * 3. Rather than a bit-at-a-time adjustment of the binary
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
106 * result in the hard case, we use floating-point
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
107 * arithmetic to determine the adjustment to within
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
108 * one bit; only in really hard cases do we need to
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
109 * compute a second residual.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
110 * 4. Because of 3., we don't need a large table of powers of 10
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
111 * for ten-to-e (just some small tables, e.g. of 10^k
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
112 * for 0 <= k <= 22).
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
113 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
114
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
115 /* Linking of Python's #defines to Gay's #defines starts here. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
116
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
117 #include "Python.h"
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
118
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
119 /* if PY_NO_SHORT_FLOAT_REPR is defined, then don't even try to compile
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
120 the following code */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
121 #ifndef PY_NO_SHORT_FLOAT_REPR
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
122
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
123 #include "float.h"
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
124
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
125 #define MALLOC PyMem_Malloc
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
126 #define FREE PyMem_Free
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
127
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
128 /* This code should also work for ARM mixed-endian format on little-endian
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
129 machines, where doubles have byte order 45670123 (in increasing address
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
130 order, 0 being the least significant byte). */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
131 #ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
132 # define IEEE_8087
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
133 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
134 #if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || \
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
135 defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
136 # define IEEE_MC68k
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
137 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
138 #if defined(IEEE_8087) + defined(IEEE_MC68k) != 1
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
139 #error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined."
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
140 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
141
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
142 /* The code below assumes that the endianness of integers matches the
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
143 endianness of the two 32-bit words of a double. Check this. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
144 #if defined(WORDS_BIGENDIAN) && (defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) || \
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
145 defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
146 #error "doubles and ints have incompatible endianness"
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
147 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
148
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
149 #if !defined(WORDS_BIGENDIAN) && defined(DOUBLE_IS_BIG_ENDIAN_IEEE754)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
150 #error "doubles and ints have incompatible endianness"
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
151 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
152
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
153
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
154 #if defined(HAVE_UINT32_T) && defined(HAVE_INT32_T)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
155 typedef PY_UINT32_T ULong;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
156 typedef PY_INT32_T Long;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
157 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
158 #error "Failed to find an exact-width 32-bit integer type"
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
159 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
160
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
161 #if defined(HAVE_UINT64_T)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
162 #define ULLong PY_UINT64_T
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
163 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
164 #undef ULLong
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
165 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
166
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
167 #undef DEBUG
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
168 #ifdef Py_DEBUG
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
169 #define DEBUG
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
170 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
171
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
172 /* End Python #define linking */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
173
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
174 #ifdef DEBUG
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
175 #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
176 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
177
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
178 #ifndef PRIVATE_MEM
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
179 #define PRIVATE_MEM 2304
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
180 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
181 #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
182 static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
183
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
184 #ifdef __cplusplus
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
185 extern "C" {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
186 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
187
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
188 typedef union { double d; ULong L[2]; } U;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
189
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
190 #ifdef IEEE_8087
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
191 #define word0(x) (x)->L[1]
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
192 #define word1(x) (x)->L[0]
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
193 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
194 #define word0(x) (x)->L[0]
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
195 #define word1(x) (x)->L[1]
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
196 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
197 #define dval(x) (x)->d
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
198
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
199 #ifndef STRTOD_DIGLIM
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
200 #define STRTOD_DIGLIM 40
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
201 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
202
58249
33e402909cf2 Change a variable type to avoid signed overflow; replace repeated '19999' constant by a define.
Mark Dickinson <dickinsm@gmail.com>
parents: 58239
diff changeset
203 /* maximum permitted exponent value for strtod; exponents larger than
33e402909cf2 Change a variable type to avoid signed overflow; replace repeated '19999' constant by a define.
Mark Dickinson <dickinsm@gmail.com>
parents: 58239
diff changeset
204 MAX_ABS_EXP in absolute value get truncated to +-MAX_ABS_EXP. MAX_ABS_EXP
33e402909cf2 Change a variable type to avoid signed overflow; replace repeated '19999' constant by a define.
Mark Dickinson <dickinsm@gmail.com>
parents: 58239
diff changeset
205 should fit into an int. */
33e402909cf2 Change a variable type to avoid signed overflow; replace repeated '19999' constant by a define.
Mark Dickinson <dickinsm@gmail.com>
parents: 58239
diff changeset
206 #ifndef MAX_ABS_EXP
87584
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
207 #define MAX_ABS_EXP 1100000000U
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
208 #endif
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
209 /* Bound on length of pieces of input strings in _Py_dg_strtod; specifically,
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
210 this is used to bound the total number of digits ignoring leading zeros and
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
211 the number of digits that follow the decimal point. Ideally, MAX_DIGITS
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
212 should satisfy MAX_DIGITS + 400 < MAX_ABS_EXP; that ensures that the
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
213 exponent clipping in _Py_dg_strtod can't affect the value of the output. */
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
214 #ifndef MAX_DIGITS
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
215 #define MAX_DIGITS 1000000000U
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
216 #endif
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
217
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
218 /* Guard against trying to use the above values on unusual platforms with ints
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
219 * of width less than 32 bits. */
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
220 #if MAX_ABS_EXP > INT_MAX
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
221 #error "MAX_ABS_EXP should fit in an int"
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
222 #endif
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
223 #if MAX_DIGITS > INT_MAX
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
224 #error "MAX_DIGITS should fit in an int"
58249
33e402909cf2 Change a variable type to avoid signed overflow; replace repeated '19999' constant by a define.
Mark Dickinson <dickinsm@gmail.com>
parents: 58239
diff changeset
225 #endif
33e402909cf2 Change a variable type to avoid signed overflow; replace repeated '19999' constant by a define.
Mark Dickinson <dickinsm@gmail.com>
parents: 58239
diff changeset
226
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
227 /* The following definition of Storeinc is appropriate for MIPS processors.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
228 * An alternative that might be better on some machines is
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
229 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
230 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
231 #if defined(IEEE_8087)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
232 #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
233 ((unsigned short *)a)[0] = (unsigned short)c, a++)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
234 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
235 #define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
236 ((unsigned short *)a)[1] = (unsigned short)c, a++)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
237 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
238
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
239 /* #define P DBL_MANT_DIG */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
240 /* Ten_pmax = floor(P*log(2)/log(5)) */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
241 /* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
242 /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
243 /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
244
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
245 #define Exp_shift 20
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
246 #define Exp_shift1 20
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
247 #define Exp_msk1 0x100000
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
248 #define Exp_msk11 0x100000
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
249 #define Exp_mask 0x7ff00000
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
250 #define P 53
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
251 #define Nbits 53
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
252 #define Bias 1023
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
253 #define Emax 1023
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
254 #define Emin (-1022)
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
255 #define Etiny (-1074) /* smallest denormal is 2**Etiny */
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
256 #define Exp_1 0x3ff00000
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
257 #define Exp_11 0x3ff00000
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
258 #define Ebits 11
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
259 #define Frac_mask 0xfffff
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
260 #define Frac_mask1 0xfffff
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
261 #define Ten_pmax 22
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
262 #define Bletch 0x10
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
263 #define Bndry_mask 0xfffff
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
264 #define Bndry_mask1 0xfffff
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
265 #define Sign_bit 0x80000000
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
266 #define Log2P 1
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
267 #define Tiny0 0
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
268 #define Tiny1 1
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
269 #define Quick_max 14
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
270 #define Int_max 14
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
271
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
272 #ifndef Flt_Rounds
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
273 #ifdef FLT_ROUNDS
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
274 #define Flt_Rounds FLT_ROUNDS
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
275 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
276 #define Flt_Rounds 1
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
277 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
278 #endif /*Flt_Rounds*/
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
279
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
280 #define Rounding Flt_Rounds
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
281
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
282 #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
283 #define Big1 0xffffffff
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
284
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
285 /* struct BCinfo is used to pass information from _Py_dg_strtod to bigcomp */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
286
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
287 typedef struct BCinfo BCinfo;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
288 struct
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
289 BCinfo {
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
290 int e0, nd, nd0, scale;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
291 };
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
292
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
293 #define FFFFFFFF 0xffffffffUL
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
294
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
295 #define Kmax 7
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
296
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
297 /* struct Bigint is used to represent arbitrary-precision integers. These
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
298 integers are stored in sign-magnitude format, with the magnitude stored as
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
299 an array of base 2**32 digits. Bigints are always normalized: if x is a
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
300 Bigint then x->wds >= 1, and either x->wds == 1 or x[wds-1] is nonzero.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
301
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
302 The Bigint fields are as follows:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
303
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
304 - next is a header used by Balloc and Bfree to keep track of lists
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
305 of freed Bigints; it's also used for the linked list of
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
306 powers of 5 of the form 5**2**i used by pow5mult.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
307 - k indicates which pool this Bigint was allocated from
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
308 - maxwds is the maximum number of words space was allocated for
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
309 (usually maxwds == 2**k)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
310 - sign is 1 for negative Bigints, 0 for positive. The sign is unused
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
311 (ignored on inputs, set to 0 on outputs) in almost all operations
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
312 involving Bigints: a notable exception is the diff function, which
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
313 ignores signs on inputs but sets the sign of the output correctly.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
314 - wds is the actual number of significant words
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
315 - x contains the vector of words (digits) for this Bigint, from least
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
316 significant (x[0]) to most significant (x[wds-1]).
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
317 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
318
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
319 struct
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
320 Bigint {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
321 struct Bigint *next;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
322 int k, maxwds, sign, wds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
323 ULong x[1];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
324 };
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
325
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
326 typedef struct Bigint Bigint;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
327
58401
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
328 #ifndef Py_USING_MEMORY_DEBUGGER
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
329
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
330 /* Memory management: memory is allocated from, and returned to, Kmax+1 pools
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
331 of memory, where pool k (0 <= k <= Kmax) is for Bigints b with b->maxwds ==
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
332 1 << k. These pools are maintained as linked lists, with freelist[k]
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
333 pointing to the head of the list for pool k.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
334
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
335 On allocation, if there's no free slot in the appropriate pool, MALLOC is
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
336 called to get more memory. This memory is not returned to the system until
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
337 Python quits. There's also a private memory pool that's allocated from
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
338 in preference to using MALLOC.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
339
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
340 For Bigints with more than (1 << Kmax) digits (which implies at least 1233
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
341 decimal digits), memory is directly allocated using MALLOC, and freed using
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
342 FREE.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
343
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
344 XXX: it would be easy to bypass this memory-management system and
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
345 translate each call to Balloc into a call to PyMem_Malloc, and each
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
346 Bfree to PyMem_Free. Investigate whether this has any significant
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
347 performance on impact. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
348
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
349 static Bigint *freelist[Kmax+1];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
350
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
351 /* Allocate space for a Bigint with up to 1<<k digits */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
352
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
353 static Bigint *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
354 Balloc(int k)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
355 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
356 int x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
357 Bigint *rv;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
358 unsigned int len;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
359
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
360 if (k <= Kmax && (rv = freelist[k]))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
361 freelist[k] = rv->next;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
362 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
363 x = 1 << k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
364 len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
365 /sizeof(double);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
366 if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
367 rv = (Bigint*)pmem_next;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
368 pmem_next += len;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
369 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
370 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
371 rv = (Bigint*)MALLOC(len*sizeof(double));
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
372 if (rv == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
373 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
374 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
375 rv->k = k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
376 rv->maxwds = x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
377 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
378 rv->sign = rv->wds = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
379 return rv;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
380 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
381
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
382 /* Free a Bigint allocated with Balloc */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
383
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
384 static void
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
385 Bfree(Bigint *v)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
386 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
387 if (v) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
388 if (v->k > Kmax)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
389 FREE((void*)v);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
390 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
391 v->next = freelist[v->k];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
392 freelist[v->k] = v;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
393 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
394 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
395 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
396
58401
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
397 #else
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
398
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
399 /* Alternative versions of Balloc and Bfree that use PyMem_Malloc and
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
400 PyMem_Free directly in place of the custom memory allocation scheme above.
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
401 These are provided for the benefit of memory debugging tools like
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
402 Valgrind. */
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
403
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
404 /* Allocate space for a Bigint with up to 1<<k digits */
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
405
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
406 static Bigint *
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
407 Balloc(int k)
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
408 {
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
409 int x;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
410 Bigint *rv;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
411 unsigned int len;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
412
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
413 x = 1 << k;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
414 len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
415 /sizeof(double);
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
416
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
417 rv = (Bigint*)MALLOC(len*sizeof(double));
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
418 if (rv == NULL)
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
419 return NULL;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
420
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
421 rv->k = k;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
422 rv->maxwds = x;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
423 rv->sign = rv->wds = 0;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
424 return rv;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
425 }
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
426
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
427 /* Free a Bigint allocated with Balloc */
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
428
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
429 static void
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
430 Bfree(Bigint *v)
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
431 {
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
432 if (v) {
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
433 FREE((void*)v);
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
434 }
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
435 }
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
436
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
437 #endif /* Py_USING_MEMORY_DEBUGGER */
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
438
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
439 #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
440 y->wds*sizeof(Long) + 2*sizeof(int))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
441
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
442 /* Multiply a Bigint b by m and add a. Either modifies b in place and returns
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
443 a pointer to the modified b, or Bfrees b and returns a pointer to a copy.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
444 On failure, return NULL. In this case, b will have been already freed. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
445
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
446 static Bigint *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
447 multadd(Bigint *b, int m, int a) /* multiply by m and add a */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
448 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
449 int i, wds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
450 #ifdef ULLong
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
451 ULong *x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
452 ULLong carry, y;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
453 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
454 ULong carry, *x, y;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
455 ULong xi, z;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
456 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
457 Bigint *b1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
458
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
459 wds = b->wds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
460 x = b->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
461 i = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
462 carry = a;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
463 do {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
464 #ifdef ULLong
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
465 y = *x * (ULLong)m + carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
466 carry = y >> 32;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
467 *x++ = (ULong)(y & FFFFFFFF);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
468 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
469 xi = *x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
470 y = (xi & 0xffff) * m + carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
471 z = (xi >> 16) * m + (y >> 16);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
472 carry = z >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
473 *x++ = (z << 16) + (y & 0xffff);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
474 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
475 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
476 while(++i < wds);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
477 if (carry) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
478 if (wds >= b->maxwds) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
479 b1 = Balloc(b->k+1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
480 if (b1 == NULL){
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
481 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
482 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
483 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
484 Bcopy(b1, b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
485 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
486 b = b1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
487 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
488 b->x[wds++] = (ULong)carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
489 b->wds = wds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
490 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
491 return b;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
492 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
493
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
494 /* convert a string s containing nd decimal digits (possibly containing a
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
495 decimal separator at position nd0, which is ignored) to a Bigint. This
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
496 function carries on where the parsing code in _Py_dg_strtod leaves off: on
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
497 entry, y9 contains the result of converting the first 9 digits. Returns
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
498 NULL on failure. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
499
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
500 static Bigint *
58310
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
501 s2b(const char *s, int nd0, int nd, ULong y9)
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
502 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
503 Bigint *b;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
504 int i, k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
505 Long x, y;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
506
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
507 x = (nd + 8) / 9;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
508 for(k = 0, y = 1; x > y; y <<= 1, k++) ;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
509 b = Balloc(k);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
510 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
511 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
512 b->x[0] = y9;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
513 b->wds = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
514
58310
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
515 if (nd <= 9)
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
516 return b;
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
517
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
518 s += 9;
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
519 for (i = 9; i < nd0; i++) {
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
520 b = multadd(b, 10, *s++ - '0');
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
521 if (b == NULL)
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
522 return NULL;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
523 }
58310
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
524 s++;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
525 for(; i < nd; i++) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
526 b = multadd(b, 10, *s++ - '0');
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
527 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
528 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
529 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
530 return b;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
531 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
532
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
533 /* count leading 0 bits in the 32-bit integer x. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
534
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
535 static int
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
536 hi0bits(ULong x)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
537 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
538 int k = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
539
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
540 if (!(x & 0xffff0000)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
541 k = 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
542 x <<= 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
543 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
544 if (!(x & 0xff000000)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
545 k += 8;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
546 x <<= 8;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
547 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
548 if (!(x & 0xf0000000)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
549 k += 4;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
550 x <<= 4;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
551 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
552 if (!(x & 0xc0000000)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
553 k += 2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
554 x <<= 2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
555 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
556 if (!(x & 0x80000000)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
557 k++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
558 if (!(x & 0x40000000))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
559 return 32;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
560 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
561 return k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
562 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
563
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
564 /* count trailing 0 bits in the 32-bit integer y, and shift y right by that
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
565 number of bits. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
566
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
567 static int
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
568 lo0bits(ULong *y)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
569 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
570 int k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
571 ULong x = *y;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
572
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
573 if (x & 7) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
574 if (x & 1)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
575 return 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
576 if (x & 2) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
577 *y = x >> 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
578 return 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
579 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
580 *y = x >> 2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
581 return 2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
582 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
583 k = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
584 if (!(x & 0xffff)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
585 k = 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
586 x >>= 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
587 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
588 if (!(x & 0xff)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
589 k += 8;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
590 x >>= 8;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
591 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
592 if (!(x & 0xf)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
593 k += 4;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
594 x >>= 4;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
595 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
596 if (!(x & 0x3)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
597 k += 2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
598 x >>= 2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
599 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
600 if (!(x & 1)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
601 k++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
602 x >>= 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
603 if (!x)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
604 return 32;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
605 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
606 *y = x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
607 return k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
608 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
609
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
610 /* convert a small nonnegative integer to a Bigint */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
611
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
612 static Bigint *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
613 i2b(int i)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
614 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
615 Bigint *b;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
616
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
617 b = Balloc(1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
618 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
619 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
620 b->x[0] = i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
621 b->wds = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
622 return b;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
623 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
624
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
625 /* multiply two Bigints. Returns a new Bigint, or NULL on failure. Ignores
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
626 the signs of a and b. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
627
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
628 static Bigint *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
629 mult(Bigint *a, Bigint *b)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
630 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
631 Bigint *c;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
632 int k, wa, wb, wc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
633 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
634 ULong y;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
635 #ifdef ULLong
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
636 ULLong carry, z;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
637 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
638 ULong carry, z;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
639 ULong z2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
640 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
641
58458
d77c947ff7db Issue #7743: Add checks for zero inputs to the lshift and mult functions;
Mark Dickinson <dickinsm@gmail.com>
parents: 58444
diff changeset
642 if ((!a->x[0] && a->wds == 1) || (!b->x[0] && b->wds == 1)) {
d77c947ff7db Issue #7743: Add checks for zero inputs to the lshift and mult functions;
Mark Dickinson <dickinsm@gmail.com>
parents: 58444
diff changeset
643 c = Balloc(0);
d77c947ff7db Issue #7743: Add checks for zero inputs to the lshift and mult functions;
Mark Dickinson <dickinsm@gmail.com>
parents: 58444
diff changeset
644 if (c == NULL)
d77c947ff7db Issue #7743: Add checks for zero inputs to the lshift and mult functions;
Mark Dickinson <dickinsm@gmail.com>
parents: 58444
diff changeset
645 return NULL;
d77c947ff7db Issue #7743: Add checks for zero inputs to the lshift and mult functions;
Mark Dickinson <dickinsm@gmail.com>
parents: 58444
diff changeset
646 c->wds = 1;
d77c947ff7db Issue #7743: Add checks for zero inputs to the lshift and mult functions;
Mark Dickinson <dickinsm@gmail.com>
parents: 58444
diff changeset
647 c->x[0] = 0;
d77c947ff7db Issue #7743: Add checks for zero inputs to the lshift and mult functions;
Mark Dickinson <dickinsm@gmail.com>
parents: 58444
diff changeset
648 return c;
d77c947ff7db Issue #7743: Add checks for zero inputs to the lshift and mult functions;
Mark Dickinson <dickinsm@gmail.com>
parents: 58444
diff changeset
649 }
d77c947ff7db Issue #7743: Add checks for zero inputs to the lshift and mult functions;
Mark Dickinson <dickinsm@gmail.com>
parents: 58444
diff changeset
650
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
651 if (a->wds < b->wds) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
652 c = a;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
653 a = b;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
654 b = c;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
655 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
656 k = a->k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
657 wa = a->wds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
658 wb = b->wds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
659 wc = wa + wb;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
660 if (wc > a->maxwds)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
661 k++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
662 c = Balloc(k);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
663 if (c == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
664 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
665 for(x = c->x, xa = x + wc; x < xa; x++)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
666 *x = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
667 xa = a->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
668 xae = xa + wa;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
669 xb = b->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
670 xbe = xb + wb;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
671 xc0 = c->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
672 #ifdef ULLong
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
673 for(; xb < xbe; xc0++) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
674 if ((y = *xb++)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
675 x = xa;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
676 xc = xc0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
677 carry = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
678 do {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
679 z = *x++ * (ULLong)y + *xc + carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
680 carry = z >> 32;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
681 *xc++ = (ULong)(z & FFFFFFFF);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
682 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
683 while(x < xae);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
684 *xc = (ULong)carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
685 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
686 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
687 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
688 for(; xb < xbe; xb++, xc0++) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
689 if (y = *xb & 0xffff) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
690 x = xa;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
691 xc = xc0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
692 carry = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
693 do {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
694 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
695 carry = z >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
696 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
697 carry = z2 >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
698 Storeinc(xc, z2, z);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
699 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
700 while(x < xae);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
701 *xc = carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
702 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
703 if (y = *xb >> 16) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
704 x = xa;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
705 xc = xc0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
706 carry = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
707 z2 = *xc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
708 do {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
709 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
710 carry = z >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
711 Storeinc(xc, z, z2);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
712 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
713 carry = z2 >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
714 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
715 while(x < xae);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
716 *xc = z2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
717 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
718 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
719 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
720 for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
721 c->wds = wc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
722 return c;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
723 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
724
58401
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
725 #ifndef Py_USING_MEMORY_DEBUGGER
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
726
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
727 /* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
728
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
729 static Bigint *p5s;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
730
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
731 /* multiply the Bigint b by 5**k. Returns a pointer to the result, or NULL on
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
732 failure; if the returned pointer is distinct from b then the original
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
733 Bigint b will have been Bfree'd. Ignores the sign of b. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
734
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
735 static Bigint *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
736 pow5mult(Bigint *b, int k)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
737 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
738 Bigint *b1, *p5, *p51;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
739 int i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
740 static int p05[3] = { 5, 25, 125 };
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
741
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
742 if ((i = k & 3)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
743 b = multadd(b, p05[i-1], 0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
744 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
745 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
746 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
747
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
748 if (!(k >>= 2))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
749 return b;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
750 p5 = p5s;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
751 if (!p5) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
752 /* first time */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
753 p5 = i2b(625);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
754 if (p5 == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
755 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
756 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
757 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
758 p5s = p5;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
759 p5->next = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
760 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
761 for(;;) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
762 if (k & 1) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
763 b1 = mult(b, p5);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
764 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
765 b = b1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
766 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
767 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
768 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
769 if (!(k >>= 1))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
770 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
771 p51 = p5->next;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
772 if (!p51) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
773 p51 = mult(p5,p5);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
774 if (p51 == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
775 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
776 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
777 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
778 p51->next = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
779 p5->next = p51;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
780 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
781 p5 = p51;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
782 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
783 return b;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
784 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
785
58401
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
786 #else
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
787
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
788 /* Version of pow5mult that doesn't cache powers of 5. Provided for
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
789 the benefit of memory debugging tools like Valgrind. */
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
790
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
791 static Bigint *
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
792 pow5mult(Bigint *b, int k)
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
793 {
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
794 Bigint *b1, *p5, *p51;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
795 int i;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
796 static int p05[3] = { 5, 25, 125 };
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
797
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
798 if ((i = k & 3)) {
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
799 b = multadd(b, p05[i-1], 0);
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
800 if (b == NULL)
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
801 return NULL;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
802 }
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
803
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
804 if (!(k >>= 2))
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
805 return b;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
806 p5 = i2b(625);
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
807 if (p5 == NULL) {
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
808 Bfree(b);
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
809 return NULL;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
810 }
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
811
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
812 for(;;) {
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
813 if (k & 1) {
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
814 b1 = mult(b, p5);
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
815 Bfree(b);
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
816 b = b1;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
817 if (b == NULL) {
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
818 Bfree(p5);
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
819 return NULL;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
820 }
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
821 }
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
822 if (!(k >>= 1))
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
823 break;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
824 p51 = mult(p5, p5);
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
825 Bfree(p5);
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
826 p5 = p51;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
827 if (p5 == NULL) {
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
828 Bfree(b);
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
829 return NULL;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
830 }
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
831 }
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
832 Bfree(p5);
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
833 return b;
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
834 }
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
835
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
836 #endif /* Py_USING_MEMORY_DEBUGGER */
5c9c53a721a5 Issue #7632: When Py_USING_MEMORY_DEBUGGER is defined, disable the
Mark Dickinson <dickinsm@gmail.com>
parents: 58390
diff changeset
837
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
838 /* shift a Bigint b left by k bits. Return a pointer to the shifted result,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
839 or NULL on failure. If the returned pointer is distinct from b then the
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
840 original b will have been Bfree'd. Ignores the sign of b. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
841
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
842 static Bigint *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
843 lshift(Bigint *b, int k)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
844 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
845 int i, k1, n, n1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
846 Bigint *b1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
847 ULong *x, *x1, *xe, z;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
848
58458
d77c947ff7db Issue #7743: Add checks for zero inputs to the lshift and mult functions;
Mark Dickinson <dickinsm@gmail.com>
parents: 58444
diff changeset
849 if (!k || (!b->x[0] && b->wds == 1))
d77c947ff7db Issue #7743: Add checks for zero inputs to the lshift and mult functions;
Mark Dickinson <dickinsm@gmail.com>
parents: 58444
diff changeset
850 return b;
d77c947ff7db Issue #7743: Add checks for zero inputs to the lshift and mult functions;
Mark Dickinson <dickinsm@gmail.com>
parents: 58444
diff changeset
851
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
852 n = k >> 5;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
853 k1 = b->k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
854 n1 = n + b->wds + 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
855 for(i = b->maxwds; n1 > i; i <<= 1)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
856 k1++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
857 b1 = Balloc(k1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
858 if (b1 == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
859 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
860 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
861 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
862 x1 = b1->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
863 for(i = 0; i < n; i++)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
864 *x1++ = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
865 x = b->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
866 xe = x + b->wds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
867 if (k &= 0x1f) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
868 k1 = 32 - k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
869 z = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
870 do {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
871 *x1++ = *x << k | z;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
872 z = *x++ >> k1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
873 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
874 while(x < xe);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
875 if ((*x1 = z))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
876 ++n1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
877 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
878 else do
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
879 *x1++ = *x++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
880 while(x < xe);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
881 b1->wds = n1 - 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
882 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
883 return b1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
884 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
885
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
886 /* Do a three-way compare of a and b, returning -1 if a < b, 0 if a == b and
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
887 1 if a > b. Ignores signs of a and b. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
888
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
889 static int
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
890 cmp(Bigint *a, Bigint *b)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
891 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
892 ULong *xa, *xa0, *xb, *xb0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
893 int i, j;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
894
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
895 i = a->wds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
896 j = b->wds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
897 #ifdef DEBUG
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
898 if (i > 1 && !a->x[i-1])
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
899 Bug("cmp called with a->x[a->wds-1] == 0");
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
900 if (j > 1 && !b->x[j-1])
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
901 Bug("cmp called with b->x[b->wds-1] == 0");
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
902 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
903 if (i -= j)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
904 return i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
905 xa0 = a->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
906 xa = xa0 + j;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
907 xb0 = b->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
908 xb = xb0 + j;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
909 for(;;) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
910 if (*--xa != *--xb)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
911 return *xa < *xb ? -1 : 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
912 if (xa <= xa0)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
913 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
914 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
915 return 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
916 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
917
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
918 /* Take the difference of Bigints a and b, returning a new Bigint. Returns
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
919 NULL on failure. The signs of a and b are ignored, but the sign of the
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
920 result is set appropriately. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
921
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
922 static Bigint *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
923 diff(Bigint *a, Bigint *b)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
924 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
925 Bigint *c;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
926 int i, wa, wb;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
927 ULong *xa, *xae, *xb, *xbe, *xc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
928 #ifdef ULLong
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
929 ULLong borrow, y;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
930 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
931 ULong borrow, y;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
932 ULong z;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
933 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
934
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
935 i = cmp(a,b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
936 if (!i) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
937 c = Balloc(0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
938 if (c == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
939 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
940 c->wds = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
941 c->x[0] = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
942 return c;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
943 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
944 if (i < 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
945 c = a;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
946 a = b;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
947 b = c;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
948 i = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
949 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
950 else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
951 i = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
952 c = Balloc(a->k);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
953 if (c == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
954 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
955 c->sign = i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
956 wa = a->wds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
957 xa = a->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
958 xae = xa + wa;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
959 wb = b->wds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
960 xb = b->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
961 xbe = xb + wb;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
962 xc = c->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
963 borrow = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
964 #ifdef ULLong
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
965 do {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
966 y = (ULLong)*xa++ - *xb++ - borrow;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
967 borrow = y >> 32 & (ULong)1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
968 *xc++ = (ULong)(y & FFFFFFFF);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
969 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
970 while(xb < xbe);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
971 while(xa < xae) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
972 y = *xa++ - borrow;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
973 borrow = y >> 32 & (ULong)1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
974 *xc++ = (ULong)(y & FFFFFFFF);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
975 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
976 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
977 do {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
978 y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
979 borrow = (y & 0x10000) >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
980 z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
981 borrow = (z & 0x10000) >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
982 Storeinc(xc, z, y);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
983 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
984 while(xb < xbe);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
985 while(xa < xae) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
986 y = (*xa & 0xffff) - borrow;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
987 borrow = (y & 0x10000) >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
988 z = (*xa++ >> 16) - borrow;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
989 borrow = (z & 0x10000) >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
990 Storeinc(xc, z, y);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
991 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
992 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
993 while(!*--xc)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
994 wa--;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
995 c->wds = wa;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
996 return c;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
997 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
998
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
999 /* Given a positive normal double x, return the difference between x and the
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1000 next double up. Doesn't give correct results for subnormals. */
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1001
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1002 static double
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1003 ulp(U *x)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1004 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1005 Long L;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1006 U u;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1007
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1008 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1009 word0(&u) = L;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1010 word1(&u) = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1011 return dval(&u);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1012 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1013
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1014 /* Convert a Bigint to a double plus an exponent */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1015
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1016 static double
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1017 b2d(Bigint *a, int *e)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1018 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1019 ULong *xa, *xa0, w, y, z;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1020 int k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1021 U d;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1022
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1023 xa0 = a->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1024 xa = xa0 + a->wds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1025 y = *--xa;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1026 #ifdef DEBUG
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1027 if (!y) Bug("zero y in b2d");
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1028 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1029 k = hi0bits(y);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1030 *e = 32 - k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1031 if (k < Ebits) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1032 word0(&d) = Exp_1 | y >> (Ebits - k);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1033 w = xa > xa0 ? *--xa : 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1034 word1(&d) = y << ((32-Ebits) + k) | w >> (Ebits - k);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1035 goto ret_d;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1036 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1037 z = xa > xa0 ? *--xa : 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1038 if (k -= Ebits) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1039 word0(&d) = Exp_1 | y << k | z >> (32 - k);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1040 y = xa > xa0 ? *--xa : 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1041 word1(&d) = z << k | y >> (32 - k);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1042 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1043 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1044 word0(&d) = Exp_1 | y;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1045 word1(&d) = z;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1046 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1047 ret_d:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1048 return dval(&d);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1049 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1050
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1051 /* Convert a scaled double to a Bigint plus an exponent. Similar to d2b,
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1052 except that it accepts the scale parameter used in _Py_dg_strtod (which
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1053 should be either 0 or 2*P), and the normalization for the return value is
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1054 different (see below). On input, d should be finite and nonnegative, and d
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1055 / 2**scale should be exactly representable as an IEEE 754 double.
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1056
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1057 Returns a Bigint b and an integer e such that
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1058
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1059 dval(d) / 2**scale = b * 2**e.
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1060
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1061 Unlike d2b, b is not necessarily odd: b and e are normalized so
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1062 that either 2**(P-1) <= b < 2**P and e >= Etiny, or b < 2**P
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1063 and e == Etiny. This applies equally to an input of 0.0: in that
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1064 case the return values are b = 0 and e = Etiny.
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1065
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1066 The above normalization ensures that for all possible inputs d,
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1067 2**e gives ulp(d/2**scale).
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1068
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1069 Returns NULL on failure.
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1070 */
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1071
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1072 static Bigint *
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1073 sd2b(U *d, int scale, int *e)
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1074 {
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1075 Bigint *b;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1076
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1077 b = Balloc(1);
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1078 if (b == NULL)
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1079 return NULL;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1080
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1081 /* First construct b and e assuming that scale == 0. */
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1082 b->wds = 2;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1083 b->x[0] = word1(d);
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1084 b->x[1] = word0(d) & Frac_mask;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1085 *e = Etiny - 1 + (int)((word0(d) & Exp_mask) >> Exp_shift);
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1086 if (*e < Etiny)
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1087 *e = Etiny;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1088 else
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1089 b->x[1] |= Exp_msk1;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1090
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1091 /* Now adjust for scale, provided that b != 0. */
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1092 if (scale && (b->x[0] || b->x[1])) {
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1093 *e -= scale;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1094 if (*e < Etiny) {
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1095 scale = Etiny - *e;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1096 *e = Etiny;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1097 /* We can't shift more than P-1 bits without shifting out a 1. */
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1098 assert(0 < scale && scale <= P - 1);
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1099 if (scale >= 32) {
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1100 /* The bits shifted out should all be zero. */
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1101 assert(b->x[0] == 0);
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1102 b->x[0] = b->x[1];
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1103 b->x[1] = 0;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1104 scale -= 32;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1105 }
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1106 if (scale) {
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1107 /* The bits shifted out should all be zero. */
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1108 assert(b->x[0] << (32 - scale) == 0);
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1109 b->x[0] = (b->x[0] >> scale) | (b->x[1] << (32 - scale));
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1110 b->x[1] >>= scale;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1111 }
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1112 }
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1113 }
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1114 /* Ensure b is normalized. */
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1115 if (!b->x[1])
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1116 b->wds = 1;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1117
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1118 return b;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1119 }
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1120
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1121 /* Convert a double to a Bigint plus an exponent. Return NULL on failure.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1122
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1123 Given a finite nonzero double d, return an odd Bigint b and exponent *e
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1124 such that fabs(d) = b * 2**e. On return, *bbits gives the number of
58151
8ca377853321 Fix typo in comment.
Mark Dickinson <dickinsm@gmail.com>
parents: 56709
diff changeset
1125 significant bits of b; that is, 2**(*bbits-1) <= b < 2**(*bbits).
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1126
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1127 If d is zero, then b == 0, *e == -1010, *bbits = 0.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1128 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1129
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1130 static Bigint *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1131 d2b(U *d, int *e, int *bits)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1132 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1133 Bigint *b;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1134 int de, k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1135 ULong *x, y, z;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1136 int i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1137
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1138 b = Balloc(1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1139 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1140 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1141 x = b->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1142
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1143 z = word0(d) & Frac_mask;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1144 word0(d) &= 0x7fffffff; /* clear sign bit, which we ignore */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1145 if ((de = (int)(word0(d) >> Exp_shift)))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1146 z |= Exp_msk1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1147 if ((y = word1(d))) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1148 if ((k = lo0bits(&y))) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1149 x[0] = y | z << (32 - k);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1150 z >>= k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1151 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1152 else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1153 x[0] = y;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1154 i =
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1155 b->wds = (x[1] = z) ? 2 : 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1156 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1157 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1158 k = lo0bits(&z);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1159 x[0] = z;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1160 i =
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1161 b->wds = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1162 k += 32;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1163 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1164 if (de) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1165 *e = de - Bias - (P-1) + k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1166 *bits = P - k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1167 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1168 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1169 *e = de - Bias - (P-1) + 1 + k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1170 *bits = 32*i - hi0bits(x[i-1]);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1171 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1172 return b;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1173 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1174
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1175 /* Compute the ratio of two Bigints, as a double. The result may have an
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1176 error of up to 2.5 ulps. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1177
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1178 static double
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1179 ratio(Bigint *a, Bigint *b)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1180 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1181 U da, db;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1182 int k, ka, kb;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1183
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1184 dval(&da) = b2d(a, &ka);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1185 dval(&db) = b2d(b, &kb);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1186 k = ka - kb + 32*(a->wds - b->wds);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1187 if (k > 0)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1188 word0(&da) += k*Exp_msk1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1189 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1190 k = -k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1191 word0(&db) += k*Exp_msk1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1192 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1193 return dval(&da) / dval(&db);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1194 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1195
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1196 static const double
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1197 tens[] = {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1198 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1199 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1200 1e20, 1e21, 1e22
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1201 };
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1202
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1203 static const double
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1204 bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1205 static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1206 9007199254740992.*9007199254740992.e-256
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1207 /* = 2^106 * 1e-256 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1208 };
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1209 /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1210 /* flag unnecessarily. It leads to a song and dance at the end of strtod. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1211 #define Scale_Bit 0x10
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1212 #define n_bigtens 5
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1213
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1214 #define ULbits 32
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1215 #define kshift 5
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1216 #define kmask 31
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1217
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1218
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1219 static int
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1220 dshift(Bigint *b, int p2)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1221 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1222 int rv = hi0bits(b->x[b->wds-1]) - 4;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1223 if (p2 > 0)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1224 rv -= p2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1225 return rv & kmask;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1226 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1227
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1228 /* special case of Bigint division. The quotient is always in the range 0 <=
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1229 quotient < 10, and on entry the divisor S is normalized so that its top 4
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1230 bits (28--31) are zero and bit 27 is set. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1231
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1232 static int
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1233 quorem(Bigint *b, Bigint *S)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1234 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1235 int n;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1236 ULong *bx, *bxe, q, *sx, *sxe;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1237 #ifdef ULLong
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1238 ULLong borrow, carry, y, ys;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1239 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1240 ULong borrow, carry, y, ys;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1241 ULong si, z, zs;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1242 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1243
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1244 n = S->wds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1245 #ifdef DEBUG
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1246 /*debug*/ if (b->wds > n)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1247 /*debug*/ Bug("oversize b in quorem");
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1248 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1249 if (b->wds < n)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1250 return 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1251 sx = S->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1252 sxe = sx + --n;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1253 bx = b->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1254 bxe = bx + n;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1255 q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1256 #ifdef DEBUG
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1257 /*debug*/ if (q > 9)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1258 /*debug*/ Bug("oversized quotient in quorem");
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1259 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1260 if (q) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1261 borrow = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1262 carry = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1263 do {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1264 #ifdef ULLong
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1265 ys = *sx++ * (ULLong)q + carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1266 carry = ys >> 32;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1267 y = *bx - (ys & FFFFFFFF) - borrow;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1268 borrow = y >> 32 & (ULong)1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1269 *bx++ = (ULong)(y & FFFFFFFF);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1270 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1271 si = *sx++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1272 ys = (si & 0xffff) * q + carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1273 zs = (si >> 16) * q + (ys >> 16);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1274 carry = zs >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1275 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1276 borrow = (y & 0x10000) >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1277 z = (*bx >> 16) - (zs & 0xffff) - borrow;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1278 borrow = (z & 0x10000) >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1279 Storeinc(bx, z, y);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1280 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1281 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1282 while(sx <= sxe);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1283 if (!*bxe) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1284 bx = b->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1285 while(--bxe > bx && !*bxe)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1286 --n;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1287 b->wds = n;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1288 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1289 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1290 if (cmp(b, S) >= 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1291 q++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1292 borrow = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1293 carry = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1294 bx = b->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1295 sx = S->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1296 do {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1297 #ifdef ULLong
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1298 ys = *sx++ + carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1299 carry = ys >> 32;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1300 y = *bx - (ys & FFFFFFFF) - borrow;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1301 borrow = y >> 32 & (ULong)1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1302 *bx++ = (ULong)(y & FFFFFFFF);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1303 #else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1304 si = *sx++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1305 ys = (si & 0xffff) + carry;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1306 zs = (si >> 16) + (ys >> 16);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1307 carry = zs >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1308 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1309 borrow = (y & 0x10000) >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1310 z = (*bx >> 16) - (zs & 0xffff) - borrow;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1311 borrow = (z & 0x10000) >> 16;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1312 Storeinc(bx, z, y);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1313 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1314 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1315 while(sx <= sxe);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1316 bx = b->x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1317 bxe = bx + n;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1318 if (!*bxe) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1319 while(--bxe > bx && !*bxe)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1320 --n;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1321 b->wds = n;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1322 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1323 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1324 return q;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1325 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1326
58305
c5a0a5d6acb0 Clarify that sulp expects a nonnegative input, but that +0.0 is fine.
Mark Dickinson <dickinsm@gmail.com>
parents: 58304
diff changeset
1327 /* sulp(x) is a version of ulp(x) that takes bc.scale into account.
58278
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1328
58305
c5a0a5d6acb0 Clarify that sulp expects a nonnegative input, but that +0.0 is fine.
Mark Dickinson <dickinsm@gmail.com>
parents: 58304
diff changeset
1329 Assuming that x is finite and nonnegative (positive zero is fine
c5a0a5d6acb0 Clarify that sulp expects a nonnegative input, but that +0.0 is fine.
Mark Dickinson <dickinsm@gmail.com>
parents: 58304
diff changeset
1330 here) and x / 2^bc.scale is exactly representable as a double,
c5a0a5d6acb0 Clarify that sulp expects a nonnegative input, but that +0.0 is fine.
Mark Dickinson <dickinsm@gmail.com>
parents: 58304
diff changeset
1331 sulp(x) is equivalent to 2^bc.scale * ulp(x / 2^bc.scale). */
58278
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1332
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1333 static double
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1334 sulp(U *x, BCinfo *bc)
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1335 {
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1336 U u;
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1337
58309
c7f33d5216f9 Fix buggy comparison: LHS of comparison was being treated as unsigned.
Mark Dickinson <dickinsm@gmail.com>
parents: 58308
diff changeset
1338 if (bc->scale && 2*P + 1 > (int)((word0(x) & Exp_mask) >> Exp_shift)) {
58278
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1339 /* rv/2^bc->scale is subnormal */
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1340 word0(&u) = (P+2)*Exp_msk1;
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1341 word1(&u) = 0;
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1342 return u.d;
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1343 }
58305
c5a0a5d6acb0 Clarify that sulp expects a nonnegative input, but that +0.0 is fine.
Mark Dickinson <dickinsm@gmail.com>
parents: 58304
diff changeset
1344 else {
c5a0a5d6acb0 Clarify that sulp expects a nonnegative input, but that +0.0 is fine.
Mark Dickinson <dickinsm@gmail.com>
parents: 58304
diff changeset
1345 assert(word0(x) || word1(x)); /* x != 0.0 */
58278
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1346 return ulp(x);
58305
c5a0a5d6acb0 Clarify that sulp expects a nonnegative input, but that +0.0 is fine.
Mark Dickinson <dickinsm@gmail.com>
parents: 58304
diff changeset
1347 }
58278
b4f301cea115 Issue #7632: Fix a bug in dtoa.c that could lead to incorrectly-rounded results.
Mark Dickinson <dickinsm@gmail.com>
parents: 58277
diff changeset
1348 }
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1349
58304
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1350 /* The bigcomp function handles some hard cases for strtod, for inputs
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1351 with more than STRTOD_DIGLIM digits. It's called once an initial
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1352 estimate for the double corresponding to the input string has
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1353 already been obtained by the code in _Py_dg_strtod.
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1354
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1355 The bigcomp function is only called after _Py_dg_strtod has found a
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1356 double value rv such that either rv or rv + 1ulp represents the
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1357 correctly rounded value corresponding to the original string. It
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1358 determines which of these two values is the correct one by
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1359 computing the decimal digits of rv + 0.5ulp and comparing them with
58308
0f974bb238ed Simplify and annotate the bigcomp function, removing unused special cases.
Mark Dickinson <dickinsm@gmail.com>
parents: 58305
diff changeset
1360 the corresponding digits of s0.
58304
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1361
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1362 In the following, write dv for the absolute value of the number represented
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1363 by the input string.
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1364
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1365 Inputs:
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1366
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1367 s0 points to the first significant digit of the input string.
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1368
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1369 rv is a (possibly scaled) estimate for the closest double value to the
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1370 value represented by the original input to _Py_dg_strtod. If
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1371 bc->scale is nonzero, then rv/2^(bc->scale) is the approximation to
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1372 the input value.
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1373
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1374 bc is a struct containing information gathered during the parsing and
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1375 estimation steps of _Py_dg_strtod. Description of fields follows:
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1376
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1377 bc->e0 gives the exponent of the input value, such that dv = (integer
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1378 given by the bd->nd digits of s0) * 10**e0
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1379
58310
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
1380 bc->nd gives the total number of significant digits of s0. It will
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
1381 be at least 1.
58304
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1382
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1383 bc->nd0 gives the number of significant digits of s0 before the
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1384 decimal separator. If there's no decimal separator, bc->nd0 ==
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1385 bc->nd.
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1386
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1387 bc->scale is the value used to scale rv to avoid doing arithmetic with
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1388 subnormal values. It's either 0 or 2*P (=106).
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1389
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1390 Outputs:
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1391
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1392 On successful exit, rv/2^(bc->scale) is the closest double to dv.
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1393
57102283ab5e Add comments explaining the role of the bigcomp function in dtoa.c.
Mark Dickinson <dickinsm@gmail.com>
parents: 58278
diff changeset
1394 Returns 0 on success, -1 on failure (e.g., due to a failed malloc call). */
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1395
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1396 static int
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1397 bigcomp(U *rv, const char *s0, BCinfo *bc)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1398 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1399 Bigint *b, *d;
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1400 int b2, d2, dd, i, nd, nd0, odd, p2, p5;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1401
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1402 nd = bc->nd;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1403 nd0 = bc->nd0;
58277
2a9f66df4dc4 Issue #7632: Fix a problem with _Py_dg_strtod that could lead to
Mark Dickinson <dickinsm@gmail.com>
parents: 58249
diff changeset
1404 p5 = nd + bc->e0;
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1405 b = sd2b(rv, bc->scale, &p2);
58308
0f974bb238ed Simplify and annotate the bigcomp function, removing unused special cases.
Mark Dickinson <dickinsm@gmail.com>
parents: 58305
diff changeset
1406 if (b == NULL)
0f974bb238ed Simplify and annotate the bigcomp function, removing unused special cases.
Mark Dickinson <dickinsm@gmail.com>
parents: 58305
diff changeset
1407 return -1;
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1408
58317
76fb7dbd7388 Issue 7632: fix a dtoa.c bug (bug 6) causing incorrect rounding. Tests to follow.
Mark Dickinson <dickinsm@gmail.com>
parents: 58316
diff changeset
1409 /* record whether the lsb of rv/2^(bc->scale) is odd: in the exact halfway
76fb7dbd7388 Issue 7632: fix a dtoa.c bug (bug 6) causing incorrect rounding. Tests to follow.
Mark Dickinson <dickinsm@gmail.com>
parents: 58316
diff changeset
1410 case, this is used for round to even. */
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1411 odd = b->x[0] & 1;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1412
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1413 /* left shift b by 1 bit and or a 1 into the least significant bit;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1414 this gives us b * 2**p2 = rv/2^(bc->scale) + 0.5 ulp. */
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1415 b = lshift(b, 1);
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1416 if (b == NULL)
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1417 return -1;
58308
0f974bb238ed Simplify and annotate the bigcomp function, removing unused special cases.
Mark Dickinson <dickinsm@gmail.com>
parents: 58305
diff changeset
1418 b->x[0] |= 1;
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1419 p2--;
58308
0f974bb238ed Simplify and annotate the bigcomp function, removing unused special cases.
Mark Dickinson <dickinsm@gmail.com>
parents: 58305
diff changeset
1420
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1421 p2 -= p5;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1422 d = i2b(1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1423 if (d == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1424 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1425 return -1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1426 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1427 /* Arrange for convenient computation of quotients:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1428 * shift left if necessary so divisor has 4 leading 0 bits.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1429 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1430 if (p5 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1431 d = pow5mult(d, p5);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1432 if (d == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1433 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1434 return -1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1435 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1436 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1437 else if (p5 < 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1438 b = pow5mult(b, -p5);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1439 if (b == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1440 Bfree(d);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1441 return -1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1442 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1443 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1444 if (p2 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1445 b2 = p2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1446 d2 = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1447 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1448 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1449 b2 = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1450 d2 = -p2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1451 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1452 i = dshift(d, d2);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1453 if ((b2 += i) > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1454 b = lshift(b, b2);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1455 if (b == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1456 Bfree(d);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1457 return -1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1458 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1459 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1460 if ((d2 += i) > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1461 d = lshift(d, d2);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1462 if (d == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1463 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1464 return -1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1465 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1466 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1467
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1468 /* Compare s0 with b/d: set dd to -1, 0, or 1 according as s0 < b/d, s0 ==
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1469 * b/d, or s0 > b/d. Here the digits of s0 are thought of as representing
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1470 * a number in the range [0.1, 1). */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1471 if (cmp(b, d) >= 0)
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1472 /* b/d >= 1 */
58277
2a9f66df4dc4 Issue #7632: Fix a problem with _Py_dg_strtod that could lead to
Mark Dickinson <dickinsm@gmail.com>
parents: 58249
diff changeset
1473 dd = -1;
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1474 else {
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1475 i = 0;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1476 for(;;) {
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1477 b = multadd(b, 10, 0);
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1478 if (b == NULL) {
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1479 Bfree(d);
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1480 return -1;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1481 }
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1482 dd = s0[i < nd0 ? i : i+1] - '0' - quorem(b, d);
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1483 i++;
58317
76fb7dbd7388 Issue 7632: fix a dtoa.c bug (bug 6) causing incorrect rounding. Tests to follow.
Mark Dickinson <dickinsm@gmail.com>
parents: 58316
diff changeset
1484
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1485 if (dd)
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1486 break;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1487 if (!b->x[0] && b->wds == 1) {
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1488 /* b/d == 0 */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1489 dd = i < nd;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1490 break;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1491 }
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1492 if (!(i < nd)) {
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1493 /* b/d != 0, but digits of s0 exhausted */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1494 dd = -1;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1495 break;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1496 }
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1497 }
58310
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
1498 }
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1499 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1500 Bfree(d);
58317
76fb7dbd7388 Issue 7632: fix a dtoa.c bug (bug 6) causing incorrect rounding. Tests to follow.
Mark Dickinson <dickinsm@gmail.com>
parents: 58316
diff changeset
1501 if (dd > 0 || (dd == 0 && odd))
58308
0f974bb238ed Simplify and annotate the bigcomp function, removing unused special cases.
Mark Dickinson <dickinsm@gmail.com>
parents: 58305
diff changeset
1502 dval(rv) += sulp(rv, bc);
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1503 return 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1504 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1505
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1506 double
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1507 _Py_dg_strtod(const char *s00, char **se)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1508 {
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1509 int bb2, bb5, bbe, bd2, bd5, bs2, c, dsign, e, e1, error;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1510 int esign, i, j, k, lz, nd, nd0, odd, sign;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1511 const char *s, *s0, *s1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1512 double aadj, aadj1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1513 U aadj2, adj, rv, rv0;
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1514 ULong y, z, abs_exp;
58358
5c32f3b65d21 Fix multiple uses of variable 'L' in _Py_dg_strtod, where one use requires an unsigned long and the other a signed long. See also r77421.
Mark Dickinson <dickinsm@gmail.com>
parents: 58356
diff changeset
1515 Long L;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1516 BCinfo bc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1517 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
87584
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1518 size_t ndigits, fraclen;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1519
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1520 dval(&rv) = 0.;
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1521
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1522 /* Start parsing. */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1523 c = *(s = s00);
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1524
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1525 /* Parse optional sign, if present. */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1526 sign = 0;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1527 switch (c) {
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1528 case '-':
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1529 sign = 1;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1530 /* no break */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1531 case '+':
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1532 c = *++s;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1533 }
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1534
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1535 /* Skip leading zeros: lz is true iff there were leading zeros. */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1536 s1 = s;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1537 while (c == '0')
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1538 c = *++s;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1539 lz = s != s1;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1540
87584
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1541 /* Point s0 at the first nonzero digit (if any). fraclen will be the
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1542 number of digits between the decimal point and the end of the
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1543 digit string. ndigits will be the total number of digits ignoring
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1544 leading zeros. */
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1545 s0 = s1 = s;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1546 while ('0' <= c && c <= '9')
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1547 c = *++s;
87584
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1548 ndigits = s - s1;
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1549 fraclen = 0;
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1550
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1551 /* Parse decimal point and following digits. */
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1552 if (c == '.') {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1553 c = *++s;
87584
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1554 if (!ndigits) {
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1555 s1 = s;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1556 while (c == '0')
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1557 c = *++s;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1558 lz = lz || s != s1;
87584
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1559 fraclen += (s - s1);
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1560 s0 = s;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1561 }
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1562 s1 = s;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1563 while ('0' <= c && c <= '9')
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1564 c = *++s;
87584
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1565 ndigits += s - s1;
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1566 fraclen += s - s1;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1567 }
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1568
87584
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1569 /* Now lz is true if and only if there were leading zero digits, and
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1570 ndigits gives the total number of digits ignoring leading zeros. A
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1571 valid input must have at least one digit. */
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1572 if (!ndigits && !lz) {
58420
5dbbc43c591b Don't try to put a value into a NULL pointer.
Mark Dickinson <dickinsm@gmail.com>
parents: 58419
diff changeset
1573 if (se)
5dbbc43c591b Don't try to put a value into a NULL pointer.
Mark Dickinson <dickinsm@gmail.com>
parents: 58419
diff changeset
1574 *se = (char *)s00;
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1575 goto parse_error;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1576 }
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1577
87584
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1578 /* Range check ndigits and fraclen to make sure that they, and values
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1579 computed with them, can safely fit in an int. */
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1580 if (ndigits > MAX_DIGITS || fraclen > MAX_DIGITS) {
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1581 if (se)
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1582 *se = (char *)s00;
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1583 goto parse_error;
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1584 }
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1585 nd = (int)ndigits;
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1586 nd0 = (int)ndigits - (int)fraclen;
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1587
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1588 /* Parse exponent. */
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1589 e = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1590 if (c == 'e' || c == 'E') {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1591 s00 = s;
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1592 c = *++s;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1593
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1594 /* Exponent sign. */
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1595 esign = 0;
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1596 switch (c) {
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1597 case '-':
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1598 esign = 1;
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1599 /* no break */
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1600 case '+':
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1601 c = *++s;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1602 }
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1603
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1604 /* Skip zeros. lz is true iff there are leading zeros. */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1605 s1 = s;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1606 while (c == '0')
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1607 c = *++s;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1608 lz = s != s1;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1609
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1610 /* Get absolute value of the exponent. */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1611 s1 = s;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1612 abs_exp = 0;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1613 while ('0' <= c && c <= '9') {
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1614 abs_exp = 10*abs_exp + (c - '0');
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1615 c = *++s;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1616 }
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1617
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1618 /* abs_exp will be correct modulo 2**32. But 10**9 < 2**32, so if
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1619 there are at most 9 significant exponent digits then overflow is
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1620 impossible. */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1621 if (s - s1 > 9 || abs_exp > MAX_ABS_EXP)
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1622 e = (int)MAX_ABS_EXP;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1623 else
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1624 e = (int)abs_exp;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1625 if (esign)
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1626 e = -e;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1627
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1628 /* A valid exponent must have at least one digit. */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1629 if (s == s1 && !lz)
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1630 s = s00;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1631 }
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1632
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1633 /* Adjust exponent to take into account position of the point. */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1634 e -= nd - nd0;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1635 if (nd0 <= 0)
58356
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1636 nd0 = nd;
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1637
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1638 /* Finished parsing. Set se to indicate how far we parsed */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1639 if (se)
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1640 *se = (char *)s;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1641
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1642 /* If all digits were zero, exit with return value +-0.0. Otherwise,
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1643 strip trailing zeros: scan back until we hit a nonzero digit. */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1644 if (!nd)
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1645 goto ret;
58356
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1646 for (i = nd; i > 0; ) {
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1647 --i;
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1648 if (s0[i < nd0 ? i : i+1] != '0') {
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1649 ++i;
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1650 break;
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1651 }
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1652 }
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1653 e += nd - i;
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1654 nd = i;
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1655 if (nd0 > nd)
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1656 nd0 = nd;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1657
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1658 /* Summary of parsing results. After parsing, and dealing with zero
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1659 * inputs, we have values s0, nd0, nd, e, sign, where:
58356
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1660 *
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1661 * - s0 points to the first significant digit of the input string
58345
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1662 *
58356
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1663 * - nd is the total number of significant digits (here, and
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1664 * below, 'significant digits' means the set of digits of the
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1665 * significand of the input that remain after ignoring leading
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1666 * and trailing zeros).
58345
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1667 *
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1668 * - nd0 indicates the position of the decimal point, if present; it
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1669 * satisfies 1 <= nd0 <= nd. The nd significant digits are in
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1670 * s0[0:nd0] and s0[nd0+1:nd+1] using the usual Python half-open slice
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1671 * notation. (If nd0 < nd, then s0[nd0] contains a '.' character; if
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1672 * nd0 == nd, then s0[nd0] could be any non-digit character.)
58345
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1673 *
58356
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1674 * - e is the adjusted exponent: the absolute value of the number
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1675 * represented by the original input string is n * 10**e, where
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1676 * n is the integer represented by the concatenation of
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1677 * s0[0:nd0] and s0[nd0+1:nd+1]
58345
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1678 *
58356
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1679 * - sign gives the sign of the input: 1 for negative, 0 for positive
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1680 *
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1681 * - the first and last significant digits are nonzero
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1682 */
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1683
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1684 /* put first DBL_DIG+1 digits into integer y and z.
58345
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1685 *
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1686 * - y contains the value represented by the first min(9, nd)
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1687 * significant digits
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1688 *
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1689 * - if nd > 9, z contains the value represented by significant digits
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1690 * with indices in [9, min(16, nd)). So y * 10**(min(16, nd) - 9) + z
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1691 * gives the value represented by the first min(16, nd) sig. digits.
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1692 */
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1693
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1694 bc.e0 = e1 = e;
58356
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1695 y = z = 0;
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1696 for (i = 0; i < nd; i++) {
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1697 if (i < 9)
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1698 y = 10*y + s0[i < nd0 ? i : i+1] - '0';
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1699 else if (i < DBL_DIG+1)
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1700 z = 10*z + s0[i < nd0 ? i : i+1] - '0';
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1701 else
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1702 break;
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1703 }
8e179a0fcb5e Issue #7632: Fix one more case of incorrect rounding for str -> float
Mark Dickinson <dickinsm@gmail.com>
parents: 58345
diff changeset
1704
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1705 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1706 dval(&rv) = y;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1707 if (k > 9) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1708 dval(&rv) = tens[k - 9] * dval(&rv) + z;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1709 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1710 bd0 = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1711 if (nd <= DBL_DIG
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1712 && Flt_Rounds == 1
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1713 ) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1714 if (!e)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1715 goto ret;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1716 if (e > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1717 if (e <= Ten_pmax) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1718 dval(&rv) *= tens[e];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1719 goto ret;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1720 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1721 i = DBL_DIG - nd;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1722 if (e <= Ten_pmax + i) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1723 /* A fancier test would sometimes let us do
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1724 * this for larger i values.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1725 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1726 e -= i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1727 dval(&rv) *= tens[i];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1728 dval(&rv) *= tens[e];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1729 goto ret;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1730 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1731 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1732 else if (e >= -Ten_pmax) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1733 dval(&rv) /= tens[-e];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1734 goto ret;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1735 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1736 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1737 e1 += nd - k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1738
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1739 bc.scale = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1740
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1741 /* Get starting approximation = rv * 10**e1 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1742
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1743 if (e1 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1744 if ((i = e1 & 15))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1745 dval(&rv) *= tens[i];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1746 if (e1 &= ~15) {
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1747 if (e1 > DBL_MAX_10_EXP)
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1748 goto ovfl;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1749 e1 >>= 4;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1750 for(j = 0; e1 > 1; j++, e1 >>= 1)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1751 if (e1 & 1)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1752 dval(&rv) *= bigtens[j];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1753 /* The last multiplication could overflow. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1754 word0(&rv) -= P*Exp_msk1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1755 dval(&rv) *= bigtens[j];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1756 if ((z = word0(&rv) & Exp_mask)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1757 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1758 goto ovfl;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1759 if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1760 /* set to largest number */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1761 /* (Can't trust DBL_MAX) */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1762 word0(&rv) = Big0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1763 word1(&rv) = Big1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1764 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1765 else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1766 word0(&rv) += P*Exp_msk1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1767 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1768 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1769 else if (e1 < 0) {
58421
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1770 /* The input decimal value lies in [10**e1, 10**(e1+16)).
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1771
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1772 If e1 <= -512, underflow immediately.
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1773 If e1 <= -256, set bc.scale to 2*P.
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1774
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1775 So for input value < 1e-256, bc.scale is always set;
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1776 for input value >= 1e-240, bc.scale is never set.
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1777 For input values in [1e-256, 1e-240), bc.scale may or may
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1778 not be set. */
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1779
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1780 e1 = -e1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1781 if ((i = e1 & 15))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1782 dval(&rv) /= tens[i];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1783 if (e1 >>= 4) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1784 if (e1 >= 1 << n_bigtens)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1785 goto undfl;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1786 if (e1 & Scale_Bit)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1787 bc.scale = 2*P;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1788 for(j = 0; e1 > 0; j++, e1 >>= 1)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1789 if (e1 & 1)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1790 dval(&rv) *= tinytens[j];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1791 if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1792 >> Exp_shift)) > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1793 /* scaled rv is denormal; clear j low bits */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1794 if (j >= 32) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1795 word1(&rv) = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1796 if (j >= 53)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1797 word0(&rv) = (P+2)*Exp_msk1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1798 else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1799 word0(&rv) &= 0xffffffff << (j-32);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1800 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1801 else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1802 word1(&rv) &= 0xffffffff << j;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1803 }
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1804 if (!dval(&rv))
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
1805 goto undfl;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1806 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1807 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1808
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1809 /* Now the hard part -- adjusting rv to the correct value.*/
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1810
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1811 /* Put digits into bd: true value = bd * 10^e */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1812
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1813 bc.nd = nd;
58239
3e1712221fa6 Remove unused BCinfo fields and an unused macro.
Mark Dickinson <dickinsm@gmail.com>
parents: 58151
diff changeset
1814 bc.nd0 = nd0; /* Only needed if nd > STRTOD_DIGLIM, but done here */
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1815 /* to silence an erroneous warning about bc.nd0 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1816 /* possibly not being initialized. */
58239
3e1712221fa6 Remove unused BCinfo fields and an unused macro.
Mark Dickinson <dickinsm@gmail.com>
parents: 58151
diff changeset
1817 if (nd > STRTOD_DIGLIM) {
3e1712221fa6 Remove unused BCinfo fields and an unused macro.
Mark Dickinson <dickinsm@gmail.com>
parents: 58151
diff changeset
1818 /* ASSERT(STRTOD_DIGLIM >= 18); 18 == one more than the */
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1819 /* minimum number of decimal digits to distinguish double values */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1820 /* in IEEE arithmetic. */
58345
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1821
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1822 /* Truncate input to 18 significant digits, then discard any trailing
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1823 zeros on the result by updating nd, nd0, e and y suitably. (There's
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1824 no need to update z; it's not reused beyond this point.) */
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1825 for (i = 18; i > 0; ) {
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1826 /* scan back until we hit a nonzero digit. significant digit 'i'
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1827 is s0[i] if i < nd0, s0[i+1] if i >= nd0. */
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1828 --i;
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1829 if (s0[i < nd0 ? i : i+1] != '0') {
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1830 ++i;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1831 break;
58345
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1832 }
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1833 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1834 e += nd - i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1835 nd = i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1836 if (nd0 > nd)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1837 nd0 = nd;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1838 if (nd < 9) { /* must recompute y */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1839 y = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1840 for(i = 0; i < nd0; ++i)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1841 y = 10*y + s0[i] - '0';
58345
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1842 for(; i < nd; ++i)
5673dc3b6432 Issue #7632: Fix a serious wrong output bug for string -> float conversion.
Mark Dickinson <dickinsm@gmail.com>
parents: 58318
diff changeset
1843 y = 10*y + s0[i+1] - '0';
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1844 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1845 }
58310
b39a0219f727 More dtoa.c cleanup; remove the need for bc.dplen, bc.dp0 and bc.dp1.
Mark Dickinson <dickinsm@gmail.com>
parents: 58309
diff changeset
1846 bd0 = s2b(s0, nd0, nd, y);
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1847 if (bd0 == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1848 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1849
58421
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1850 /* Notation for the comments below. Write:
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1851
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1852 - dv for the absolute value of the number represented by the original
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1853 decimal input string.
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1854
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1855 - if we've truncated dv, write tdv for the truncated value.
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1856 Otherwise, set tdv == dv.
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1857
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1858 - srv for the quantity rv/2^bc.scale; so srv is the current binary
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1859 approximation to tdv (and dv). It should be exactly representable
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1860 in an IEEE 754 double.
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1861 */
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1862
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1863 for(;;) {
58421
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1864
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1865 /* This is the main correction loop for _Py_dg_strtod.
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1866
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1867 We've got a decimal value tdv, and a floating-point approximation
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1868 srv=rv/2^bc.scale to tdv. The aim is to determine whether srv is
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1869 close enough (i.e., within 0.5 ulps) to tdv, and to compute a new
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1870 approximation if not.
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1871
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1872 To determine whether srv is close enough to tdv, compute integers
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1873 bd, bb and bs proportional to tdv, srv and 0.5 ulp(srv)
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1874 respectively, and then use integer arithmetic to determine whether
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1875 |tdv - srv| is less than, equal to, or greater than 0.5 ulp(srv).
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1876 */
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1877
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1878 bd = Balloc(bd0->k);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1879 if (bd == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1880 Bfree(bd0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1881 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1882 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1883 Bcopy(bd, bd0);
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1884 bb = sd2b(&rv, bc.scale, &bbe); /* srv = bb * 2^bbe */
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1885 if (bb == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1886 Bfree(bd);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1887 Bfree(bd0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1888 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1889 }
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1890 /* Record whether lsb of bb is odd, in case we need this
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1891 for the round-to-even step later. */
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1892 odd = bb->x[0] & 1;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1893
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1894 /* tdv = bd * 10**e; srv = bb * 2**bbe */
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1895 bs = i2b(1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1896 if (bs == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1897 Bfree(bb);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1898 Bfree(bd);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1899 Bfree(bd0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1900 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1901 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1902
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1903 if (e >= 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1904 bb2 = bb5 = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1905 bd2 = bd5 = e;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1906 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1907 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1908 bb2 = bb5 = -e;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1909 bd2 = bd5 = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1910 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1911 if (bbe >= 0)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1912 bb2 += bbe;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1913 else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1914 bd2 -= bbe;
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1915 bs2 = bb2;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1916 bb2++;
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1917 bd2++;
58421
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1918
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1919 /* At this stage bd5 - bb5 == e == bd2 - bb2 + bbe, bb2 - bs2 == 1,
87584
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1920 and bs == 1, so:
58421
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1921
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1922 tdv == bd * 10**e = bd * 2**(bbe - bb2 + bd2) * 5**(bd5 - bb5)
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1923 srv == bb * 2**bbe = bb * 2**(bbe - bb2 + bb2)
87584
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1924 0.5 ulp(srv) == 2**(bbe-1) = bs * 2**(bbe - bb2 + bs2)
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1925
87584
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1926 It follows that:
58421
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1927
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1928 M * tdv = bd * 2**bd2 * 5**bd5
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1929 M * srv = bb * 2**bb2 * 5**bb5
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1930 M * 0.5 ulp(srv) = bs * 2**bs2 * 5**bb5
58421
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1931
87584
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1932 for some constant M. (Actually, M == 2**(bb2 - bbe) * 5**bb5, but
6d6a018a3bb0 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 61267
diff changeset
1933 this fact is not needed below.)
58421
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1934 */
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1935
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
1936 /* Remove factor of 2**i, where i = min(bb2, bd2, bs2). */
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1937 i = bb2 < bd2 ? bb2 : bd2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1938 if (i > bs2)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1939 i = bs2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1940 if (i > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1941 bb2 -= i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1942 bd2 -= i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1943 bs2 -= i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1944 }
58421
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1945
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
1946 /* Scale bb, bd, bs by the appropriate powers of 2 and 5. */
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1947 if (bb5 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1948 bs = pow5mult(bs, bb5);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1949 if (bs == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1950 Bfree(bb);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1951 Bfree(bd);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1952 Bfree(bd0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1953 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1954 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1955 bb1 = mult(bs, bb);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1956 Bfree(bb);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1957 bb = bb1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1958 if (bb == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1959 Bfree(bs);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1960 Bfree(bd);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1961 Bfree(bd0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1962 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1963 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1964 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1965 if (bb2 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1966 bb = lshift(bb, bb2);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1967 if (bb == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1968 Bfree(bs);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1969 Bfree(bd);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1970 Bfree(bd0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1971 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1972 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1973 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1974 if (bd5 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1975 bd = pow5mult(bd, bd5);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1976 if (bd == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1977 Bfree(bb);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1978 Bfree(bs);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1979 Bfree(bd0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1980 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1981 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1982 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1983 if (bd2 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1984 bd = lshift(bd, bd2);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1985 if (bd == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1986 Bfree(bb);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1987 Bfree(bs);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1988 Bfree(bd0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1989 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1990 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1991 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1992 if (bs2 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1993 bs = lshift(bs, bs2);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1994 if (bs == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1995 Bfree(bb);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1996 Bfree(bd);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1997 Bfree(bd0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1998 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1999 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2000 }
58421
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
2001
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
2002 /* Now bd, bb and bs are scaled versions of tdv, srv and 0.5 ulp(srv),
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
2003 respectively. Compute the difference |tdv - srv|, and compare
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
2004 with 0.5 ulp(srv). */
886320f1ba82 Additional explanatory comments for _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58420
diff changeset
2005
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2006 delta = diff(bb, bd);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2007 if (delta == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2008 Bfree(bb);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2009 Bfree(bs);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2010 Bfree(bd);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2011 Bfree(bd0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2012 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2013 }
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2014 dsign = delta->sign;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2015 delta->sign = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2016 i = cmp(delta, bs);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2017 if (bc.nd > nd && i <= 0) {
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2018 if (dsign)
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2019 break; /* Must use bigcomp(). */
58318
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2020
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2021 /* Here rv overestimates the truncated decimal value by at most
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2022 0.5 ulp(rv). Hence rv either overestimates the true decimal
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2023 value by <= 0.5 ulp(rv), or underestimates it by some small
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2024 amount (< 0.1 ulp(rv)); either way, rv is within 0.5 ulps of
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2025 the true decimal value, so it's possible to exit.
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2026
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2027 Exception: if scaled rv is a normal exact power of 2, but not
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2028 DBL_MIN, then rv - 0.5 ulp(rv) takes us all the way down to the
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2029 next double, so the correctly rounded result is either rv - 0.5
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2030 ulp(rv) or rv; in this case, use bigcomp to distinguish. */
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2031
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2032 if (!word1(&rv) && !(word0(&rv) & Bndry_mask)) {
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2033 /* rv can't be 0, since it's an overestimate for some
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2034 nonzero value. So rv is a normal power of 2. */
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2035 j = (int)(word0(&rv) & Exp_mask) >> Exp_shift;
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2036 /* rv / 2^bc.scale = 2^(j - 1023 - bc.scale); use bigcomp if
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2037 rv / 2^bc.scale >= 2^-1021. */
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2038 if (j - bc.scale >= 2) {
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2039 dval(&rv) -= 0.5 * sulp(&rv, &bc);
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2040 break; /* Use bigcomp. */
58318
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2041 }
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2042 }
92384d7f425a Issue 7632: fix incorrect rounding for long input strings with values very close to a power of 2. (See Bug 4 in the tracker discussion.)
Mark Dickinson <dickinsm@gmail.com>
parents: 58317
diff changeset
2043
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2044 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2045 bc.nd = nd;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2046 i = -1; /* Discarded digits make delta smaller. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2047 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2048 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2049
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2050 if (i < 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2051 /* Error is less than half an ulp -- check for
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2052 * special case of mantissa a power of two.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2053 */
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2054 if (dsign || word1(&rv) || word0(&rv) & Bndry_mask
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2055 || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2056 ) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2057 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2058 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2059 if (!delta->x[0] && delta->wds <= 1) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2060 /* exact result */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2061 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2062 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2063 delta = lshift(delta,Log2P);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2064 if (delta == NULL) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2065 Bfree(bb);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2066 Bfree(bs);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2067 Bfree(bd);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2068 Bfree(bd0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2069 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2070 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2071 if (cmp(delta, bs) > 0)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2072 goto drop_down;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2073 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2074 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2075 if (i == 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2076 /* exactly half-way between */
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2077 if (dsign) {
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2078 if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2079 && word1(&rv) == (
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2080 (bc.scale &&
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2081 (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) ?
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2082 (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2083 0xffffffff)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2084 /*boundary case -- increment exponent*/
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2085 word0(&rv) = (word0(&rv) & Exp_mask)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2086 + Exp_msk1
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2087 ;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2088 word1(&rv) = 0;
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2089 dsign = 0;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2090 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2091 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2092 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2093 else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2094 drop_down:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2095 /* boundary case -- decrement exponent */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2096 if (bc.scale) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2097 L = word0(&rv) & Exp_mask;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2098 if (L <= (2*P+1)*Exp_msk1) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2099 if (L > (P+2)*Exp_msk1)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2100 /* round even ==> */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2101 /* accept rv */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2102 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2103 /* rv = smallest denormal */
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2104 if (bc.nd > nd)
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2105 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2106 goto undfl;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2107 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2108 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2109 L = (word0(&rv) & Exp_mask) - Exp_msk1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2110 word0(&rv) = L | Bndry_mask1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2111 word1(&rv) = 0xffffffff;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2112 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2113 }
58444
7a9f36cc6df1 Issue #7743: Fix a potential incorrect rounding bug in dtoa.c (2nd bug
Mark Dickinson <dickinsm@gmail.com>
parents: 58421
diff changeset
2114 if (!odd)
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2115 break;
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2116 if (dsign)
58459
b40a5a568e76 dtoa.c fix from upstream that fixes incorrectly rounded results for certain subnormals that are also halfway cases.
Mark Dickinson <dickinsm@gmail.com>
parents: 58458
diff changeset
2117 dval(&rv) += sulp(&rv, &bc);
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2118 else {
58459
b40a5a568e76 dtoa.c fix from upstream that fixes incorrectly rounded results for certain subnormals that are also halfway cases.
Mark Dickinson <dickinsm@gmail.com>
parents: 58458
diff changeset
2119 dval(&rv) -= sulp(&rv, &bc);
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2120 if (!dval(&rv)) {
58239
3e1712221fa6 Remove unused BCinfo fields and an unused macro.
Mark Dickinson <dickinsm@gmail.com>
parents: 58151
diff changeset
2121 if (bc.nd >nd)
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2122 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2123 goto undfl;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2124 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2125 }
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2126 dsign = 1 - dsign;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2127 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2128 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2129 if ((aadj = ratio(delta, bs)) <= 2.) {
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2130 if (dsign)
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2131 aadj = aadj1 = 1.;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2132 else if (word1(&rv) || word0(&rv) & Bndry_mask) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2133 if (word1(&rv) == Tiny1 && !word0(&rv)) {
58239
3e1712221fa6 Remove unused BCinfo fields and an unused macro.
Mark Dickinson <dickinsm@gmail.com>
parents: 58151
diff changeset
2134 if (bc.nd >nd)
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2135 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2136 goto undfl;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2137 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2138 aadj = 1.;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2139 aadj1 = -1.;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2140 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2141 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2142 /* special case -- power of FLT_RADIX to be */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2143 /* rounded down... */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2144
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2145 if (aadj < 2./FLT_RADIX)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2146 aadj = 1./FLT_RADIX;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2147 else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2148 aadj *= 0.5;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2149 aadj1 = -aadj;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2150 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2151 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2152 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2153 aadj *= 0.5;
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2154 aadj1 = dsign ? aadj : -aadj;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2155 if (Flt_Rounds == 0)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2156 aadj1 += 0.5;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2157 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2158 y = word0(&rv) & Exp_mask;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2159
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2160 /* Check for overflow */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2161
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2162 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2163 dval(&rv0) = dval(&rv);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2164 word0(&rv) -= P*Exp_msk1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2165 adj.d = aadj1 * ulp(&rv);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2166 dval(&rv) += adj.d;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2167 if ((word0(&rv) & Exp_mask) >=
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2168 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
58390
7322c5691294 Issue #7632: Fix a memory leak in _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58358
diff changeset
2169 if (word0(&rv0) == Big0 && word1(&rv0) == Big1) {
7322c5691294 Issue #7632: Fix a memory leak in _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58358
diff changeset
2170 Bfree(bb);
7322c5691294 Issue #7632: Fix a memory leak in _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58358
diff changeset
2171 Bfree(bd);
7322c5691294 Issue #7632: Fix a memory leak in _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58358
diff changeset
2172 Bfree(bs);
7322c5691294 Issue #7632: Fix a memory leak in _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58358
diff changeset
2173 Bfree(bd0);
7322c5691294 Issue #7632: Fix a memory leak in _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58358
diff changeset
2174 Bfree(delta);
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2175 goto ovfl;
58390
7322c5691294 Issue #7632: Fix a memory leak in _Py_dg_strtod.
Mark Dickinson <dickinsm@gmail.com>
parents: 58358
diff changeset
2176 }
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2177 word0(&rv) = Big0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2178 word1(&rv) = Big1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2179 goto cont;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2180 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2181 else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2182 word0(&rv) += P*Exp_msk1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2183 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2184 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2185 if (bc.scale && y <= 2*P*Exp_msk1) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2186 if (aadj <= 0x7fffffff) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2187 if ((z = (ULong)aadj) <= 0)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2188 z = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2189 aadj = z;
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2190 aadj1 = dsign ? aadj : -aadj;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2191 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2192 dval(&aadj2) = aadj1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2193 word0(&aadj2) += (2*P+1)*Exp_msk1 - y;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2194 aadj1 = dval(&aadj2);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2195 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2196 adj.d = aadj1 * ulp(&rv);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2197 dval(&rv) += adj.d;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2198 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2199 z = word0(&rv) & Exp_mask;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2200 if (bc.nd == nd) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2201 if (!bc.scale)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2202 if (y == z) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2203 /* Can we stop now? */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2204 L = (Long)aadj;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2205 aadj -= L;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2206 /* The tolerances below are conservative. */
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2207 if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) {
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2208 if (aadj < .4999999 || aadj > .5000001)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2209 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2210 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2211 else if (aadj < .4999999/FLT_RADIX)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2212 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2213 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2214 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2215 cont:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2216 Bfree(bb);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2217 Bfree(bd);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2218 Bfree(bs);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2219 Bfree(delta);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2220 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2221 Bfree(bb);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2222 Bfree(bd);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2223 Bfree(bs);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2224 Bfree(bd0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2225 Bfree(delta);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2226 if (bc.nd > nd) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2227 error = bigcomp(&rv, s0, &bc);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2228 if (error)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2229 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2230 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2231
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2232 if (bc.scale) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2233 word0(&rv0) = Exp_1 - 2*P*Exp_msk1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2234 word1(&rv0) = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2235 dval(&rv) *= dval(&rv0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2236 }
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2237
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2238 ret:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2239 return sign ? -dval(&rv) : dval(&rv);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2240
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2241 parse_error:
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2242 return 0.0;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2243
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2244 failed_malloc:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2245 errno = ENOMEM;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2246 return -1.0;
58419
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2247
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2248 undfl:
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2249 return sign ? -0.0 : 0.0;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2250
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2251 ovfl:
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2252 errno = ERANGE;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2253 /* Can't trust HUGE_VAL */
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2254 word0(&rv) = Exp_mask;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2255 word1(&rv) = 0;
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2256 return sign ? -dval(&rv) : dval(&rv);
bac821dffea8 Various dtoa.c cleanups. 1. Despagghetify _Py_dg_strtod parsing code
Mark Dickinson <dickinsm@gmail.com>
parents: 58401
diff changeset
2257
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2258 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2259
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2260 static char *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2261 rv_alloc(int i)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2262 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2263 int j, k, *r;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2264
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2265 j = sizeof(ULong);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2266 for(k = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2267 sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (unsigned)i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2268 j <<= 1)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2269 k++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2270 r = (int*)Balloc(k);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2271 if (r == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2272 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2273 *r = k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2274 return (char *)(r+1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2275 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2276
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2277 static char *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2278 nrv_alloc(char *s, char **rve, int n)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2279 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2280 char *rv, *t;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2281
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2282 rv = rv_alloc(n);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2283 if (rv == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2284 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2285 t = rv;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2286 while((*t = *s++)) t++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2287 if (rve)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2288 *rve = t;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2289 return rv;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2290 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2291
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2292 /* freedtoa(s) must be used to free values s returned by dtoa
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2293 * when MULTIPLE_THREADS is #defined. It should be used in all cases,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2294 * but for consistency with earlier versions of dtoa, it is optional
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2295 * when MULTIPLE_THREADS is not defined.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2296 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2297
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2298 void
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2299 _Py_dg_freedtoa(char *s)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2300 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2301 Bigint *b = (Bigint *)((int *)s - 1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2302 b->maxwds = 1 << (b->k = *(int*)b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2303 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2304 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2305
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2306 /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2307 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2308 * Inspired by "How to Print Floating-Point Numbers Accurately" by
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2309 * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2310 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2311 * Modifications:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2312 * 1. Rather than iterating, we use a simple numeric overestimate
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2313 * to determine k = floor(log10(d)). We scale relevant
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2314 * quantities using O(log2(k)) rather than O(k) multiplications.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2315 * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2316 * try to generate digits strictly left to right. Instead, we
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2317 * compute with fewer bits and propagate the carry if necessary
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2318 * when rounding the final digit up. This is often faster.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2319 * 3. Under the assumption that input will be rounded nearest,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2320 * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2321 * That is, we allow equality in stopping tests when the
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2322 * round-nearest rule will give the same floating-point value
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2323 * as would satisfaction of the stopping test with strict
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2324 * inequality.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2325 * 4. We remove common factors of powers of 2 from relevant
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2326 * quantities.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2327 * 5. When converting floating-point integers less than 1e16,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2328 * we use floating-point arithmetic rather than resorting
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2329 * to multiple-precision integers.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2330 * 6. When asked to produce fewer than 15 digits, we first try
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2331 * to get by with floating-point arithmetic; we resort to
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2332 * multiple-precision integer arithmetic only if we cannot
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2333 * guarantee that the floating-point calculation has given
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2334 * the correctly rounded result. For k requested digits and
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2335 * "uniformly" distributed input, the probability is
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2336 * something like 10^(k-15) that we must resort to the Long
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2337 * calculation.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2338 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2339
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2340 /* Additional notes (METD): (1) returns NULL on failure. (2) to avoid memory
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2341 leakage, a successful call to _Py_dg_dtoa should always be matched by a
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2342 call to _Py_dg_freedtoa. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2343
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2344 char *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2345 _Py_dg_dtoa(double dd, int mode, int ndigits,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2346 int *decpt, int *sign, char **rve)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2347 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2348 /* Arguments ndigits, decpt, sign are similar to those
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2349 of ecvt and fcvt; trailing zeros are suppressed from
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2350 the returned string. If not null, *rve is set to point
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2351 to the end of the return value. If d is +-Infinity or NaN,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2352 then *decpt is set to 9999.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2353
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2354 mode:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2355 0 ==> shortest string that yields d when read in
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2356 and rounded to nearest.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2357 1 ==> like 0, but with Steele & White stopping rule;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2358 e.g. with IEEE P754 arithmetic , mode 0 gives
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2359 1e23 whereas mode 1 gives 9.999999999999999e22.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2360 2 ==> max(1,ndigits) significant digits. This gives a
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2361 return value similar to that of ecvt, except
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2362 that trailing zeros are suppressed.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2363 3 ==> through ndigits past the decimal point. This
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2364 gives a return value similar to that from fcvt,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2365 except that trailing zeros are suppressed, and
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2366 ndigits can be negative.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2367 4,5 ==> similar to 2 and 3, respectively, but (in
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2368 round-nearest mode) with the tests of mode 0 to
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2369 possibly return a shorter string that rounds to d.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2370 With IEEE arithmetic and compilation with
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2371 -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2372 as modes 2 and 3 when FLT_ROUNDS != 1.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2373 6-9 ==> Debugging modes similar to mode - 4: don't try
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2374 fast floating-point estimate (if applicable).
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2375
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2376 Values of mode other than 0-9 are treated as mode 0.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2377
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2378 Sufficient space is allocated to the return value
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2379 to hold the suppressed trailing zeros.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2380 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2381
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2382 int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2383 j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2384 spec_case, try_quick;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2385 Long L;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2386 int denorm;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2387 ULong x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2388 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2389 U d2, eps, u;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2390 double ds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2391 char *s, *s0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2392
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2393 /* set pointers to NULL, to silence gcc compiler warnings and make
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2394 cleanup easier on error */
61267
5cea27275af1 Remove three unneeded variable assignments.
Brett Cannon <bcannon@gmail.com>
parents: 58459
diff changeset
2395 mlo = mhi = S = 0;
56700
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2396 s0 = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2397
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2398 u.d = dd;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2399 if (word0(&u) & Sign_bit) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2400 /* set sign for everything, including 0's and NaNs */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2401 *sign = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2402 word0(&u) &= ~Sign_bit; /* clear sign bit */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2403 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2404 else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2405 *sign = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2406
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2407 /* quick return for Infinities, NaNs and zeros */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2408 if ((word0(&u) & Exp_mask) == Exp_mask)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2409 {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2410 /* Infinity or NaN */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2411 *decpt = 9999;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2412 if (!word1(&u) && !(word0(&u) & 0xfffff))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2413 return nrv_alloc("Infinity", rve, 8);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2414 return nrv_alloc("NaN", rve, 3);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2415 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2416 if (!dval(&u)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2417 *decpt = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2418 return nrv_alloc("0", rve, 1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2419 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2420
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2421 /* compute k = floor(log10(d)). The computation may leave k
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2422 one too large, but should never leave k too small. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2423 b = d2b(&u, &be, &bbits);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2424 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2425 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2426 if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2427 dval(&d2) = dval(&u);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2428 word0(&d2) &= Frac_mask1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2429 word0(&d2) |= Exp_11;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2430
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2431 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2432 * log10(x) = log(x) / log(10)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2433 * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2434 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2435 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2436 * This suggests computing an approximation k to log10(d) by
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2437 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2438 * k = (i - Bias)*0.301029995663981
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2439 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2440 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2441 * We want k to be too large rather than too small.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2442 * The error in the first-order Taylor series approximation
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2443 * is in our favor, so we just round up the constant enough
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2444 * to compensate for any error in the multiplication of
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2445 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2446 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2447 * adding 1e-13 to the constant term more than suffices.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2448 * Hence we adjust the constant term to 0.1760912590558.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2449 * (We could get a more accurate k by invoking log10,
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2450 * but this is probably not worthwhile.)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2451 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2452
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2453 i -= Bias;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2454 denorm = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2455 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2456 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2457 /* d is denormalized */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2458
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2459 i = bbits + be + (Bias + (P-1) - 1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2460 x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2461 : word1(&u) << (32 - i);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2462 dval(&d2) = x;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2463 word0(&d2) -= 31*Exp_msk1; /* adjust exponent */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2464 i -= (Bias + (P-1) - 1) + 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2465 denorm = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2466 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2467 ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 +
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2468 i*0.301029995663981;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2469 k = (int)ds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2470 if (ds < 0. && ds != k)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2471 k--; /* want k = floor(ds) */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2472 k_check = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2473 if (k >= 0 && k <= Ten_pmax) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2474 if (dval(&u) < tens[k])
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2475 k--;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2476 k_check = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2477 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2478 j = bbits - i - 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2479 if (j >= 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2480 b2 = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2481 s2 = j;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2482 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2483 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2484 b2 = -j;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2485 s2 = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2486 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2487 if (k >= 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2488 b5 = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2489 s5 = k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2490 s2 += k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2491 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2492 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2493 b2 -= k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2494 b5 = -k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2495 s5 = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2496 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2497 if (mode < 0 || mode > 9)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2498 mode = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2499
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2500 try_quick = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2501
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2502 if (mode > 5) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2503 mode -= 4;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2504 try_quick = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2505 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2506 leftright = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2507 ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2508 /* silence erroneous "gcc -Wall" warning. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2509 switch(mode) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2510 case 0:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2511 case 1:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2512 i = 18;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2513 ndigits = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2514 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2515 case 2:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2516 leftright = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2517 /* no break */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2518 case 4:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2519 if (ndigits <= 0)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2520 ndigits = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2521 ilim = ilim1 = i = ndigits;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2522 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2523 case 3:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2524 leftright = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2525 /* no break */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2526 case 5:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2527 i = ndigits + k + 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2528 ilim = i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2529 ilim1 = i - 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2530 if (i <= 0)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2531 i = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2532 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2533 s0 = rv_alloc(i);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2534 if (s0 == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2535 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2536 s = s0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2537
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2538
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2539 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2540
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2541 /* Try to get by with floating-point arithmetic. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2542
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2543 i = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2544 dval(&d2) = dval(&u);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2545 k0 = k;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2546 ilim0 = ilim;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2547 ieps = 2; /* conservative */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2548 if (k > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2549 ds = tens[k&0xf];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2550 j = k >> 4;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2551 if (j & Bletch) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2552 /* prevent overflows */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2553 j &= Bletch - 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2554 dval(&u) /= bigtens[n_bigtens-1];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2555 ieps++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2556 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2557 for(; j; j >>= 1, i++)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2558 if (j & 1) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2559 ieps++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2560 ds *= bigtens[i];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2561 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2562 dval(&u) /= ds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2563 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2564 else if ((j1 = -k)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2565 dval(&u) *= tens[j1 & 0xf];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2566 for(j = j1 >> 4; j; j >>= 1, i++)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2567 if (j & 1) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2568 ieps++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2569 dval(&u) *= bigtens[i];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2570 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2571 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2572 if (k_check && dval(&u) < 1. && ilim > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2573 if (ilim1 <= 0)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2574 goto fast_failed;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2575 ilim = ilim1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2576 k--;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2577 dval(&u) *= 10.;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2578 ieps++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2579 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2580 dval(&eps) = ieps*dval(&u) + 7.;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2581 word0(&eps) -= (P-1)*Exp_msk1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2582 if (ilim == 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2583 S = mhi = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2584 dval(&u) -= 5.;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2585 if (dval(&u) > dval(&eps))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2586 goto one_digit;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2587 if (dval(&u) < -dval(&eps))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2588 goto no_digits;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2589 goto fast_failed;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2590 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2591 if (leftright) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2592 /* Use Steele & White method of only
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2593 * generating digits needed.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2594 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2595 dval(&eps) = 0.5/tens[ilim-1] - dval(&eps);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2596 for(i = 0;;) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2597 L = (Long)dval(&u);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2598 dval(&u) -= L;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2599 *s++ = '0' + (int)L;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2600 if (dval(&u) < dval(&eps))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2601 goto ret1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2602 if (1. - dval(&u) < dval(&eps))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2603 goto bump_up;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2604 if (++i >= ilim)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2605 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2606 dval(&eps) *= 10.;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2607 dval(&u) *= 10.;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2608 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2609 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2610 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2611 /* Generate ilim digits, then fix them up. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2612 dval(&eps) *= tens[ilim-1];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2613 for(i = 1;; i++, dval(&u) *= 10.) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2614 L = (Long)(dval(&u));
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2615 if (!(dval(&u) -= L))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2616 ilim = i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2617 *s++ = '0' + (int)L;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2618 if (i == ilim) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2619 if (dval(&u) > 0.5 + dval(&eps))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2620 goto bump_up;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2621 else if (dval(&u) < 0.5 - dval(&eps)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2622 while(*--s == '0');
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2623 s++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2624 goto ret1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2625 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2626 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2627 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2628 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2629 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2630 fast_failed:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2631 s = s0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2632 dval(&u) = dval(&d2);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2633 k = k0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2634 ilim = ilim0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2635 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2636
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2637 /* Do we have a "small" integer? */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2638
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2639 if (be >= 0 && k <= Int_max) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2640 /* Yes. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2641 ds = tens[k];
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2642 if (ndigits < 0 && ilim <= 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2643 S = mhi = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2644 if (ilim < 0 || dval(&u) <= 5*ds)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2645 goto no_digits;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2646 goto one_digit;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2647 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2648 for(i = 1;; i++, dval(&u) *= 10.) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2649 L = (Long)(dval(&u) / ds);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2650 dval(&u) -= L*ds;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2651 *s++ = '0' + (int)L;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2652 if (!dval(&u)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2653 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2654 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2655 if (i == ilim) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2656 dval(&u) += dval(&u);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2657 if (dval(&u) > ds || (dval(&u) == ds && L & 1)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2658 bump_up:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2659 while(*--s == '9')
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2660 if (s == s0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2661 k++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2662 *s = '0';
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2663 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2664 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2665 ++*s++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2666 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2667 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2668 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2669 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2670 goto ret1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2671 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2672
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2673 m2 = b2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2674 m5 = b5;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2675 if (leftright) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2676 i =
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2677 denorm ? be + (Bias + (P-1) - 1 + 1) :
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2678 1 + P - bbits;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2679 b2 += i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2680 s2 += i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2681 mhi = i2b(1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2682 if (mhi == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2683 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2684 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2685 if (m2 > 0 && s2 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2686 i = m2 < s2 ? m2 : s2;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2687 b2 -= i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2688 m2 -= i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2689 s2 -= i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2690 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2691 if (b5 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2692 if (leftright) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2693 if (m5 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2694 mhi = pow5mult(mhi, m5);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2695 if (mhi == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2696 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2697 b1 = mult(mhi, b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2698 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2699 b = b1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2700 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2701 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2702 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2703 if ((j = b5 - m5)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2704 b = pow5mult(b, j);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2705 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2706 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2707 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2708 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2709 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2710 b = pow5mult(b, b5);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2711 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2712 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2713 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2714 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2715 S = i2b(1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2716 if (S == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2717 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2718 if (s5 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2719 S = pow5mult(S, s5);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2720 if (S == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2721 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2722 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2723
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2724 /* Check for special case that d is a normalized power of 2. */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2725
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2726 spec_case = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2727 if ((mode < 2 || leftright)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2728 ) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2729 if (!word1(&u) && !(word0(&u) & Bndry_mask)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2730 && word0(&u) & (Exp_mask & ~Exp_msk1)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2731 ) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2732 /* The special case */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2733 b2 += Log2P;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2734 s2 += Log2P;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2735 spec_case = 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2736 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2737 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2738
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2739 /* Arrange for convenient computation of quotients:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2740 * shift left if necessary so divisor has 4 leading 0 bits.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2741 *
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2742 * Perhaps we should just compute leading 28 bits of S once
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2743 * and for all and pass them and a shift to quorem, so it
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2744 * can do shifts and ors to compute the numerator for q.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2745 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2746 #define iInc 28
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2747 i = dshift(S, s2);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2748 b2 += i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2749 m2 += i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2750 s2 += i;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2751 if (b2 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2752 b = lshift(b, b2);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2753 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2754 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2755 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2756 if (s2 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2757 S = lshift(S, s2);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2758 if (S == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2759 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2760 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2761 if (k_check) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2762 if (cmp(b,S) < 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2763 k--;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2764 b = multadd(b, 10, 0); /* we botched the k estimate */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2765 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2766 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2767 if (leftright) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2768 mhi = multadd(mhi, 10, 0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2769 if (mhi == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2770 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2771 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2772 ilim = ilim1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2773 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2774 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2775 if (ilim <= 0 && (mode == 3 || mode == 5)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2776 if (ilim < 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2777 /* no digits, fcvt style */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2778 no_digits:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2779 k = -1 - ndigits;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2780 goto ret;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2781 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2782 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2783 S = multadd(S, 5, 0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2784 if (S == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2785 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2786 if (cmp(b, S) <= 0)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2787 goto no_digits;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2788 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2789 one_digit:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2790 *s++ = '1';
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2791 k++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2792 goto ret;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2793 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2794 if (leftright) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2795 if (m2 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2796 mhi = lshift(mhi, m2);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2797 if (mhi == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2798 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2799 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2800
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2801 /* Compute mlo -- check for special case
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2802 * that d is a normalized power of 2.
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2803 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2804
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2805 mlo = mhi;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2806 if (spec_case) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2807 mhi = Balloc(mhi->k);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2808 if (mhi == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2809 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2810 Bcopy(mhi, mlo);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2811 mhi = lshift(mhi, Log2P);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2812 if (mhi == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2813 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2814 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2815
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2816 for(i = 1;;i++) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2817 dig = quorem(b,S) + '0';
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2818 /* Do we yet have the shortest decimal string
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2819 * that will round to d?
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2820 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2821 j = cmp(b, mlo);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2822 delta = diff(S, mhi);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2823 if (delta == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2824 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2825 j1 = delta->sign ? 1 : cmp(b, delta);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2826 Bfree(delta);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2827 if (j1 == 0 && mode != 1 && !(word1(&u) & 1)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2828 ) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2829 if (dig == '9')
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2830 goto round_9_up;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2831 if (j > 0)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2832 dig++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2833 *s++ = dig;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2834 goto ret;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2835 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2836 if (j < 0 || (j == 0 && mode != 1
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2837 && !(word1(&u) & 1)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2838 )) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2839 if (!b->x[0] && b->wds <= 1) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2840 goto accept_dig;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2841 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2842 if (j1 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2843 b = lshift(b, 1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2844 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2845 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2846 j1 = cmp(b, S);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2847 if ((j1 > 0 || (j1 == 0 && dig & 1))
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2848 && dig++ == '9')
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2849 goto round_9_up;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2850 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2851 accept_dig:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2852 *s++ = dig;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2853 goto ret;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2854 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2855 if (j1 > 0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2856 if (dig == '9') { /* possible if i == 1 */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2857 round_9_up:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2858 *s++ = '9';
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2859 goto roundoff;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2860 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2861 *s++ = dig + 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2862 goto ret;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2863 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2864 *s++ = dig;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2865 if (i == ilim)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2866 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2867 b = multadd(b, 10, 0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2868 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2869 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2870 if (mlo == mhi) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2871 mlo = mhi = multadd(mhi, 10, 0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2872 if (mlo == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2873 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2874 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2875 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2876 mlo = multadd(mlo, 10, 0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2877 if (mlo == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2878 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2879 mhi = multadd(mhi, 10, 0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2880 if (mhi == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2881 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2882 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2883 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2884 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2885 else
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2886 for(i = 1;; i++) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2887 *s++ = dig = quorem(b,S) + '0';
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2888 if (!b->x[0] && b->wds <= 1) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2889 goto ret;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2890 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2891 if (i >= ilim)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2892 break;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2893 b = multadd(b, 10, 0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2894 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2895 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2896 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2897
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2898 /* Round off last digit */
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2899
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2900 b = lshift(b, 1);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2901 if (b == NULL)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2902 goto failed_malloc;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2903 j = cmp(b, S);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2904 if (j > 0 || (j == 0 && dig & 1)) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2905 roundoff:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2906 while(*--s == '9')
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2907 if (s == s0) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2908 k++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2909 *s++ = '1';
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2910 goto ret;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2911 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2912 ++*s++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2913 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2914 else {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2915 while(*--s == '0');
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2916 s++;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2917 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2918 ret:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2919 Bfree(S);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2920 if (mhi) {
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2921 if (mlo && mlo != mhi)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2922 Bfree(mlo);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2923 Bfree(mhi);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2924 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2925 ret1:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2926 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2927 *s = 0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2928 *decpt = k + 1;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2929 if (rve)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2930 *rve = s;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2931 return s0;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2932 failed_malloc:
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2933 if (S)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2934 Bfree(S);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2935 if (mlo && mlo != mhi)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2936 Bfree(mlo);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2937 if (mhi)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2938 Bfree(mhi);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2939 if (b)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2940 Bfree(b);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2941 if (s0)
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2942 _Py_dg_freedtoa(s0);
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2943 return NULL;
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2944 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2945 #ifdef __cplusplus
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2946 }
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2947 #endif
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2948
2146bbdf4ed7 Issue #7117: Prepare for backport of py3k float repr.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2949 #endif /* PY_NO_SHORT_FLOAT_REPR */