annotate Python/dtoa.c @ 87686:07425df887b5 3.3

Fixes issue #15798: subprocess.Popen() no longer fails if file descriptor 0, 1 or 2 is closed. The errpipe_write fd will always be >= 3.
author Gregory P. Smith <greg@krypto.org>
date Sun, 01 Dec 2013 17:27:40 -0800
parents eac133e13bb5
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1 /****************************************************************
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
3 * The author of this software is David M. Gay.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
4 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
5 * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
6 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
7 * Permission to use, copy, modify, and distribute this software for any
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
8 * purpose without fee is hereby granted, provided that this entire notice
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
9 * is included in all copies of any software which is or includes a copy
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
10 * or modification of this software and in all copies of the supporting
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
11 * documentation for such software.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
12 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
13 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
14 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
15 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
16 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
17 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
18 ***************************************************************/
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
19
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
20 /****************************************************************
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
21 * This is dtoa.c by David M. Gay, downloaded from
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
22 * http://www.netlib.org/fp/dtoa.c on April 15, 2009 and modified for
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
23 * inclusion into the Python core by Mark E. T. Dickinson and Eric V. Smith.
53203
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
24 *
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
25 * Please remember to check http://www.netlib.org/fp regularly (and especially
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
26 * before any Python release) for bugfixes and updates.
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
27 *
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
28 * The major modifications from Gay's original code are as follows:
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
29 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
30 * 0. The original code has been specialized to Python's needs by removing
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
31 * many of the #ifdef'd sections. In particular, code to support VAX and
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
32 * IBM floating-point formats, hex NaNs, hex floats, locale-aware
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
33 * treatment of the decimal point, and setting of the inexact flag have
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
34 * been removed.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
35 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
36 * 1. We use PyMem_Malloc and PyMem_Free in place of malloc and free.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
37 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
38 * 2. The public functions strtod, dtoa and freedtoa all now have
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
39 * a _Py_dg_ prefix.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
40 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
41 * 3. Instead of assuming that PyMem_Malloc always succeeds, we thread
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
42 * PyMem_Malloc failures through the code. The functions
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
43 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
44 * Balloc, multadd, s2b, i2b, mult, pow5mult, lshift, diff, d2b
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
45 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
46 * of return type *Bigint all return NULL to indicate a malloc failure.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
47 * Similarly, rv_alloc and nrv_alloc (return type char *) return NULL on
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
48 * failure. bigcomp now has return type int (it used to be void) and
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
49 * returns -1 on failure and 0 otherwise. _Py_dg_dtoa returns NULL
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
50 * on failure. _Py_dg_strtod indicates failure due to malloc failure
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
51 * by returning -1.0, setting errno=ENOMEM and *se to s00.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
52 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
53 * 4. The static variable dtoa_result has been removed. Callers of
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
54 * _Py_dg_dtoa are expected to call _Py_dg_freedtoa to free
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
55 * the memory allocated by _Py_dg_dtoa.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
56 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
57 * 5. The code has been reformatted to better fit with Python's
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
58 * C style guide (PEP 7).
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
59 *
53203
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
60 * 6. A bug in the memory allocation has been fixed: to avoid FREEing memory
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
61 * that hasn't been MALLOC'ed, private_mem should only be used when k <=
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
62 * Kmax.
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
63 *
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53207
diff changeset
64 * 7. _Py_dg_strtod has been modified so that it doesn't accept strings with
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53207
diff changeset
65 * leading whitespace.
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53207
diff changeset
66 *
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
67 ***************************************************************/
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
68
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
69 /* Please send bug reports for the original dtoa.c code to David M. Gay (dmg
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
70 * at acm dot org, with " at " changed at "@" and " dot " changed to ".").
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
71 * Please report bugs for this modified version using the Python issue tracker
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
72 * (http://bugs.python.org). */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
73
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
74 /* On a machine with IEEE extended-precision registers, it is
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
75 * necessary to specify double-precision (53-bit) rounding precision
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
76 * before invoking strtod or dtoa. If the machine uses (the equivalent
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
77 * of) Intel 80x87 arithmetic, the call
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
78 * _control87(PC_53, MCW_PC);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
79 * does this with many compilers. Whether this or another call is
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
80 * appropriate depends on the compiler; for this to work, it may be
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
81 * necessary to #include "float.h" or another system-dependent header
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
82 * file.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
83 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
84
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
85 /* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
86 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
87 * This strtod returns a nearest machine number to the input decimal
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
88 * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
89 * broken by the IEEE round-even rule. Otherwise ties are broken by
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
90 * biased rounding (add half and chop).
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
91 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
92 * Inspired loosely by William D. Clinger's paper "How to Read Floating
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
93 * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
94 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
95 * Modifications:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
96 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
97 * 1. We only require IEEE, IBM, or VAX double-precision
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
98 * arithmetic (not IEEE double-extended).
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
99 * 2. We get by with floating-point arithmetic in a case that
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
100 * Clinger missed -- when we're computing d * 10^n
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
101 * for a small integer d and the integer n is not too
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
102 * much larger than 22 (the maximum integer k for which
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
103 * we can represent 10^k exactly), we may be able to
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
104 * compute (d*10^k) * 10^(e-k) with just one roundoff.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
105 * 3. Rather than a bit-at-a-time adjustment of the binary
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
106 * result in the hard case, we use floating-point
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
107 * arithmetic to determine the adjustment to within
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
108 * one bit; only in really hard cases do we need to
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
109 * compute a second residual.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
110 * 4. Because of 3., we don't need a large table of powers of 10
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
111 * for ten-to-e (just some small tables, e.g. of 10^k
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
112 * for 0 <= k <= 22).
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
113 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
114
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
115 /* Linking of Python's #defines to Gay's #defines starts here. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
116
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
117 #include "Python.h"
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
118
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
119 /* if PY_NO_SHORT_FLOAT_REPR is defined, then don't even try to compile
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
120 the following code */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
121 #ifndef PY_NO_SHORT_FLOAT_REPR
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
122
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
123 #include "float.h"
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
124
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
125 #define MALLOC PyMem_Malloc
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
126 #define FREE PyMem_Free
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
127
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
128 /* This code should also work for ARM mixed-endian format on little-endian
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
129 machines, where doubles have byte order 45670123 (in increasing address
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
130 order, 0 being the least significant byte). */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
131 #ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
132 # define IEEE_8087
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
133 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
134 #if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || \
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
135 defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
136 # define IEEE_MC68k
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
137 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
138 #if defined(IEEE_8087) + defined(IEEE_MC68k) != 1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
139 #error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined."
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
140 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
141
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
142 /* The code below assumes that the endianness of integers matches the
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
143 endianness of the two 32-bit words of a double. Check this. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
144 #if defined(WORDS_BIGENDIAN) && (defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) || \
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
145 defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
146 #error "doubles and ints have incompatible endianness"
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
147 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
148
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
149 #if !defined(WORDS_BIGENDIAN) && defined(DOUBLE_IS_BIG_ENDIAN_IEEE754)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
150 #error "doubles and ints have incompatible endianness"
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
151 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
152
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
153
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
154 #if defined(HAVE_UINT32_T) && defined(HAVE_INT32_T)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
155 typedef PY_UINT32_T ULong;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
156 typedef PY_INT32_T Long;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
157 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
158 #error "Failed to find an exact-width 32-bit integer type"
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
159 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
160
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
161 #if defined(HAVE_UINT64_T)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
162 #define ULLong PY_UINT64_T
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
163 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
164 #undef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
165 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
166
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
167 #undef DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
168 #ifdef Py_DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
169 #define DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
170 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
171
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
172 /* End Python #define linking */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
173
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
174 #ifdef DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
175 #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
176 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
177
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
178 #ifndef PRIVATE_MEM
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
179 #define PRIVATE_MEM 2304
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
180 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
181 #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
182 static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
183
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
184 #ifdef __cplusplus
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
185 extern "C" {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
186 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
187
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
188 typedef union { double d; ULong L[2]; } U;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
189
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
190 #ifdef IEEE_8087
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
191 #define word0(x) (x)->L[1]
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
192 #define word1(x) (x)->L[0]
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
193 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
194 #define word0(x) (x)->L[0]
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
195 #define word1(x) (x)->L[1]
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
196 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
197 #define dval(x) (x)->d
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
198
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
199 #ifndef STRTOD_DIGLIM
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
200 #define STRTOD_DIGLIM 40
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
201 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
202
58279
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
203 /* maximum permitted exponent value for strtod; exponents larger than
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
204 MAX_ABS_EXP in absolute value get truncated to +-MAX_ABS_EXP. MAX_ABS_EXP
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
205 should fit into an int. */
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
206 #ifndef MAX_ABS_EXP
87582
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
207 #define MAX_ABS_EXP 1100000000U
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
208 #endif
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
209 /* Bound on length of pieces of input strings in _Py_dg_strtod; specifically,
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
210 this is used to bound the total number of digits ignoring leading zeros and
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
211 the number of digits that follow the decimal point. Ideally, MAX_DIGITS
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
212 should satisfy MAX_DIGITS + 400 < MAX_ABS_EXP; that ensures that the
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
213 exponent clipping in _Py_dg_strtod can't affect the value of the output. */
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
214 #ifndef MAX_DIGITS
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
215 #define MAX_DIGITS 1000000000U
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
216 #endif
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
217
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
218 /* Guard against trying to use the above values on unusual platforms with ints
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
219 * of width less than 32 bits. */
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
220 #if MAX_ABS_EXP > INT_MAX
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
221 #error "MAX_ABS_EXP should fit in an int"
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
222 #endif
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
223 #if MAX_DIGITS > INT_MAX
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
224 #error "MAX_DIGITS should fit in an int"
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
225 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
226
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
227 /* The following definition of Storeinc is appropriate for MIPS processors.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
228 * An alternative that might be better on some machines is
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
229 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
230 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
231 #if defined(IEEE_8087)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
232 #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
233 ((unsigned short *)a)[0] = (unsigned short)c, a++)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
234 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
235 #define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
236 ((unsigned short *)a)[1] = (unsigned short)c, a++)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
237 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
238
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
239 /* #define P DBL_MANT_DIG */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
240 /* Ten_pmax = floor(P*log(2)/log(5)) */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
241 /* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
242 /* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
243 /* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
244
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
245 #define Exp_shift 20
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
246 #define Exp_shift1 20
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
247 #define Exp_msk1 0x100000
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
248 #define Exp_msk11 0x100000
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
249 #define Exp_mask 0x7ff00000
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
250 #define P 53
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
251 #define Nbits 53
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
252 #define Bias 1023
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
253 #define Emax 1023
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
254 #define Emin (-1022)
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
255 #define Etiny (-1074) /* smallest denormal is 2**Etiny */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
256 #define Exp_1 0x3ff00000
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
257 #define Exp_11 0x3ff00000
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
258 #define Ebits 11
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
259 #define Frac_mask 0xfffff
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
260 #define Frac_mask1 0xfffff
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
261 #define Ten_pmax 22
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
262 #define Bletch 0x10
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
263 #define Bndry_mask 0xfffff
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
264 #define Bndry_mask1 0xfffff
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
265 #define Sign_bit 0x80000000
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
266 #define Log2P 1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
267 #define Tiny0 0
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
268 #define Tiny1 1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
269 #define Quick_max 14
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
270 #define Int_max 14
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
271
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
272 #ifndef Flt_Rounds
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
273 #ifdef FLT_ROUNDS
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
274 #define Flt_Rounds FLT_ROUNDS
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
275 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
276 #define Flt_Rounds 1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
277 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
278 #endif /*Flt_Rounds*/
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
279
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
280 #define Rounding Flt_Rounds
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
281
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
282 #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
283 #define Big1 0xffffffff
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
284
76629
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
285 /* Standard NaN used by _Py_dg_stdnan. */
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
286
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
287 #define NAN_WORD0 0x7ff80000
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
288 #define NAN_WORD1 0
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
289
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
290 /* Bits of the representation of positive infinity. */
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
291
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
292 #define POSINF_WORD0 0x7ff00000
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
293 #define POSINF_WORD1 0
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
294
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
295 /* struct BCinfo is used to pass information from _Py_dg_strtod to bigcomp */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
296
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
297 typedef struct BCinfo BCinfo;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
298 struct
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
299 BCinfo {
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
300 int e0, nd, nd0, scale;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
301 };
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
302
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
303 #define FFFFFFFF 0xffffffffUL
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
304
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
305 #define Kmax 7
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
306
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
307 /* struct Bigint is used to represent arbitrary-precision integers. These
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
308 integers are stored in sign-magnitude format, with the magnitude stored as
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
309 an array of base 2**32 digits. Bigints are always normalized: if x is a
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
310 Bigint then x->wds >= 1, and either x->wds == 1 or x[wds-1] is nonzero.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
311
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
312 The Bigint fields are as follows:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
313
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
314 - next is a header used by Balloc and Bfree to keep track of lists
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
315 of freed Bigints; it's also used for the linked list of
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
316 powers of 5 of the form 5**2**i used by pow5mult.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
317 - k indicates which pool this Bigint was allocated from
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
318 - maxwds is the maximum number of words space was allocated for
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
319 (usually maxwds == 2**k)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
320 - sign is 1 for negative Bigints, 0 for positive. The sign is unused
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
321 (ignored on inputs, set to 0 on outputs) in almost all operations
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
322 involving Bigints: a notable exception is the diff function, which
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
323 ignores signs on inputs but sets the sign of the output correctly.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
324 - wds is the actual number of significant words
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
325 - x contains the vector of words (digits) for this Bigint, from least
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
326 significant (x[0]) to most significant (x[wds-1]).
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
327 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
328
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
329 struct
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
330 Bigint {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
331 struct Bigint *next;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
332 int k, maxwds, sign, wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
333 ULong x[1];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
334 };
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
335
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
336 typedef struct Bigint Bigint;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
337
58402
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
338 #ifndef Py_USING_MEMORY_DEBUGGER
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
339
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
340 /* Memory management: memory is allocated from, and returned to, Kmax+1 pools
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
341 of memory, where pool k (0 <= k <= Kmax) is for Bigints b with b->maxwds ==
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
342 1 << k. These pools are maintained as linked lists, with freelist[k]
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
343 pointing to the head of the list for pool k.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
344
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
345 On allocation, if there's no free slot in the appropriate pool, MALLOC is
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
346 called to get more memory. This memory is not returned to the system until
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
347 Python quits. There's also a private memory pool that's allocated from
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
348 in preference to using MALLOC.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
349
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
350 For Bigints with more than (1 << Kmax) digits (which implies at least 1233
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
351 decimal digits), memory is directly allocated using MALLOC, and freed using
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
352 FREE.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
353
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
354 XXX: it would be easy to bypass this memory-management system and
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
355 translate each call to Balloc into a call to PyMem_Malloc, and each
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
356 Bfree to PyMem_Free. Investigate whether this has any significant
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
357 performance on impact. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
358
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
359 static Bigint *freelist[Kmax+1];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
360
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
361 /* Allocate space for a Bigint with up to 1<<k digits */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
362
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
363 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
364 Balloc(int k)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
365 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
366 int x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
367 Bigint *rv;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
368 unsigned int len;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
369
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
370 if (k <= Kmax && (rv = freelist[k]))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
371 freelist[k] = rv->next;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
372 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
373 x = 1 << k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
374 len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
375 /sizeof(double);
53203
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
376 if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) {
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
377 rv = (Bigint*)pmem_next;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
378 pmem_next += len;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
379 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
380 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
381 rv = (Bigint*)MALLOC(len*sizeof(double));
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
382 if (rv == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
383 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
384 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
385 rv->k = k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
386 rv->maxwds = x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
387 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
388 rv->sign = rv->wds = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
389 return rv;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
390 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
391
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
392 /* Free a Bigint allocated with Balloc */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
393
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
394 static void
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
395 Bfree(Bigint *v)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
396 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
397 if (v) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
398 if (v->k > Kmax)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
399 FREE((void*)v);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
400 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
401 v->next = freelist[v->k];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
402 freelist[v->k] = v;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
403 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
404 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
405 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
406
58402
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
407 #else
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
408
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
409 /* Alternative versions of Balloc and Bfree that use PyMem_Malloc and
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
410 PyMem_Free directly in place of the custom memory allocation scheme above.
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
411 These are provided for the benefit of memory debugging tools like
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
412 Valgrind. */
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
413
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
414 /* Allocate space for a Bigint with up to 1<<k digits */
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
415
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
416 static Bigint *
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
417 Balloc(int k)
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
418 {
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
419 int x;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
420 Bigint *rv;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
421 unsigned int len;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
422
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
423 x = 1 << k;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
424 len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1)
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
425 /sizeof(double);
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
426
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
427 rv = (Bigint*)MALLOC(len*sizeof(double));
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
428 if (rv == NULL)
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
429 return NULL;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
430
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
431 rv->k = k;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
432 rv->maxwds = x;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
433 rv->sign = rv->wds = 0;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
434 return rv;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
435 }
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
436
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
437 /* Free a Bigint allocated with Balloc */
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
438
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
439 static void
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
440 Bfree(Bigint *v)
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
441 {
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
442 if (v) {
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
443 FREE((void*)v);
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
444 }
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
445 }
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
446
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
447 #endif /* Py_USING_MEMORY_DEBUGGER */
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
448
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
449 #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
450 y->wds*sizeof(Long) + 2*sizeof(int))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
451
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
452 /* Multiply a Bigint b by m and add a. Either modifies b in place and returns
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
453 a pointer to the modified b, or Bfrees b and returns a pointer to a copy.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
454 On failure, return NULL. In this case, b will have been already freed. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
455
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
456 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
457 multadd(Bigint *b, int m, int a) /* multiply by m and add a */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
458 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
459 int i, wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
460 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
461 ULong *x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
462 ULLong carry, y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
463 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
464 ULong carry, *x, y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
465 ULong xi, z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
466 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
467 Bigint *b1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
468
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
469 wds = b->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
470 x = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
471 i = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
472 carry = a;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
473 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
474 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
475 y = *x * (ULLong)m + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
476 carry = y >> 32;
53207
fe99a562b708 Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents: 53203
diff changeset
477 *x++ = (ULong)(y & FFFFFFFF);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
478 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
479 xi = *x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
480 y = (xi & 0xffff) * m + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
481 z = (xi >> 16) * m + (y >> 16);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
482 carry = z >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
483 *x++ = (z << 16) + (y & 0xffff);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
484 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
485 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
486 while(++i < wds);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
487 if (carry) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
488 if (wds >= b->maxwds) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
489 b1 = Balloc(b->k+1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
490 if (b1 == NULL){
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
491 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
492 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
493 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
494 Bcopy(b1, b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
495 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
496 b = b1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
497 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
498 b->x[wds++] = (ULong)carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
499 b->wds = wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
500 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
501 return b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
502 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
503
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
504 /* convert a string s containing nd decimal digits (possibly containing a
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
505 decimal separator at position nd0, which is ignored) to a Bigint. This
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
506 function carries on where the parsing code in _Py_dg_strtod leaves off: on
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
507 entry, y9 contains the result of converting the first 9 digits. Returns
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
508 NULL on failure. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
509
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
510 static Bigint *
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
511 s2b(const char *s, int nd0, int nd, ULong y9)
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
512 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
513 Bigint *b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
514 int i, k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
515 Long x, y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
516
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
517 x = (nd + 8) / 9;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
518 for(k = 0, y = 1; x > y; y <<= 1, k++) ;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
519 b = Balloc(k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
520 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
521 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
522 b->x[0] = y9;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
523 b->wds = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
524
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
525 if (nd <= 9)
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
526 return b;
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
527
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
528 s += 9;
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
529 for (i = 9; i < nd0; i++) {
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
530 b = multadd(b, 10, *s++ - '0');
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
531 if (b == NULL)
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
532 return NULL;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
533 }
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
534 s++;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
535 for(; i < nd; i++) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
536 b = multadd(b, 10, *s++ - '0');
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
537 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
538 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
539 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
540 return b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
541 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
542
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
543 /* count leading 0 bits in the 32-bit integer x. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
544
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
545 static int
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
546 hi0bits(ULong x)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
547 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
548 int k = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
549
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
550 if (!(x & 0xffff0000)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
551 k = 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
552 x <<= 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
553 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
554 if (!(x & 0xff000000)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
555 k += 8;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
556 x <<= 8;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
557 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
558 if (!(x & 0xf0000000)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
559 k += 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
560 x <<= 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
561 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
562 if (!(x & 0xc0000000)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
563 k += 2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
564 x <<= 2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
565 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
566 if (!(x & 0x80000000)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
567 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
568 if (!(x & 0x40000000))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
569 return 32;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
570 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
571 return k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
572 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
573
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
574 /* count trailing 0 bits in the 32-bit integer y, and shift y right by that
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
575 number of bits. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
576
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
577 static int
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
578 lo0bits(ULong *y)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
579 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
580 int k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
581 ULong x = *y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
582
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
583 if (x & 7) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
584 if (x & 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
585 return 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
586 if (x & 2) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
587 *y = x >> 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
588 return 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
589 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
590 *y = x >> 2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
591 return 2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
592 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
593 k = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
594 if (!(x & 0xffff)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
595 k = 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
596 x >>= 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
597 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
598 if (!(x & 0xff)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
599 k += 8;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
600 x >>= 8;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
601 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
602 if (!(x & 0xf)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
603 k += 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
604 x >>= 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
605 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
606 if (!(x & 0x3)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
607 k += 2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
608 x >>= 2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
609 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
610 if (!(x & 1)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
611 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
612 x >>= 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
613 if (!x)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
614 return 32;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
615 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
616 *y = x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
617 return k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
618 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
619
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
620 /* convert a small nonnegative integer to a Bigint */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
621
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
622 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
623 i2b(int i)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
624 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
625 Bigint *b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
626
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
627 b = Balloc(1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
628 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
629 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
630 b->x[0] = i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
631 b->wds = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
632 return b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
633 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
634
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
635 /* multiply two Bigints. Returns a new Bigint, or NULL on failure. Ignores
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
636 the signs of a and b. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
637
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
638 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
639 mult(Bigint *a, Bigint *b)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
640 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
641 Bigint *c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
642 int k, wa, wb, wc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
643 ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
644 ULong y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
645 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
646 ULLong carry, z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
647 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
648 ULong carry, z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
649 ULong z2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
650 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
651
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
652 if ((!a->x[0] && a->wds == 1) || (!b->x[0] && b->wds == 1)) {
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
653 c = Balloc(0);
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
654 if (c == NULL)
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
655 return NULL;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
656 c->wds = 1;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
657 c->x[0] = 0;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
658 return c;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
659 }
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
660
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
661 if (a->wds < b->wds) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
662 c = a;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
663 a = b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
664 b = c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
665 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
666 k = a->k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
667 wa = a->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
668 wb = b->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
669 wc = wa + wb;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
670 if (wc > a->maxwds)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
671 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
672 c = Balloc(k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
673 if (c == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
674 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
675 for(x = c->x, xa = x + wc; x < xa; x++)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
676 *x = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
677 xa = a->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
678 xae = xa + wa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
679 xb = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
680 xbe = xb + wb;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
681 xc0 = c->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
682 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
683 for(; xb < xbe; xc0++) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
684 if ((y = *xb++)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
685 x = xa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
686 xc = xc0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
687 carry = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
688 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
689 z = *x++ * (ULLong)y + *xc + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
690 carry = z >> 32;
53207
fe99a562b708 Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents: 53203
diff changeset
691 *xc++ = (ULong)(z & FFFFFFFF);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
692 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
693 while(x < xae);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
694 *xc = (ULong)carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
695 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
696 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
697 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
698 for(; xb < xbe; xb++, xc0++) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
699 if (y = *xb & 0xffff) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
700 x = xa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
701 xc = xc0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
702 carry = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
703 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
704 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
705 carry = z >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
706 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
707 carry = z2 >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
708 Storeinc(xc, z2, z);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
709 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
710 while(x < xae);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
711 *xc = carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
712 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
713 if (y = *xb >> 16) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
714 x = xa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
715 xc = xc0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
716 carry = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
717 z2 = *xc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
718 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
719 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
720 carry = z >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
721 Storeinc(xc, z, z2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
722 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
723 carry = z2 >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
724 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
725 while(x < xae);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
726 *xc = z2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
727 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
728 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
729 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
730 for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
731 c->wds = wc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
732 return c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
733 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
734
58402
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
735 #ifndef Py_USING_MEMORY_DEBUGGER
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
736
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
737 /* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
738
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
739 static Bigint *p5s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
740
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
741 /* multiply the Bigint b by 5**k. Returns a pointer to the result, or NULL on
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
742 failure; if the returned pointer is distinct from b then the original
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
743 Bigint b will have been Bfree'd. Ignores the sign of b. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
744
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
745 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
746 pow5mult(Bigint *b, int k)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
747 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
748 Bigint *b1, *p5, *p51;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
749 int i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
750 static int p05[3] = { 5, 25, 125 };
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
751
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
752 if ((i = k & 3)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
753 b = multadd(b, p05[i-1], 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
754 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
755 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
756 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
757
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
758 if (!(k >>= 2))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
759 return b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
760 p5 = p5s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
761 if (!p5) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
762 /* first time */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
763 p5 = i2b(625);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
764 if (p5 == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
765 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
766 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
767 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
768 p5s = p5;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
769 p5->next = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
770 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
771 for(;;) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
772 if (k & 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
773 b1 = mult(b, p5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
774 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
775 b = b1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
776 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
777 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
778 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
779 if (!(k >>= 1))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
780 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
781 p51 = p5->next;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
782 if (!p51) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
783 p51 = mult(p5,p5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
784 if (p51 == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
785 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
786 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
787 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
788 p51->next = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
789 p5->next = p51;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
790 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
791 p5 = p51;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
792 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
793 return b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
794 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
795
58402
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
796 #else
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
797
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
798 /* Version of pow5mult that doesn't cache powers of 5. Provided for
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
799 the benefit of memory debugging tools like Valgrind. */
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
800
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
801 static Bigint *
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
802 pow5mult(Bigint *b, int k)
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
803 {
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
804 Bigint *b1, *p5, *p51;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
805 int i;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
806 static int p05[3] = { 5, 25, 125 };
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
807
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
808 if ((i = k & 3)) {
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
809 b = multadd(b, p05[i-1], 0);
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
810 if (b == NULL)
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
811 return NULL;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
812 }
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
813
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
814 if (!(k >>= 2))
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
815 return b;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
816 p5 = i2b(625);
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
817 if (p5 == NULL) {
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
818 Bfree(b);
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
819 return NULL;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
820 }
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
821
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
822 for(;;) {
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
823 if (k & 1) {
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
824 b1 = mult(b, p5);
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
825 Bfree(b);
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
826 b = b1;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
827 if (b == NULL) {
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
828 Bfree(p5);
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
829 return NULL;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
830 }
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
831 }
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
832 if (!(k >>= 1))
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
833 break;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
834 p51 = mult(p5, p5);
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
835 Bfree(p5);
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
836 p5 = p51;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
837 if (p5 == NULL) {
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
838 Bfree(b);
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
839 return NULL;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
840 }
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
841 }
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
842 Bfree(p5);
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
843 return b;
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
844 }
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
845
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
846 #endif /* Py_USING_MEMORY_DEBUGGER */
3e629471850a Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58391
diff changeset
847
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
848 /* shift a Bigint b left by k bits. Return a pointer to the shifted result,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
849 or NULL on failure. If the returned pointer is distinct from b then the
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
850 original b will have been Bfree'd. Ignores the sign of b. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
851
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
852 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
853 lshift(Bigint *b, int k)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
854 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
855 int i, k1, n, n1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
856 Bigint *b1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
857 ULong *x, *x1, *xe, z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
858
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
859 if (!k || (!b->x[0] && b->wds == 1))
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
860 return b;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
861
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
862 n = k >> 5;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
863 k1 = b->k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
864 n1 = n + b->wds + 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
865 for(i = b->maxwds; n1 > i; i <<= 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
866 k1++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
867 b1 = Balloc(k1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
868 if (b1 == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
869 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
870 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
871 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
872 x1 = b1->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
873 for(i = 0; i < n; i++)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
874 *x1++ = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
875 x = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
876 xe = x + b->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
877 if (k &= 0x1f) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
878 k1 = 32 - k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
879 z = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
880 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
881 *x1++ = *x << k | z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
882 z = *x++ >> k1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
883 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
884 while(x < xe);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
885 if ((*x1 = z))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
886 ++n1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
887 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
888 else do
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
889 *x1++ = *x++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
890 while(x < xe);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
891 b1->wds = n1 - 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
892 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
893 return b1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
894 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
895
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
896 /* Do a three-way compare of a and b, returning -1 if a < b, 0 if a == b and
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
897 1 if a > b. Ignores signs of a and b. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
898
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
899 static int
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
900 cmp(Bigint *a, Bigint *b)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
901 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
902 ULong *xa, *xa0, *xb, *xb0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
903 int i, j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
904
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
905 i = a->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
906 j = b->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
907 #ifdef DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
908 if (i > 1 && !a->x[i-1])
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
909 Bug("cmp called with a->x[a->wds-1] == 0");
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
910 if (j > 1 && !b->x[j-1])
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
911 Bug("cmp called with b->x[b->wds-1] == 0");
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
912 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
913 if (i -= j)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
914 return i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
915 xa0 = a->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
916 xa = xa0 + j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
917 xb0 = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
918 xb = xb0 + j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
919 for(;;) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
920 if (*--xa != *--xb)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
921 return *xa < *xb ? -1 : 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
922 if (xa <= xa0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
923 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
924 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
925 return 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
926 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
927
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
928 /* Take the difference of Bigints a and b, returning a new Bigint. Returns
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
929 NULL on failure. The signs of a and b are ignored, but the sign of the
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
930 result is set appropriately. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
931
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
932 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
933 diff(Bigint *a, Bigint *b)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
934 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
935 Bigint *c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
936 int i, wa, wb;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
937 ULong *xa, *xae, *xb, *xbe, *xc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
938 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
939 ULLong borrow, y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
940 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
941 ULong borrow, y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
942 ULong z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
943 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
944
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
945 i = cmp(a,b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
946 if (!i) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
947 c = Balloc(0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
948 if (c == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
949 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
950 c->wds = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
951 c->x[0] = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
952 return c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
953 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
954 if (i < 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
955 c = a;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
956 a = b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
957 b = c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
958 i = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
959 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
960 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
961 i = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
962 c = Balloc(a->k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
963 if (c == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
964 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
965 c->sign = i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
966 wa = a->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
967 xa = a->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
968 xae = xa + wa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
969 wb = b->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
970 xb = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
971 xbe = xb + wb;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
972 xc = c->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
973 borrow = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
974 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
975 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
976 y = (ULLong)*xa++ - *xb++ - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
977 borrow = y >> 32 & (ULong)1;
53207
fe99a562b708 Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents: 53203
diff changeset
978 *xc++ = (ULong)(y & FFFFFFFF);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
979 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
980 while(xb < xbe);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
981 while(xa < xae) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
982 y = *xa++ - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
983 borrow = y >> 32 & (ULong)1;
53207
fe99a562b708 Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents: 53203
diff changeset
984 *xc++ = (ULong)(y & FFFFFFFF);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
985 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
986 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
987 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
988 y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
989 borrow = (y & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
990 z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
991 borrow = (z & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
992 Storeinc(xc, z, y);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
993 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
994 while(xb < xbe);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
995 while(xa < xae) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
996 y = (*xa & 0xffff) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
997 borrow = (y & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
998 z = (*xa++ >> 16) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
999 borrow = (z & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1000 Storeinc(xc, z, y);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1001 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1002 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1003 while(!*--xc)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1004 wa--;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1005 c->wds = wa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1006 return c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1007 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1008
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1009 /* Given a positive normal double x, return the difference between x and the
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1010 next double up. Doesn't give correct results for subnormals. */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1011
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1012 static double
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1013 ulp(U *x)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1014 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1015 Long L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1016 U u;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1017
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1018 L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1019 word0(&u) = L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1020 word1(&u) = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1021 return dval(&u);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1022 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1023
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1024 /* Convert a Bigint to a double plus an exponent */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1025
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1026 static double
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1027 b2d(Bigint *a, int *e)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1028 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1029 ULong *xa, *xa0, w, y, z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1030 int k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1031 U d;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1032
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1033 xa0 = a->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1034 xa = xa0 + a->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1035 y = *--xa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1036 #ifdef DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1037 if (!y) Bug("zero y in b2d");
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1038 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1039 k = hi0bits(y);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1040 *e = 32 - k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1041 if (k < Ebits) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1042 word0(&d) = Exp_1 | y >> (Ebits - k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1043 w = xa > xa0 ? *--xa : 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1044 word1(&d) = y << ((32-Ebits) + k) | w >> (Ebits - k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1045 goto ret_d;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1046 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1047 z = xa > xa0 ? *--xa : 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1048 if (k -= Ebits) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1049 word0(&d) = Exp_1 | y << k | z >> (32 - k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1050 y = xa > xa0 ? *--xa : 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1051 word1(&d) = z << k | y >> (32 - k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1052 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1053 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1054 word0(&d) = Exp_1 | y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1055 word1(&d) = z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1056 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1057 ret_d:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1058 return dval(&d);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1059 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1060
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1061 /* Convert a scaled double to a Bigint plus an exponent. Similar to d2b,
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1062 except that it accepts the scale parameter used in _Py_dg_strtod (which
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1063 should be either 0 or 2*P), and the normalization for the return value is
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1064 different (see below). On input, d should be finite and nonnegative, and d
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1065 / 2**scale should be exactly representable as an IEEE 754 double.
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1066
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1067 Returns a Bigint b and an integer e such that
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1068
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1069 dval(d) / 2**scale = b * 2**e.
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1070
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1071 Unlike d2b, b is not necessarily odd: b and e are normalized so
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1072 that either 2**(P-1) <= b < 2**P and e >= Etiny, or b < 2**P
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1073 and e == Etiny. This applies equally to an input of 0.0: in that
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1074 case the return values are b = 0 and e = Etiny.
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1075
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1076 The above normalization ensures that for all possible inputs d,
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1077 2**e gives ulp(d/2**scale).
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1078
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1079 Returns NULL on failure.
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1080 */
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1081
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1082 static Bigint *
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1083 sd2b(U *d, int scale, int *e)
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1084 {
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1085 Bigint *b;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1086
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1087 b = Balloc(1);
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1088 if (b == NULL)
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1089 return NULL;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1090
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1091 /* First construct b and e assuming that scale == 0. */
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1092 b->wds = 2;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1093 b->x[0] = word1(d);
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1094 b->x[1] = word0(d) & Frac_mask;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1095 *e = Etiny - 1 + (int)((word0(d) & Exp_mask) >> Exp_shift);
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1096 if (*e < Etiny)
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1097 *e = Etiny;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1098 else
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1099 b->x[1] |= Exp_msk1;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1100
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1101 /* Now adjust for scale, provided that b != 0. */
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1102 if (scale && (b->x[0] || b->x[1])) {
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1103 *e -= scale;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1104 if (*e < Etiny) {
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1105 scale = Etiny - *e;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1106 *e = Etiny;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1107 /* We can't shift more than P-1 bits without shifting out a 1. */
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1108 assert(0 < scale && scale <= P - 1);
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1109 if (scale >= 32) {
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1110 /* The bits shifted out should all be zero. */
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1111 assert(b->x[0] == 0);
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1112 b->x[0] = b->x[1];
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1113 b->x[1] = 0;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1114 scale -= 32;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1115 }
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1116 if (scale) {
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1117 /* The bits shifted out should all be zero. */
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1118 assert(b->x[0] << (32 - scale) == 0);
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1119 b->x[0] = (b->x[0] >> scale) | (b->x[1] << (32 - scale));
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1120 b->x[1] >>= scale;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1121 }
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1122 }
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1123 }
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1124 /* Ensure b is normalized. */
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1125 if (!b->x[1])
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1126 b->wds = 1;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1127
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1128 return b;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1129 }
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1130
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1131 /* Convert a double to a Bigint plus an exponent. Return NULL on failure.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1132
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1133 Given a finite nonzero double d, return an odd Bigint b and exponent *e
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1134 such that fabs(d) = b * 2**e. On return, *bbits gives the number of
58154
70f6fa3084e6 Merged revisions 77304 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 54232
diff changeset
1135 significant bits of b; that is, 2**(*bbits-1) <= b < 2**(*bbits).
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1136
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1137 If d is zero, then b == 0, *e == -1010, *bbits = 0.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1138 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1139
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1140 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1141 d2b(U *d, int *e, int *bits)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1142 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1143 Bigint *b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1144 int de, k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1145 ULong *x, y, z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1146 int i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1147
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1148 b = Balloc(1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1149 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1150 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1151 x = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1152
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1153 z = word0(d) & Frac_mask;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1154 word0(d) &= 0x7fffffff; /* clear sign bit, which we ignore */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1155 if ((de = (int)(word0(d) >> Exp_shift)))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1156 z |= Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1157 if ((y = word1(d))) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1158 if ((k = lo0bits(&y))) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1159 x[0] = y | z << (32 - k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1160 z >>= k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1161 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1162 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1163 x[0] = y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1164 i =
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1165 b->wds = (x[1] = z) ? 2 : 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1166 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1167 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1168 k = lo0bits(&z);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1169 x[0] = z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1170 i =
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1171 b->wds = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1172 k += 32;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1173 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1174 if (de) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1175 *e = de - Bias - (P-1) + k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1176 *bits = P - k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1177 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1178 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1179 *e = de - Bias - (P-1) + 1 + k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1180 *bits = 32*i - hi0bits(x[i-1]);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1181 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1182 return b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1183 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1184
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1185 /* Compute the ratio of two Bigints, as a double. The result may have an
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1186 error of up to 2.5 ulps. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1187
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1188 static double
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1189 ratio(Bigint *a, Bigint *b)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1190 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1191 U da, db;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1192 int k, ka, kb;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1193
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1194 dval(&da) = b2d(a, &ka);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1195 dval(&db) = b2d(b, &kb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1196 k = ka - kb + 32*(a->wds - b->wds);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1197 if (k > 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1198 word0(&da) += k*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1199 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1200 k = -k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1201 word0(&db) += k*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1202 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1203 return dval(&da) / dval(&db);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1204 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1205
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1206 static const double
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1207 tens[] = {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1208 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1209 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1210 1e20, 1e21, 1e22
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1211 };
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1212
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1213 static const double
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1214 bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1215 static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1216 9007199254740992.*9007199254740992.e-256
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1217 /* = 2^106 * 1e-256 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1218 };
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1219 /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1220 /* flag unnecessarily. It leads to a song and dance at the end of strtod. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1221 #define Scale_Bit 0x10
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1222 #define n_bigtens 5
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1223
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1224 #define ULbits 32
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1225 #define kshift 5
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1226 #define kmask 31
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1227
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1228
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1229 static int
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1230 dshift(Bigint *b, int p2)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1231 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1232 int rv = hi0bits(b->x[b->wds-1]) - 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1233 if (p2 > 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1234 rv -= p2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1235 return rv & kmask;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1236 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1237
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1238 /* special case of Bigint division. The quotient is always in the range 0 <=
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1239 quotient < 10, and on entry the divisor S is normalized so that its top 4
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1240 bits (28--31) are zero and bit 27 is set. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1241
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1242 static int
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1243 quorem(Bigint *b, Bigint *S)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1244 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1245 int n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1246 ULong *bx, *bxe, q, *sx, *sxe;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1247 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1248 ULLong borrow, carry, y, ys;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1249 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1250 ULong borrow, carry, y, ys;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1251 ULong si, z, zs;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1252 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1253
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1254 n = S->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1255 #ifdef DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1256 /*debug*/ if (b->wds > n)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1257 /*debug*/ Bug("oversize b in quorem");
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1258 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1259 if (b->wds < n)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1260 return 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1261 sx = S->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1262 sxe = sx + --n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1263 bx = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1264 bxe = bx + n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1265 q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1266 #ifdef DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1267 /*debug*/ if (q > 9)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1268 /*debug*/ Bug("oversized quotient in quorem");
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1269 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1270 if (q) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1271 borrow = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1272 carry = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1273 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1274 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1275 ys = *sx++ * (ULLong)q + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1276 carry = ys >> 32;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1277 y = *bx - (ys & FFFFFFFF) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1278 borrow = y >> 32 & (ULong)1;
53207
fe99a562b708 Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents: 53203
diff changeset
1279 *bx++ = (ULong)(y & FFFFFFFF);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1280 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1281 si = *sx++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1282 ys = (si & 0xffff) * q + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1283 zs = (si >> 16) * q + (ys >> 16);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1284 carry = zs >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1285 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1286 borrow = (y & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1287 z = (*bx >> 16) - (zs & 0xffff) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1288 borrow = (z & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1289 Storeinc(bx, z, y);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1290 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1291 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1292 while(sx <= sxe);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1293 if (!*bxe) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1294 bx = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1295 while(--bxe > bx && !*bxe)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1296 --n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1297 b->wds = n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1298 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1299 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1300 if (cmp(b, S) >= 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1301 q++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1302 borrow = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1303 carry = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1304 bx = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1305 sx = S->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1306 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1307 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1308 ys = *sx++ + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1309 carry = ys >> 32;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1310 y = *bx - (ys & FFFFFFFF) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1311 borrow = y >> 32 & (ULong)1;
53207
fe99a562b708 Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents: 53203
diff changeset
1312 *bx++ = (ULong)(y & FFFFFFFF);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1313 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1314 si = *sx++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1315 ys = (si & 0xffff) + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1316 zs = (si >> 16) + (ys >> 16);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1317 carry = zs >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1318 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1319 borrow = (y & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1320 z = (*bx >> 16) - (zs & 0xffff) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1321 borrow = (z & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1322 Storeinc(bx, z, y);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1323 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1324 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1325 while(sx <= sxe);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1326 bx = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1327 bxe = bx + n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1328 if (!*bxe) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1329 while(--bxe > bx && !*bxe)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1330 --n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1331 b->wds = n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1332 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1333 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1334 return q;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1335 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1336
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1337 /* sulp(x) is a version of ulp(x) that takes bc.scale into account.
58279
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1338
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1339 Assuming that x is finite and nonnegative (positive zero is fine
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1340 here) and x / 2^bc.scale is exactly representable as a double,
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1341 sulp(x) is equivalent to 2^bc.scale * ulp(x / 2^bc.scale). */
58279
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1342
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1343 static double
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1344 sulp(U *x, BCinfo *bc)
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1345 {
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1346 U u;
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1347
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1348 if (bc->scale && 2*P + 1 > (int)((word0(x) & Exp_mask) >> Exp_shift)) {
58279
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1349 /* rv/2^bc->scale is subnormal */
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1350 word0(&u) = (P+2)*Exp_msk1;
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1351 word1(&u) = 0;
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1352 return u.d;
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1353 }
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1354 else {
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1355 assert(word0(x) || word1(x)); /* x != 0.0 */
58279
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1356 return ulp(x);
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1357 }
58279
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1358 }
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1359
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1360 /* The bigcomp function handles some hard cases for strtod, for inputs
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1361 with more than STRTOD_DIGLIM digits. It's called once an initial
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1362 estimate for the double corresponding to the input string has
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1363 already been obtained by the code in _Py_dg_strtod.
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1364
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1365 The bigcomp function is only called after _Py_dg_strtod has found a
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1366 double value rv such that either rv or rv + 1ulp represents the
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1367 correctly rounded value corresponding to the original string. It
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1368 determines which of these two values is the correct one by
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1369 computing the decimal digits of rv + 0.5ulp and comparing them with
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1370 the corresponding digits of s0.
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1371
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1372 In the following, write dv for the absolute value of the number represented
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1373 by the input string.
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1374
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1375 Inputs:
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1376
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1377 s0 points to the first significant digit of the input string.
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1378
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1379 rv is a (possibly scaled) estimate for the closest double value to the
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1380 value represented by the original input to _Py_dg_strtod. If
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1381 bc->scale is nonzero, then rv/2^(bc->scale) is the approximation to
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1382 the input value.
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1383
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1384 bc is a struct containing information gathered during the parsing and
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1385 estimation steps of _Py_dg_strtod. Description of fields follows:
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1386
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1387 bc->e0 gives the exponent of the input value, such that dv = (integer
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1388 given by the bd->nd digits of s0) * 10**e0
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1389
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1390 bc->nd gives the total number of significant digits of s0. It will
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1391 be at least 1.
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1392
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1393 bc->nd0 gives the number of significant digits of s0 before the
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1394 decimal separator. If there's no decimal separator, bc->nd0 ==
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1395 bc->nd.
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1396
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1397 bc->scale is the value used to scale rv to avoid doing arithmetic with
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1398 subnormal values. It's either 0 or 2*P (=106).
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1399
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1400 Outputs:
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1401
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1402 On successful exit, rv/2^(bc->scale) is the closest double to dv.
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1403
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1404 Returns 0 on success, -1 on failure (e.g., due to a failed malloc call). */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1405
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1406 static int
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1407 bigcomp(U *rv, const char *s0, BCinfo *bc)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1408 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1409 Bigint *b, *d;
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1410 int b2, d2, dd, i, nd, nd0, odd, p2, p5;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1411
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1412 nd = bc->nd;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1413 nd0 = bc->nd0;
58279
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1414 p5 = nd + bc->e0;
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1415 b = sd2b(rv, bc->scale, &p2);
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1416 if (b == NULL)
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1417 return -1;
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1418
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1419 /* record whether the lsb of rv/2^(bc->scale) is odd: in the exact halfway
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1420 case, this is used for round to even. */
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1421 odd = b->x[0] & 1;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1422
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1423 /* left shift b by 1 bit and or a 1 into the least significant bit;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1424 this gives us b * 2**p2 = rv/2^(bc->scale) + 0.5 ulp. */
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1425 b = lshift(b, 1);
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1426 if (b == NULL)
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1427 return -1;
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1428 b->x[0] |= 1;
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1429 p2--;
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1430
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1431 p2 -= p5;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1432 d = i2b(1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1433 if (d == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1434 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1435 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1436 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1437 /* Arrange for convenient computation of quotients:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1438 * shift left if necessary so divisor has 4 leading 0 bits.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1439 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1440 if (p5 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1441 d = pow5mult(d, p5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1442 if (d == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1443 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1444 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1445 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1446 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1447 else if (p5 < 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1448 b = pow5mult(b, -p5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1449 if (b == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1450 Bfree(d);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1451 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1452 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1453 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1454 if (p2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1455 b2 = p2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1456 d2 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1457 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1458 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1459 b2 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1460 d2 = -p2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1461 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1462 i = dshift(d, d2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1463 if ((b2 += i) > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1464 b = lshift(b, b2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1465 if (b == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1466 Bfree(d);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1467 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1468 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1469 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1470 if ((d2 += i) > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1471 d = lshift(d, d2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1472 if (d == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1473 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1474 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1475 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1476 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1477
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1478 /* Compare s0 with b/d: set dd to -1, 0, or 1 according as s0 < b/d, s0 ==
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1479 * b/d, or s0 > b/d. Here the digits of s0 are thought of as representing
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1480 * a number in the range [0.1, 1). */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1481 if (cmp(b, d) >= 0)
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1482 /* b/d >= 1 */
58279
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1483 dd = -1;
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1484 else {
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1485 i = 0;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1486 for(;;) {
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1487 b = multadd(b, 10, 0);
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1488 if (b == NULL) {
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1489 Bfree(d);
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1490 return -1;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1491 }
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1492 dd = s0[i < nd0 ? i : i+1] - '0' - quorem(b, d);
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1493 i++;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1494
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1495 if (dd)
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1496 break;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1497 if (!b->x[0] && b->wds == 1) {
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1498 /* b/d == 0 */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1499 dd = i < nd;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1500 break;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1501 }
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1502 if (!(i < nd)) {
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1503 /* b/d != 0, but digits of s0 exhausted */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1504 dd = -1;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1505 break;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1506 }
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1507 }
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1508 }
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1509 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1510 Bfree(d);
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1511 if (dd > 0 || (dd == 0 && odd))
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1512 dval(rv) += sulp(rv, bc);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1513 return 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1514 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1515
76629
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1516 /* Return a 'standard' NaN value.
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1517
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1518 There are exactly two quiet NaNs that don't arise by 'quieting' signaling
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1519 NaNs (see IEEE 754-2008, section 6.2.1). If sign == 0, return the one whose
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1520 sign bit is cleared. Otherwise, return the one whose sign bit is set.
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1521 */
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1522
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1523 double
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1524 _Py_dg_stdnan(int sign)
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1525 {
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1526 U rv;
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1527 word0(&rv) = NAN_WORD0;
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1528 word1(&rv) = NAN_WORD1;
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1529 if (sign)
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1530 word0(&rv) |= Sign_bit;
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1531 return dval(&rv);
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1532 }
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1533
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1534 /* Return positive or negative infinity, according to the given sign (0 for
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1535 * positive infinity, 1 for negative infinity). */
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1536
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1537 double
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1538 _Py_dg_infinity(int sign)
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1539 {
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1540 U rv;
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1541 word0(&rv) = POSINF_WORD0;
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1542 word1(&rv) = POSINF_WORD1;
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1543 return sign ? -dval(&rv) : dval(&rv);
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1544 }
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1545
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1546 double
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1547 _Py_dg_strtod(const char *s00, char **se)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1548 {
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1549 int bb2, bb5, bbe, bd2, bd5, bs2, c, dsign, e, e1, error;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1550 int esign, i, j, k, lz, nd, nd0, odd, sign;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1551 const char *s, *s0, *s1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1552 double aadj, aadj1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1553 U aadj2, adj, rv, rv0;
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1554 ULong y, z, abs_exp;
58360
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1555 Long L;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1556 BCinfo bc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1557 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
87582
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1558 size_t ndigits, fraclen;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1559
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1560 dval(&rv) = 0.;
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1561
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1562 /* Start parsing. */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1563 c = *(s = s00);
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1564
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1565 /* Parse optional sign, if present. */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1566 sign = 0;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1567 switch (c) {
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1568 case '-':
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1569 sign = 1;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1570 /* no break */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1571 case '+':
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1572 c = *++s;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1573 }
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1574
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1575 /* Skip leading zeros: lz is true iff there were leading zeros. */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1576 s1 = s;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1577 while (c == '0')
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1578 c = *++s;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1579 lz = s != s1;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1580
87582
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1581 /* Point s0 at the first nonzero digit (if any). fraclen will be the
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1582 number of digits between the decimal point and the end of the
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1583 digit string. ndigits will be the total number of digits ignoring
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1584 leading zeros. */
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1585 s0 = s1 = s;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1586 while ('0' <= c && c <= '9')
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1587 c = *++s;
87582
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1588 ndigits = s - s1;
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1589 fraclen = 0;
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1590
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1591 /* Parse decimal point and following digits. */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1592 if (c == '.') {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1593 c = *++s;
87582
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1594 if (!ndigits) {
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1595 s1 = s;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1596 while (c == '0')
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1597 c = *++s;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1598 lz = lz || s != s1;
87582
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1599 fraclen += (s - s1);
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1600 s0 = s;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1601 }
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1602 s1 = s;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1603 while ('0' <= c && c <= '9')
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1604 c = *++s;
87582
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1605 ndigits += s - s1;
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1606 fraclen += s - s1;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1607 }
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1608
87582
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1609 /* Now lz is true if and only if there were leading zero digits, and
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1610 ndigits gives the total number of digits ignoring leading zeros. A
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1611 valid input must have at least one digit. */
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1612 if (!ndigits && !lz) {
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1613 if (se)
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1614 *se = (char *)s00;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1615 goto parse_error;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1616 }
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1617
87582
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1618 /* Range check ndigits and fraclen to make sure that they, and values
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1619 computed with them, can safely fit in an int. */
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1620 if (ndigits > MAX_DIGITS || fraclen > MAX_DIGITS) {
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1621 if (se)
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1622 *se = (char *)s00;
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1623 goto parse_error;
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1624 }
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1625 nd = (int)ndigits;
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1626 nd0 = (int)ndigits - (int)fraclen;
eac133e13bb5 Issue #19638: Raise ValueError instead of crashing when converting billion character strings to float.
Mark Dickinson <dickinsm@gmail.com>
parents: 76629
diff changeset
1627
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1628 /* Parse exponent. */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1629 e = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1630 if (c == 'e' || c == 'E') {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1631 s00 = s;
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1632 c = *++s;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1633
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1634 /* Exponent sign. */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1635 esign = 0;
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1636 switch (c) {
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1637 case '-':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1638 esign = 1;
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1639 /* no break */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1640 case '+':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1641 c = *++s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1642 }
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1643
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1644 /* Skip zeros. lz is true iff there are leading zeros. */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1645 s1 = s;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1646 while (c == '0')
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1647 c = *++s;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1648 lz = s != s1;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1649
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1650 /* Get absolute value of the exponent. */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1651 s1 = s;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1652 abs_exp = 0;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1653 while ('0' <= c && c <= '9') {
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1654 abs_exp = 10*abs_exp + (c - '0');
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1655 c = *++s;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1656 }
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1657
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1658 /* abs_exp will be correct modulo 2**32. But 10**9 < 2**32, so if
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1659 there are at most 9 significant exponent digits then overflow is
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1660 impossible. */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1661 if (s - s1 > 9 || abs_exp > MAX_ABS_EXP)
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1662 e = (int)MAX_ABS_EXP;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1663 else
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1664 e = (int)abs_exp;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1665 if (esign)
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1666 e = -e;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1667
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1668 /* A valid exponent must have at least one digit. */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1669 if (s == s1 && !lz)
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1670 s = s00;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1671 }
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1672
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1673 /* Adjust exponent to take into account position of the point. */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1674 e -= nd - nd0;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1675 if (nd0 <= 0)
58360
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1676 nd0 = nd;
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1677
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1678 /* Finished parsing. Set se to indicate how far we parsed */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1679 if (se)
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1680 *se = (char *)s;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1681
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1682 /* If all digits were zero, exit with return value +-0.0. Otherwise,
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1683 strip trailing zeros: scan back until we hit a nonzero digit. */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1684 if (!nd)
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1685 goto ret;
58360
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1686 for (i = nd; i > 0; ) {
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1687 --i;
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1688 if (s0[i < nd0 ? i : i+1] != '0') {
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1689 ++i;
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1690 break;
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1691 }
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1692 }
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1693 e += nd - i;
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1694 nd = i;
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1695 if (nd0 > nd)
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1696 nd0 = nd;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1697
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1698 /* Summary of parsing results. After parsing, and dealing with zero
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1699 * inputs, we have values s0, nd0, nd, e, sign, where:
58360
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1700 *
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1701 * - s0 points to the first significant digit of the input string
58360
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1702 *
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1703 * - nd is the total number of significant digits (here, and
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1704 * below, 'significant digits' means the set of digits of the
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1705 * significand of the input that remain after ignoring leading
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1706 * and trailing zeros).
58360
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1707 *
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1708 * - nd0 indicates the position of the decimal point, if present; it
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1709 * satisfies 1 <= nd0 <= nd. The nd significant digits are in
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1710 * s0[0:nd0] and s0[nd0+1:nd+1] using the usual Python half-open slice
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1711 * notation. (If nd0 < nd, then s0[nd0] contains a '.' character; if
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1712 * nd0 == nd, then s0[nd0] could be any non-digit character.)
58360
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1713 *
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1714 * - e is the adjusted exponent: the absolute value of the number
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1715 * represented by the original input string is n * 10**e, where
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1716 * n is the integer represented by the concatenation of
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1717 * s0[0:nd0] and s0[nd0+1:nd+1]
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1718 *
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1719 * - sign gives the sign of the input: 1 for negative, 0 for positive
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1720 *
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1721 * - the first and last significant digits are nonzero
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1722 */
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1723
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1724 /* put first DBL_DIG+1 digits into integer y and z.
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1725 *
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1726 * - y contains the value represented by the first min(9, nd)
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1727 * significant digits
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1728 *
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1729 * - if nd > 9, z contains the value represented by significant digits
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1730 * with indices in [9, min(16, nd)). So y * 10**(min(16, nd) - 9) + z
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1731 * gives the value represented by the first min(16, nd) sig. digits.
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1732 */
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1733
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1734 bc.e0 = e1 = e;
58360
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1735 y = z = 0;
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1736 for (i = 0; i < nd; i++) {
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1737 if (i < 9)
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1738 y = 10*y + s0[i < nd0 ? i : i+1] - '0';
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1739 else if (i < DBL_DIG+1)
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1740 z = 10*z + s0[i < nd0 ? i : i+1] - '0';
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1741 else
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1742 break;
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1743 }
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1744
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1745 k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1746 dval(&rv) = y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1747 if (k > 9) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1748 dval(&rv) = tens[k - 9] * dval(&rv) + z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1749 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1750 bd0 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1751 if (nd <= DBL_DIG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1752 && Flt_Rounds == 1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1753 ) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1754 if (!e)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1755 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1756 if (e > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1757 if (e <= Ten_pmax) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1758 dval(&rv) *= tens[e];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1759 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1760 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1761 i = DBL_DIG - nd;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1762 if (e <= Ten_pmax + i) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1763 /* A fancier test would sometimes let us do
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1764 * this for larger i values.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1765 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1766 e -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1767 dval(&rv) *= tens[i];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1768 dval(&rv) *= tens[e];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1769 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1770 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1771 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1772 else if (e >= -Ten_pmax) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1773 dval(&rv) /= tens[-e];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1774 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1775 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1776 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1777 e1 += nd - k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1778
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1779 bc.scale = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1780
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1781 /* Get starting approximation = rv * 10**e1 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1782
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1783 if (e1 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1784 if ((i = e1 & 15))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1785 dval(&rv) *= tens[i];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1786 if (e1 &= ~15) {
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1787 if (e1 > DBL_MAX_10_EXP)
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1788 goto ovfl;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1789 e1 >>= 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1790 for(j = 0; e1 > 1; j++, e1 >>= 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1791 if (e1 & 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1792 dval(&rv) *= bigtens[j];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1793 /* The last multiplication could overflow. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1794 word0(&rv) -= P*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1795 dval(&rv) *= bigtens[j];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1796 if ((z = word0(&rv) & Exp_mask)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1797 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1798 goto ovfl;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1799 if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1800 /* set to largest number */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1801 /* (Can't trust DBL_MAX) */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1802 word0(&rv) = Big0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1803 word1(&rv) = Big1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1804 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1805 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1806 word0(&rv) += P*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1807 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1808 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1809 else if (e1 < 0) {
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1810 /* The input decimal value lies in [10**e1, 10**(e1+16)).
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1811
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1812 If e1 <= -512, underflow immediately.
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1813 If e1 <= -256, set bc.scale to 2*P.
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1814
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1815 So for input value < 1e-256, bc.scale is always set;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1816 for input value >= 1e-240, bc.scale is never set.
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1817 For input values in [1e-256, 1e-240), bc.scale may or may
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1818 not be set. */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1819
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1820 e1 = -e1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1821 if ((i = e1 & 15))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1822 dval(&rv) /= tens[i];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1823 if (e1 >>= 4) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1824 if (e1 >= 1 << n_bigtens)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1825 goto undfl;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1826 if (e1 & Scale_Bit)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1827 bc.scale = 2*P;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1828 for(j = 0; e1 > 0; j++, e1 >>= 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1829 if (e1 & 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1830 dval(&rv) *= tinytens[j];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1831 if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1832 >> Exp_shift)) > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1833 /* scaled rv is denormal; clear j low bits */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1834 if (j >= 32) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1835 word1(&rv) = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1836 if (j >= 53)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1837 word0(&rv) = (P+2)*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1838 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1839 word0(&rv) &= 0xffffffff << (j-32);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1840 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1841 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1842 word1(&rv) &= 0xffffffff << j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1843 }
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1844 if (!dval(&rv))
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1845 goto undfl;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1846 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1847 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1848
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1849 /* Now the hard part -- adjusting rv to the correct value.*/
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1850
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1851 /* Put digits into bd: true value = bd * 10^e */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1852
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1853 bc.nd = nd;
58279
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1854 bc.nd0 = nd0; /* Only needed if nd > STRTOD_DIGLIM, but done here */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1855 /* to silence an erroneous warning about bc.nd0 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1856 /* possibly not being initialized. */
58279
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1857 if (nd > STRTOD_DIGLIM) {
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
1858 /* ASSERT(STRTOD_DIGLIM >= 18); 18 == one more than the */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1859 /* minimum number of decimal digits to distinguish double values */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1860 /* in IEEE arithmetic. */
58360
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1861
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1862 /* Truncate input to 18 significant digits, then discard any trailing
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1863 zeros on the result by updating nd, nd0, e and y suitably. (There's
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1864 no need to update z; it's not reused beyond this point.) */
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1865 for (i = 18; i > 0; ) {
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1866 /* scan back until we hit a nonzero digit. significant digit 'i'
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1867 is s0[i] if i < nd0, s0[i+1] if i >= nd0. */
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1868 --i;
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1869 if (s0[i < nd0 ? i : i+1] != '0') {
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1870 ++i;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1871 break;
58360
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1872 }
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1873 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1874 e += nd - i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1875 nd = i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1876 if (nd0 > nd)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1877 nd0 = nd;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1878 if (nd < 9) { /* must recompute y */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1879 y = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1880 for(i = 0; i < nd0; ++i)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1881 y = 10*y + s0[i] - '0';
58360
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1882 for(; i < nd; ++i)
6351d3d53ded Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58320
diff changeset
1883 y = 10*y + s0[i+1] - '0';
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1884 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1885 }
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
1886 bd0 = s2b(s0, nd0, nd, y);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1887 if (bd0 == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1888 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1889
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1890 /* Notation for the comments below. Write:
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1891
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1892 - dv for the absolute value of the number represented by the original
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1893 decimal input string.
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1894
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1895 - if we've truncated dv, write tdv for the truncated value.
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1896 Otherwise, set tdv == dv.
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1897
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1898 - srv for the quantity rv/2^bc.scale; so srv is the current binary
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1899 approximation to tdv (and dv). It should be exactly representable
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1900 in an IEEE 754 double.
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1901 */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1902
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1903 for(;;) {
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1904
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1905 /* This is the main correction loop for _Py_dg_strtod.
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1906
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1907 We've got a decimal value tdv, and a floating-point approximation
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1908 srv=rv/2^bc.scale to tdv. The aim is to determine whether srv is
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1909 close enough (i.e., within 0.5 ulps) to tdv, and to compute a new
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1910 approximation if not.
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1911
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1912 To determine whether srv is close enough to tdv, compute integers
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1913 bd, bb and bs proportional to tdv, srv and 0.5 ulp(srv)
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1914 respectively, and then use integer arithmetic to determine whether
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1915 |tdv - srv| is less than, equal to, or greater than 0.5 ulp(srv).
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1916 */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1917
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1918 bd = Balloc(bd0->k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1919 if (bd == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1920 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1921 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1922 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1923 Bcopy(bd, bd0);
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1924 bb = sd2b(&rv, bc.scale, &bbe); /* srv = bb * 2^bbe */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1925 if (bb == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1926 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1927 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1928 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1929 }
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1930 /* Record whether lsb of bb is odd, in case we need this
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1931 for the round-to-even step later. */
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1932 odd = bb->x[0] & 1;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1933
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1934 /* tdv = bd * 10**e; srv = bb * 2**bbe */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1935 bs = i2b(1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1936 if (bs == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1937 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1938 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1939 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1940 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1941 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1942
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1943 if (e >= 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1944 bb2 = bb5 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1945 bd2 = bd5 = e;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1946 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1947 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1948 bb2 = bb5 = -e;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1949 bd2 = bd5 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1950 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1951 if (bbe >= 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1952 bb2 += bbe;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1953 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1954 bd2 -= bbe;
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1955 bs2 = bb2;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1956 bb2++;
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1957 bd2++;
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1958
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1959 /* At this stage bd5 - bb5 == e == bd2 - bb2 + bbe, bb2 - bs2 == 1,
76629
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1960 and bs == 1, so:
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1961
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1962 tdv == bd * 10**e = bd * 2**(bbe - bb2 + bd2) * 5**(bd5 - bb5)
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1963 srv == bb * 2**bbe = bb * 2**(bbe - bb2 + bb2)
76629
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1964 0.5 ulp(srv) == 2**(bbe-1) = bs * 2**(bbe - bb2 + bs2)
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1965
76629
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1966 It follows that:
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1967
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1968 M * tdv = bd * 2**bd2 * 5**bd5
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1969 M * srv = bb * 2**bb2 * 5**bb5
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1970 M * 0.5 ulp(srv) = bs * 2**bs2 * 5**bb5
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1971
76629
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1972 for some constant M. (Actually, M == 2**(bb2 - bbe) * 5**bb5, but
c468511fc887 Issue #14521: Make result of float('nan') and float('-nan') more consistent across platforms. Further, don't rely on Py_HUGE_VAL for float('inf').
Mark Dickinson <mdickinson@enthought.com>
parents: 68102
diff changeset
1973 this fact is not needed below.)
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1974 */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1975
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
1976 /* Remove factor of 2**i, where i = min(bb2, bd2, bs2). */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1977 i = bb2 < bd2 ? bb2 : bd2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1978 if (i > bs2)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1979 i = bs2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1980 if (i > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1981 bb2 -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1982 bd2 -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1983 bs2 -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1984 }
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1985
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
1986 /* Scale bb, bd, bs by the appropriate powers of 2 and 5. */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1987 if (bb5 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1988 bs = pow5mult(bs, bb5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1989 if (bs == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1990 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1991 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1992 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1993 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1994 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1995 bb1 = mult(bs, bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1996 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1997 bb = bb1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1998 if (bb == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1999 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2000 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2001 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2002 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2003 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2004 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2005 if (bb2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2006 bb = lshift(bb, bb2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2007 if (bb == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2008 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2009 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2010 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2011 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2012 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2013 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2014 if (bd5 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2015 bd = pow5mult(bd, bd5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2016 if (bd == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2017 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2018 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2019 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2020 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2021 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2022 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2023 if (bd2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2024 bd = lshift(bd, bd2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2025 if (bd == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2026 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2027 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2028 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2029 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2030 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2031 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2032 if (bs2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2033 bs = lshift(bs, bs2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2034 if (bs == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2035 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2036 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2037 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2038 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2039 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2040 }
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2041
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2042 /* Now bd, bb and bs are scaled versions of tdv, srv and 0.5 ulp(srv),
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2043 respectively. Compute the difference |tdv - srv|, and compare
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2044 with 0.5 ulp(srv). */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2045
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2046 delta = diff(bb, bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2047 if (delta == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2048 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2049 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2050 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2051 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2052 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2053 }
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2054 dsign = delta->sign;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2055 delta->sign = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2056 i = cmp(delta, bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2057 if (bc.nd > nd && i <= 0) {
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2058 if (dsign)
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2059 break; /* Must use bigcomp(). */
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2060
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2061 /* Here rv overestimates the truncated decimal value by at most
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2062 0.5 ulp(rv). Hence rv either overestimates the true decimal
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2063 value by <= 0.5 ulp(rv), or underestimates it by some small
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2064 amount (< 0.1 ulp(rv)); either way, rv is within 0.5 ulps of
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2065 the true decimal value, so it's possible to exit.
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2066
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2067 Exception: if scaled rv is a normal exact power of 2, but not
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2068 DBL_MIN, then rv - 0.5 ulp(rv) takes us all the way down to the
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2069 next double, so the correctly rounded result is either rv - 0.5
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2070 ulp(rv) or rv; in this case, use bigcomp to distinguish. */
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2071
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2072 if (!word1(&rv) && !(word0(&rv) & Bndry_mask)) {
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2073 /* rv can't be 0, since it's an overestimate for some
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2074 nonzero value. So rv is a normal power of 2. */
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2075 j = (int)(word0(&rv) & Exp_mask) >> Exp_shift;
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2076 /* rv / 2^bc.scale = 2^(j - 1023 - bc.scale); use bigcomp if
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2077 rv / 2^bc.scale >= 2^-1021. */
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2078 if (j - bc.scale >= 2) {
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2079 dval(&rv) -= 0.5 * sulp(&rv, &bc);
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2080 break; /* Use bigcomp. */
58320
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2081 }
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2082 }
ce11c1270b69 Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58279
diff changeset
2083
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2084 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2085 bc.nd = nd;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2086 i = -1; /* Discarded digits make delta smaller. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2087 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2088 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2089
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2090 if (i < 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2091 /* Error is less than half an ulp -- check for
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2092 * special case of mantissa a power of two.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2093 */
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2094 if (dsign || word1(&rv) || word0(&rv) & Bndry_mask
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2095 || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2096 ) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2097 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2098 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2099 if (!delta->x[0] && delta->wds <= 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2100 /* exact result */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2101 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2102 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2103 delta = lshift(delta,Log2P);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2104 if (delta == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2105 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2106 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2107 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2108 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2109 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2110 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2111 if (cmp(delta, bs) > 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2112 goto drop_down;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2113 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2114 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2115 if (i == 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2116 /* exactly half-way between */
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2117 if (dsign) {
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2118 if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2119 && word1(&rv) == (
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2120 (bc.scale &&
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2121 (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) ?
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2122 (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) :
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2123 0xffffffff)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2124 /*boundary case -- increment exponent*/
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2125 word0(&rv) = (word0(&rv) & Exp_mask)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2126 + Exp_msk1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2127 ;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2128 word1(&rv) = 0;
68102
e2f96bd29252 Issue #8914: fix various warnings from the Clang static analyzer v254.
Brett Cannon <bcannon@gmail.com>
parents: 61547
diff changeset
2129 /* dsign = 0; */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2130 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2131 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2132 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2133 else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2134 drop_down:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2135 /* boundary case -- decrement exponent */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2136 if (bc.scale) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2137 L = word0(&rv) & Exp_mask;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2138 if (L <= (2*P+1)*Exp_msk1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2139 if (L > (P+2)*Exp_msk1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2140 /* round even ==> */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2141 /* accept rv */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2142 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2143 /* rv = smallest denormal */
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2144 if (bc.nd > nd)
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2145 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2146 goto undfl;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2147 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2148 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2149 L = (word0(&rv) & Exp_mask) - Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2150 word0(&rv) = L | Bndry_mask1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2151 word1(&rv) = 0xffffffff;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2152 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2153 }
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
2154 if (!odd)
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2155 break;
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2156 if (dsign)
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
2157 dval(&rv) += sulp(&rv, &bc);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2158 else {
58467
be12d3621519 Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58427
diff changeset
2159 dval(&rv) -= sulp(&rv, &bc);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2160 if (!dval(&rv)) {
58279
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
2161 if (bc.nd >nd)
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2162 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2163 goto undfl;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2164 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2165 }
68102
e2f96bd29252 Issue #8914: fix various warnings from the Clang static analyzer v254.
Brett Cannon <bcannon@gmail.com>
parents: 61547
diff changeset
2166 /* dsign = 1 - dsign; */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2167 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2168 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2169 if ((aadj = ratio(delta, bs)) <= 2.) {
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2170 if (dsign)
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2171 aadj = aadj1 = 1.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2172 else if (word1(&rv) || word0(&rv) & Bndry_mask) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2173 if (word1(&rv) == Tiny1 && !word0(&rv)) {
58279
c32d3b08fcdc Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58154
diff changeset
2174 if (bc.nd >nd)
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2175 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2176 goto undfl;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2177 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2178 aadj = 1.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2179 aadj1 = -1.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2180 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2181 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2182 /* special case -- power of FLT_RADIX to be */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2183 /* rounded down... */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2184
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2185 if (aadj < 2./FLT_RADIX)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2186 aadj = 1./FLT_RADIX;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2187 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2188 aadj *= 0.5;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2189 aadj1 = -aadj;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2190 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2191 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2192 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2193 aadj *= 0.5;
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2194 aadj1 = dsign ? aadj : -aadj;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2195 if (Flt_Rounds == 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2196 aadj1 += 0.5;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2197 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2198 y = word0(&rv) & Exp_mask;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2199
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2200 /* Check for overflow */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2201
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2202 if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2203 dval(&rv0) = dval(&rv);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2204 word0(&rv) -= P*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2205 adj.d = aadj1 * ulp(&rv);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2206 dval(&rv) += adj.d;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2207 if ((word0(&rv) & Exp_mask) >=
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2208 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
58391
b9888c1339df Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58360
diff changeset
2209 if (word0(&rv0) == Big0 && word1(&rv0) == Big1) {
b9888c1339df Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58360
diff changeset
2210 Bfree(bb);
b9888c1339df Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58360
diff changeset
2211 Bfree(bd);
b9888c1339df Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58360
diff changeset
2212 Bfree(bs);
b9888c1339df Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58360
diff changeset
2213 Bfree(bd0);
b9888c1339df Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58360
diff changeset
2214 Bfree(delta);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2215 goto ovfl;
58391
b9888c1339df Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58360
diff changeset
2216 }
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2217 word0(&rv) = Big0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2218 word1(&rv) = Big1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2219 goto cont;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2220 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2221 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2222 word0(&rv) += P*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2223 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2224 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2225 if (bc.scale && y <= 2*P*Exp_msk1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2226 if (aadj <= 0x7fffffff) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2227 if ((z = (ULong)aadj) <= 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2228 z = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2229 aadj = z;
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2230 aadj1 = dsign ? aadj : -aadj;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2231 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2232 dval(&aadj2) = aadj1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2233 word0(&aadj2) += (2*P+1)*Exp_msk1 - y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2234 aadj1 = dval(&aadj2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2235 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2236 adj.d = aadj1 * ulp(&rv);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2237 dval(&rv) += adj.d;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2238 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2239 z = word0(&rv) & Exp_mask;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2240 if (bc.nd == nd) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2241 if (!bc.scale)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2242 if (y == z) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2243 /* Can we stop now? */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2244 L = (Long)aadj;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2245 aadj -= L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2246 /* The tolerances below are conservative. */
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2247 if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) {
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2248 if (aadj < .4999999 || aadj > .5000001)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2249 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2250 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2251 else if (aadj < .4999999/FLT_RADIX)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2252 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2253 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2254 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2255 cont:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2256 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2257 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2258 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2259 Bfree(delta);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2260 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2261 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2262 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2263 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2264 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2265 Bfree(delta);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2266 if (bc.nd > nd) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2267 error = bigcomp(&rv, s0, &bc);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2268 if (error)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2269 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2270 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2271
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2272 if (bc.scale) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2273 word0(&rv0) = Exp_1 - 2*P*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2274 word1(&rv0) = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2275 dval(&rv) *= dval(&rv0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2276 }
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2277
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2278 ret:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2279 return sign ? -dval(&rv) : dval(&rv);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2280
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2281 parse_error:
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2282 return 0.0;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2283
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2284 failed_malloc:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2285 errno = ENOMEM;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2286 return -1.0;
58427
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2287
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2288 undfl:
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2289 return sign ? -0.0 : 0.0;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2290
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2291 ovfl:
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2292 errno = ERANGE;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2293 /* Can't trust HUGE_VAL */
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2294 word0(&rv) = Exp_mask;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2295 word1(&rv) = 0;
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2296 return sign ? -dval(&rv) : dval(&rv);
f38c1196d9ff Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents: 58402
diff changeset
2297
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2298 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2299
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2300 static char *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2301 rv_alloc(int i)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2302 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2303 int j, k, *r;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2304
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2305 j = sizeof(ULong);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2306 for(k = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2307 sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= (unsigned)i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2308 j <<= 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2309 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2310 r = (int*)Balloc(k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2311 if (r == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2312 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2313 *r = k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2314 return (char *)(r+1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2315 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2316
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2317 static char *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2318 nrv_alloc(char *s, char **rve, int n)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2319 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2320 char *rv, *t;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2321
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2322 rv = rv_alloc(n);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2323 if (rv == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2324 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2325 t = rv;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2326 while((*t = *s++)) t++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2327 if (rve)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2328 *rve = t;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2329 return rv;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2330 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2331
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2332 /* freedtoa(s) must be used to free values s returned by dtoa
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2333 * when MULTIPLE_THREADS is #defined. It should be used in all cases,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2334 * but for consistency with earlier versions of dtoa, it is optional
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2335 * when MULTIPLE_THREADS is not defined.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2336 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2337
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2338 void
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2339 _Py_dg_freedtoa(char *s)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2340 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2341 Bigint *b = (Bigint *)((int *)s - 1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2342 b->maxwds = 1 << (b->k = *(int*)b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2343 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2344 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2345
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2346 /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2347 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2348 * Inspired by "How to Print Floating-Point Numbers Accurately" by
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2349 * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2350 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2351 * Modifications:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2352 * 1. Rather than iterating, we use a simple numeric overestimate
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2353 * to determine k = floor(log10(d)). We scale relevant
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2354 * quantities using O(log2(k)) rather than O(k) multiplications.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2355 * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2356 * try to generate digits strictly left to right. Instead, we
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2357 * compute with fewer bits and propagate the carry if necessary
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2358 * when rounding the final digit up. This is often faster.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2359 * 3. Under the assumption that input will be rounded nearest,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2360 * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2361 * That is, we allow equality in stopping tests when the
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2362 * round-nearest rule will give the same floating-point value
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2363 * as would satisfaction of the stopping test with strict
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2364 * inequality.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2365 * 4. We remove common factors of powers of 2 from relevant
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2366 * quantities.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2367 * 5. When converting floating-point integers less than 1e16,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2368 * we use floating-point arithmetic rather than resorting
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2369 * to multiple-precision integers.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2370 * 6. When asked to produce fewer than 15 digits, we first try
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2371 * to get by with floating-point arithmetic; we resort to
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2372 * multiple-precision integer arithmetic only if we cannot
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2373 * guarantee that the floating-point calculation has given
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2374 * the correctly rounded result. For k requested digits and
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2375 * "uniformly" distributed input, the probability is
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2376 * something like 10^(k-15) that we must resort to the Long
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2377 * calculation.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2378 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2379
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2380 /* Additional notes (METD): (1) returns NULL on failure. (2) to avoid memory
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2381 leakage, a successful call to _Py_dg_dtoa should always be matched by a
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2382 call to _Py_dg_freedtoa. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2383
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2384 char *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2385 _Py_dg_dtoa(double dd, int mode, int ndigits,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2386 int *decpt, int *sign, char **rve)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2387 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2388 /* Arguments ndigits, decpt, sign are similar to those
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2389 of ecvt and fcvt; trailing zeros are suppressed from
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2390 the returned string. If not null, *rve is set to point
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2391 to the end of the return value. If d is +-Infinity or NaN,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2392 then *decpt is set to 9999.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2393
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2394 mode:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2395 0 ==> shortest string that yields d when read in
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2396 and rounded to nearest.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2397 1 ==> like 0, but with Steele & White stopping rule;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2398 e.g. with IEEE P754 arithmetic , mode 0 gives
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2399 1e23 whereas mode 1 gives 9.999999999999999e22.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2400 2 ==> max(1,ndigits) significant digits. This gives a
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2401 return value similar to that of ecvt, except
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2402 that trailing zeros are suppressed.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2403 3 ==> through ndigits past the decimal point. This
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2404 gives a return value similar to that from fcvt,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2405 except that trailing zeros are suppressed, and
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2406 ndigits can be negative.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2407 4,5 ==> similar to 2 and 3, respectively, but (in
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2408 round-nearest mode) with the tests of mode 0 to
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2409 possibly return a shorter string that rounds to d.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2410 With IEEE arithmetic and compilation with
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2411 -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2412 as modes 2 and 3 when FLT_ROUNDS != 1.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2413 6-9 ==> Debugging modes similar to mode - 4: don't try
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2414 fast floating-point estimate (if applicable).
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2415
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2416 Values of mode other than 0-9 are treated as mode 0.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2417
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2418 Sufficient space is allocated to the return value
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2419 to hold the suppressed trailing zeros.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2420 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2421
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2422 int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2423 j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2424 spec_case, try_quick;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2425 Long L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2426 int denorm;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2427 ULong x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2428 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2429 U d2, eps, u;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2430 double ds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2431 char *s, *s0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2432
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2433 /* set pointers to NULL, to silence gcc compiler warnings and make
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2434 cleanup easier on error */
61547
8410f83fd159 Remove unnecessary assignments.
Mark Dickinson <dickinsm@gmail.com>
parents: 58467
diff changeset
2435 mlo = mhi = S = 0;
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2436 s0 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2437
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2438 u.d = dd;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2439 if (word0(&u) & Sign_bit) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2440 /* set sign for everything, including 0's and NaNs */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2441 *sign = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2442 word0(&u) &= ~Sign_bit; /* clear sign bit */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2443 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2444 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2445 *sign = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2446
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2447 /* quick return for Infinities, NaNs and zeros */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2448 if ((word0(&u) & Exp_mask) == Exp_mask)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2449 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2450 /* Infinity or NaN */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2451 *decpt = 9999;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2452 if (!word1(&u) && !(word0(&u) & 0xfffff))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2453 return nrv_alloc("Infinity", rve, 8);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2454 return nrv_alloc("NaN", rve, 3);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2455 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2456 if (!dval(&u)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2457 *decpt = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2458 return nrv_alloc("0", rve, 1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2459 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2460
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2461 /* compute k = floor(log10(d)). The computation may leave k
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2462 one too large, but should never leave k too small. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2463 b = d2b(&u, &be, &bbits);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2464 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2465 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2466 if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2467 dval(&d2) = dval(&u);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2468 word0(&d2) &= Frac_mask1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2469 word0(&d2) |= Exp_11;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2470
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2471 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2472 * log10(x) = log(x) / log(10)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2473 * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2474 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2475 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2476 * This suggests computing an approximation k to log10(d) by
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2477 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2478 * k = (i - Bias)*0.301029995663981
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2479 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2480 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2481 * We want k to be too large rather than too small.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2482 * The error in the first-order Taylor series approximation
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2483 * is in our favor, so we just round up the constant enough
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2484 * to compensate for any error in the multiplication of
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2485 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2486 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2487 * adding 1e-13 to the constant term more than suffices.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2488 * Hence we adjust the constant term to 0.1760912590558.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2489 * (We could get a more accurate k by invoking log10,
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2490 * but this is probably not worthwhile.)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2491 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2492
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2493 i -= Bias;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2494 denorm = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2495 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2496 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2497 /* d is denormalized */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2498
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2499 i = bbits + be + (Bias + (P-1) - 1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2500 x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2501 : word1(&u) << (32 - i);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2502 dval(&d2) = x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2503 word0(&d2) -= 31*Exp_msk1; /* adjust exponent */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2504 i -= (Bias + (P-1) - 1) + 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2505 denorm = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2506 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2507 ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 +
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2508 i*0.301029995663981;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2509 k = (int)ds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2510 if (ds < 0. && ds != k)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2511 k--; /* want k = floor(ds) */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2512 k_check = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2513 if (k >= 0 && k <= Ten_pmax) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2514 if (dval(&u) < tens[k])
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2515 k--;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2516 k_check = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2517 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2518 j = bbits - i - 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2519 if (j >= 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2520 b2 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2521 s2 = j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2522 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2523 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2524 b2 = -j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2525 s2 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2526 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2527 if (k >= 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2528 b5 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2529 s5 = k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2530 s2 += k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2531 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2532 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2533 b2 -= k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2534 b5 = -k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2535 s5 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2536 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2537 if (mode < 0 || mode > 9)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2538 mode = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2539
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2540 try_quick = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2541
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2542 if (mode > 5) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2543 mode -= 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2544 try_quick = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2545 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2546 leftright = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2547 ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2548 /* silence erroneous "gcc -Wall" warning. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2549 switch(mode) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2550 case 0:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2551 case 1:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2552 i = 18;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2553 ndigits = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2554 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2555 case 2:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2556 leftright = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2557 /* no break */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2558 case 4:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2559 if (ndigits <= 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2560 ndigits = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2561 ilim = ilim1 = i = ndigits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2562 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2563 case 3:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2564 leftright = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2565 /* no break */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2566 case 5:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2567 i = ndigits + k + 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2568 ilim = i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2569 ilim1 = i - 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2570 if (i <= 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2571 i = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2572 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2573 s0 = rv_alloc(i);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2574 if (s0 == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2575 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2576 s = s0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2577
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2578
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2579 if (ilim >= 0 && ilim <= Quick_max && try_quick) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2580
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2581 /* Try to get by with floating-point arithmetic. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2582
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2583 i = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2584 dval(&d2) = dval(&u);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2585 k0 = k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2586 ilim0 = ilim;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2587 ieps = 2; /* conservative */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2588 if (k > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2589 ds = tens[k&0xf];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2590 j = k >> 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2591 if (j & Bletch) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2592 /* prevent overflows */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2593 j &= Bletch - 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2594 dval(&u) /= bigtens[n_bigtens-1];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2595 ieps++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2596 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2597 for(; j; j >>= 1, i++)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2598 if (j & 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2599 ieps++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2600 ds *= bigtens[i];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2601 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2602 dval(&u) /= ds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2603 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2604 else if ((j1 = -k)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2605 dval(&u) *= tens[j1 & 0xf];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2606 for(j = j1 >> 4; j; j >>= 1, i++)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2607 if (j & 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2608 ieps++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2609 dval(&u) *= bigtens[i];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2610 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2611 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2612 if (k_check && dval(&u) < 1. && ilim > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2613 if (ilim1 <= 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2614 goto fast_failed;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2615 ilim = ilim1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2616 k--;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2617 dval(&u) *= 10.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2618 ieps++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2619 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2620 dval(&eps) = ieps*dval(&u) + 7.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2621 word0(&eps) -= (P-1)*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2622 if (ilim == 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2623 S = mhi = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2624 dval(&u) -= 5.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2625 if (dval(&u) > dval(&eps))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2626 goto one_digit;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2627 if (dval(&u) < -dval(&eps))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2628 goto no_digits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2629 goto fast_failed;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2630 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2631 if (leftright) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2632 /* Use Steele & White method of only
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2633 * generating digits needed.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2634 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2635 dval(&eps) = 0.5/tens[ilim-1] - dval(&eps);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2636 for(i = 0;;) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2637 L = (Long)dval(&u);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2638 dval(&u) -= L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2639 *s++ = '0' + (int)L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2640 if (dval(&u) < dval(&eps))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2641 goto ret1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2642 if (1. - dval(&u) < dval(&eps))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2643 goto bump_up;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2644 if (++i >= ilim)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2645 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2646 dval(&eps) *= 10.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2647 dval(&u) *= 10.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2648 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2649 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2650 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2651 /* Generate ilim digits, then fix them up. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2652 dval(&eps) *= tens[ilim-1];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2653 for(i = 1;; i++, dval(&u) *= 10.) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2654 L = (Long)(dval(&u));
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2655 if (!(dval(&u) -= L))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2656 ilim = i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2657 *s++ = '0' + (int)L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2658 if (i == ilim) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2659 if (dval(&u) > 0.5 + dval(&eps))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2660 goto bump_up;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2661 else if (dval(&u) < 0.5 - dval(&eps)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2662 while(*--s == '0');
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2663 s++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2664 goto ret1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2665 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2666 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2667 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2668 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2669 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2670 fast_failed:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2671 s = s0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2672 dval(&u) = dval(&d2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2673 k = k0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2674 ilim = ilim0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2675 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2676
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2677 /* Do we have a "small" integer? */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2678
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2679 if (be >= 0 && k <= Int_max) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2680 /* Yes. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2681 ds = tens[k];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2682 if (ndigits < 0 && ilim <= 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2683 S = mhi = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2684 if (ilim < 0 || dval(&u) <= 5*ds)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2685 goto no_digits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2686 goto one_digit;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2687 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2688 for(i = 1;; i++, dval(&u) *= 10.) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2689 L = (Long)(dval(&u) / ds);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2690 dval(&u) -= L*ds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2691 *s++ = '0' + (int)L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2692 if (!dval(&u)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2693 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2694 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2695 if (i == ilim) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2696 dval(&u) += dval(&u);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2697 if (dval(&u) > ds || (dval(&u) == ds && L & 1)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2698 bump_up:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2699 while(*--s == '9')
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2700 if (s == s0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2701 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2702 *s = '0';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2703 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2704 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2705 ++*s++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2706 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2707 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2708 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2709 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2710 goto ret1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2711 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2712
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2713 m2 = b2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2714 m5 = b5;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2715 if (leftright) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2716 i =
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2717 denorm ? be + (Bias + (P-1) - 1 + 1) :
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2718 1 + P - bbits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2719 b2 += i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2720 s2 += i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2721 mhi = i2b(1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2722 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2723 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2724 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2725 if (m2 > 0 && s2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2726 i = m2 < s2 ? m2 : s2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2727 b2 -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2728 m2 -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2729 s2 -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2730 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2731 if (b5 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2732 if (leftright) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2733 if (m5 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2734 mhi = pow5mult(mhi, m5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2735 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2736 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2737 b1 = mult(mhi, b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2738 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2739 b = b1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2740 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2741 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2742 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2743 if ((j = b5 - m5)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2744 b = pow5mult(b, j);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2745 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2746 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2747 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2748 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2749 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2750 b = pow5mult(b, b5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2751 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2752 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2753 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2754 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2755 S = i2b(1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2756 if (S == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2757 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2758 if (s5 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2759 S = pow5mult(S, s5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2760 if (S == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2761 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2762 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2763
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2764 /* Check for special case that d is a normalized power of 2. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2765
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2766 spec_case = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2767 if ((mode < 2 || leftright)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2768 ) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2769 if (!word1(&u) && !(word0(&u) & Bndry_mask)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2770 && word0(&u) & (Exp_mask & ~Exp_msk1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2771 ) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2772 /* The special case */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2773 b2 += Log2P;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2774 s2 += Log2P;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2775 spec_case = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2776 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2777 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2778
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2779 /* Arrange for convenient computation of quotients:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2780 * shift left if necessary so divisor has 4 leading 0 bits.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2781 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2782 * Perhaps we should just compute leading 28 bits of S once
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2783 * and for all and pass them and a shift to quorem, so it
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2784 * can do shifts and ors to compute the numerator for q.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2785 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2786 #define iInc 28
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2787 i = dshift(S, s2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2788 b2 += i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2789 m2 += i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2790 s2 += i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2791 if (b2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2792 b = lshift(b, b2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2793 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2794 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2795 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2796 if (s2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2797 S = lshift(S, s2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2798 if (S == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2799 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2800 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2801 if (k_check) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2802 if (cmp(b,S) < 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2803 k--;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2804 b = multadd(b, 10, 0); /* we botched the k estimate */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2805 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2806 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2807 if (leftright) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2808 mhi = multadd(mhi, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2809 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2810 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2811 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2812 ilim = ilim1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2813 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2814 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2815 if (ilim <= 0 && (mode == 3 || mode == 5)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2816 if (ilim < 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2817 /* no digits, fcvt style */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2818 no_digits:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2819 k = -1 - ndigits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2820 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2821 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2822 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2823 S = multadd(S, 5, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2824 if (S == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2825 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2826 if (cmp(b, S) <= 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2827 goto no_digits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2828 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2829 one_digit:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2830 *s++ = '1';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2831 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2832 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2833 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2834 if (leftright) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2835 if (m2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2836 mhi = lshift(mhi, m2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2837 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2838 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2839 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2840
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2841 /* Compute mlo -- check for special case
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2842 * that d is a normalized power of 2.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2843 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2844
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2845 mlo = mhi;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2846 if (spec_case) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2847 mhi = Balloc(mhi->k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2848 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2849 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2850 Bcopy(mhi, mlo);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2851 mhi = lshift(mhi, Log2P);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2852 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2853 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2854 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2855
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2856 for(i = 1;;i++) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2857 dig = quorem(b,S) + '0';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2858 /* Do we yet have the shortest decimal string
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2859 * that will round to d?
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2860 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2861 j = cmp(b, mlo);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2862 delta = diff(S, mhi);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2863 if (delta == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2864 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2865 j1 = delta->sign ? 1 : cmp(b, delta);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2866 Bfree(delta);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2867 if (j1 == 0 && mode != 1 && !(word1(&u) & 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2868 ) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2869 if (dig == '9')
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2870 goto round_9_up;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2871 if (j > 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2872 dig++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2873 *s++ = dig;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2874 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2875 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2876 if (j < 0 || (j == 0 && mode != 1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2877 && !(word1(&u) & 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2878 )) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2879 if (!b->x[0] && b->wds <= 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2880 goto accept_dig;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2881 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2882 if (j1 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2883 b = lshift(b, 1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2884 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2885 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2886 j1 = cmp(b, S);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2887 if ((j1 > 0 || (j1 == 0 && dig & 1))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2888 && dig++ == '9')
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2889 goto round_9_up;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2890 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2891 accept_dig:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2892 *s++ = dig;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2893 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2894 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2895 if (j1 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2896 if (dig == '9') { /* possible if i == 1 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2897 round_9_up:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2898 *s++ = '9';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2899 goto roundoff;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2900 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2901 *s++ = dig + 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2902 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2903 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2904 *s++ = dig;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2905 if (i == ilim)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2906 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2907 b = multadd(b, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2908 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2909 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2910 if (mlo == mhi) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2911 mlo = mhi = multadd(mhi, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2912 if (mlo == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2913 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2914 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2915 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2916 mlo = multadd(mlo, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2917 if (mlo == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2918 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2919 mhi = multadd(mhi, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2920 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2921 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2922 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2923 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2924 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2925 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2926 for(i = 1;; i++) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2927 *s++ = dig = quorem(b,S) + '0';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2928 if (!b->x[0] && b->wds <= 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2929 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2930 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2931 if (i >= ilim)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2932 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2933 b = multadd(b, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2934 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2935 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2936 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2937
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2938 /* Round off last digit */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2939
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2940 b = lshift(b, 1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2941 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2942 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2943 j = cmp(b, S);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2944 if (j > 0 || (j == 0 && dig & 1)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2945 roundoff:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2946 while(*--s == '9')
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2947 if (s == s0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2948 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2949 *s++ = '1';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2950 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2951 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2952 ++*s++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2953 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2954 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2955 while(*--s == '0');
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2956 s++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2957 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2958 ret:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2959 Bfree(S);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2960 if (mhi) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2961 if (mlo && mlo != mhi)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2962 Bfree(mlo);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2963 Bfree(mhi);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2964 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2965 ret1:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2966 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2967 *s = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2968 *decpt = k + 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2969 if (rve)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2970 *rve = s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2971 return s0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2972 failed_malloc:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2973 if (S)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2974 Bfree(S);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2975 if (mlo && mlo != mhi)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2976 Bfree(mlo);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2977 if (mhi)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2978 Bfree(mhi);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2979 if (b)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2980 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2981 if (s0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2982 _Py_dg_freedtoa(s0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2983 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2984 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2985 #ifdef __cplusplus
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2986 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2987 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2988
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2989 #endif /* PY_NO_SHORT_FLOAT_REPR */