Mercurial > cpython-lru_cache-weakref
annotate Python/dtoa.c @ 73323:dad02a080bbc
Improve byte-compilation in packaging to be independent of -O or -B.
The code I fixed to comply with PEP 3147 still had one bug: When run
under python -O, some paths for pyc files would be pyo, because I called
imp.cache_from_source without explicit debug_override argument in some
places, and under -O that would return .pyo (this is well explained in
the imp docs). Now all code (util.byte_compile, build_py, install_lib)
can create .pyo files according to options given by users,
without interference from the calling Python’s own optimize mode.
On a related topic, I also removed the code that prevented byte
compilation under python -B. The rationale is that packaging gives
control over the creation of pyc files to the user with its own explicit
option, and the behavior should not be changed if the calling Python
happens to run with -B for whatever reason. I will argue that this is a
bug fix and ask to be allowed to backport this change to distutils.
Finally, I moved one nugget of information about the --compile and
--optimize options from the source into the doc. It clears up a
misunderstanding that I (and maybe other people) had.
| author | Éric Araujo <merwok@netwok.org> |
|---|---|
| date | Thu, 03 Nov 2011 05:08:28 +0100 |
| parents | e2f96bd29252 |
| children | c468511fc887 |
| 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 |
|
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
207 #define MAX_ABS_EXP 19999U |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
208 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
209 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
210 /* 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
|
211 * 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
|
212 * #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
|
213 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
214 #if defined(IEEE_8087) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
215 #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
|
216 ((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
|
217 #else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
218 #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
|
219 ((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
|
220 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
221 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
222 /* #define P DBL_MANT_DIG */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
223 /* 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
|
224 /* 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
|
225 /* 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
|
226 /* 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
|
227 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
228 #define Exp_shift 20 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
229 #define Exp_shift1 20 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
230 #define Exp_msk1 0x100000 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
231 #define Exp_msk11 0x100000 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
232 #define Exp_mask 0x7ff00000 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
233 #define P 53 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
234 #define Nbits 53 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
235 #define Bias 1023 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
236 #define Emax 1023 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
237 #define Emin (-1022) |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
238 #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
|
239 #define Exp_1 0x3ff00000 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
240 #define Exp_11 0x3ff00000 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
241 #define Ebits 11 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
242 #define Frac_mask 0xfffff |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
243 #define Frac_mask1 0xfffff |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
244 #define Ten_pmax 22 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
245 #define Bletch 0x10 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
246 #define Bndry_mask 0xfffff |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
247 #define Bndry_mask1 0xfffff |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
248 #define Sign_bit 0x80000000 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
249 #define Log2P 1 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
250 #define Tiny0 0 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
251 #define Tiny1 1 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
252 #define Quick_max 14 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
253 #define Int_max 14 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
254 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
255 #ifndef Flt_Rounds |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
256 #ifdef FLT_ROUNDS |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
257 #define Flt_Rounds FLT_ROUNDS |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
258 #else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
259 #define Flt_Rounds 1 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
260 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
261 #endif /*Flt_Rounds*/ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
262 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
263 #define Rounding Flt_Rounds |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
264 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
265 #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
|
266 #define Big1 0xffffffff |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
267 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
268 /* 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
|
269 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
270 typedef struct BCinfo BCinfo; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
271 struct |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
272 BCinfo { |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
273 int e0, nd, nd0, scale; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
274 }; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
275 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
276 #define FFFFFFFF 0xffffffffUL |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
277 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
278 #define Kmax 7 |
|
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 /* 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
|
281 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
|
282 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
|
283 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
|
284 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
285 The Bigint fields are as follows: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
286 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
287 - 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
|
288 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
|
289 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
|
290 - 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
|
291 - 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
|
292 (usually maxwds == 2**k) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
293 - 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
|
294 (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
|
295 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
|
296 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
|
297 - 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
|
298 - 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
|
299 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
|
300 */ |
|
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 struct |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
303 Bigint { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
304 struct Bigint *next; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
305 int k, maxwds, sign, wds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
306 ULong x[1]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
307 }; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
308 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
309 typedef struct Bigint Bigint; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
310 |
|
58402
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
311 #ifndef Py_USING_MEMORY_DEBUGGER |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
312 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
313 /* 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
|
314 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
|
315 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
|
316 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
|
317 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
318 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
|
319 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
|
320 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
|
321 in preference to using MALLOC. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
322 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
323 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
|
324 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
|
325 FREE. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
326 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
327 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
|
328 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
|
329 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
|
330 performance on impact. */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
331 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
332 static Bigint *freelist[Kmax+1]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
333 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
334 /* 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
|
335 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
336 static Bigint * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
337 Balloc(int k) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
338 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
339 int x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
340 Bigint *rv; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
341 unsigned int len; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
342 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
343 if (k <= Kmax && (rv = freelist[k])) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
344 freelist[k] = rv->next; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
345 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
346 x = 1 << k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
347 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
|
348 /sizeof(double); |
|
53203
ab06a38b590c
Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents:
53185
diff
changeset
|
349 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
|
350 rv = (Bigint*)pmem_next; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
351 pmem_next += len; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
352 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
353 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
354 rv = (Bigint*)MALLOC(len*sizeof(double)); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
355 if (rv == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
356 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
357 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
358 rv->k = k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
359 rv->maxwds = x; |
|
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 rv->sign = rv->wds = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
362 return rv; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
363 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
364 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
365 /* Free a Bigint allocated with Balloc */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
366 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
367 static void |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
368 Bfree(Bigint *v) |
|
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 (v) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
371 if (v->k > Kmax) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
372 FREE((void*)v); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
373 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
374 v->next = freelist[v->k]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
375 freelist[v->k] = v; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
376 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
377 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
378 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
379 |
|
58402
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
380 #else |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
381 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
382 /* 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
|
383 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
|
384 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
|
385 Valgrind. */ |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
386 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
387 /* 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
|
388 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
389 static Bigint * |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
390 Balloc(int k) |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
391 { |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
392 int x; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
393 Bigint *rv; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
394 unsigned int len; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
395 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
396 x = 1 << k; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
397 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
|
398 /sizeof(double); |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
399 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
400 rv = (Bigint*)MALLOC(len*sizeof(double)); |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
401 if (rv == NULL) |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
402 return NULL; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
403 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
404 rv->k = k; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
405 rv->maxwds = x; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
406 rv->sign = rv->wds = 0; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
407 return rv; |
|
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 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
410 /* Free a Bigint allocated with Balloc */ |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
411 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
412 static void |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
413 Bfree(Bigint *v) |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
414 { |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
415 if (v) { |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
416 FREE((void*)v); |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
417 } |
|
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 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
420 #endif /* Py_USING_MEMORY_DEBUGGER */ |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
421 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
422 #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
|
423 y->wds*sizeof(Long) + 2*sizeof(int)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
424 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
425 /* 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
|
426 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
|
427 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
|
428 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
429 static Bigint * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
430 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
|
431 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
432 int i, wds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
433 #ifdef ULLong |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
434 ULong *x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
435 ULLong carry, y; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
436 #else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
437 ULong carry, *x, y; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
438 ULong xi, z; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
439 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
440 Bigint *b1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
441 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
442 wds = b->wds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
443 x = b->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
444 i = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
445 carry = a; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
446 do { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
447 #ifdef ULLong |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
448 y = *x * (ULLong)m + carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
449 carry = y >> 32; |
|
53207
fe99a562b708
Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents:
53203
diff
changeset
|
450 *x++ = (ULong)(y & FFFFFFFF); |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
451 #else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
452 xi = *x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
453 y = (xi & 0xffff) * m + carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
454 z = (xi >> 16) * m + (y >> 16); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
455 carry = z >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
456 *x++ = (z << 16) + (y & 0xffff); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
457 #endif |
|
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 while(++i < wds); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
460 if (carry) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
461 if (wds >= b->maxwds) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
462 b1 = Balloc(b->k+1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
463 if (b1 == NULL){ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
464 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
465 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
466 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
467 Bcopy(b1, b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
468 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
469 b = b1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
470 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
471 b->x[wds++] = (ULong)carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
472 b->wds = wds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
473 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
474 return b; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
475 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
476 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
477 /* 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
|
478 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
|
479 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
|
480 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
|
481 NULL on failure. */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
482 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
483 static Bigint * |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
484 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
|
485 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
486 Bigint *b; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
487 int i, k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
488 Long x, y; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
489 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
490 x = (nd + 8) / 9; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
491 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
|
492 b = Balloc(k); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
493 if (b == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
494 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
495 b->x[0] = y9; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
496 b->wds = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
497 |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
498 if (nd <= 9) |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
499 return b; |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
500 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
501 s += 9; |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
502 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
|
503 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
|
504 if (b == NULL) |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
505 return NULL; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
506 } |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
507 s++; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
508 for(; i < nd; i++) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
509 b = multadd(b, 10, *s++ - '0'); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
510 if (b == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
511 return NULL; |
|
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 return b; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
514 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
515 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
516 /* 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
|
517 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
518 static int |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
519 hi0bits(ULong x) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
520 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
521 int k = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
522 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
523 if (!(x & 0xffff0000)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
524 k = 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
525 x <<= 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
526 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
527 if (!(x & 0xff000000)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
528 k += 8; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
529 x <<= 8; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
530 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
531 if (!(x & 0xf0000000)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
532 k += 4; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
533 x <<= 4; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
534 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
535 if (!(x & 0xc0000000)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
536 k += 2; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
537 x <<= 2; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
538 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
539 if (!(x & 0x80000000)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
540 k++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
541 if (!(x & 0x40000000)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
542 return 32; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
543 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
544 return k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
545 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
546 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
547 /* 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
|
548 number of bits. */ |
|
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 static int |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
551 lo0bits(ULong *y) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
552 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
553 int k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
554 ULong x = *y; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
555 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
556 if (x & 7) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
557 if (x & 1) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
558 return 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
559 if (x & 2) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
560 *y = x >> 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
561 return 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
562 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
563 *y = x >> 2; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
564 return 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 k = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
567 if (!(x & 0xffff)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
568 k = 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
569 x >>= 16; |
|
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 if (!(x & 0xff)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
572 k += 8; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
573 x >>= 8; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
574 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
575 if (!(x & 0xf)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
576 k += 4; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
577 x >>= 4; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
578 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
579 if (!(x & 0x3)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
580 k += 2; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
581 x >>= 2; |
|
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 & 1)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
584 k++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
585 x >>= 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
586 if (!x) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
587 return 32; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
588 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
589 *y = x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
590 return k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
591 } |
|
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 /* 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
|
594 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
595 static Bigint * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
596 i2b(int i) |
|
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 Bigint *b; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
599 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
600 b = Balloc(1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
601 if (b == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
602 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
603 b->x[0] = i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
604 b->wds = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
605 return b; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
606 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
607 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
608 /* 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
|
609 the signs of a and b. */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
610 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
611 static Bigint * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
612 mult(Bigint *a, Bigint *b) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
613 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
614 Bigint *c; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
615 int k, wa, wb, wc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
616 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
|
617 ULong y; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
618 #ifdef ULLong |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
619 ULLong carry, z; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
620 #else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
621 ULong carry, z; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
622 ULong z2; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
623 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
624 |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
625 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
|
626 c = Balloc(0); |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
627 if (c == NULL) |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
628 return NULL; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
629 c->wds = 1; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
630 c->x[0] = 0; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
631 return c; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
632 } |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
633 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
634 if (a->wds < b->wds) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
635 c = a; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
636 a = b; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
637 b = c; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
638 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
639 k = a->k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
640 wa = a->wds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
641 wb = b->wds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
642 wc = wa + wb; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
643 if (wc > a->maxwds) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
644 k++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
645 c = Balloc(k); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
646 if (c == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
647 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
648 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
|
649 *x = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
650 xa = a->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
651 xae = xa + wa; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
652 xb = b->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
653 xbe = xb + wb; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
654 xc0 = c->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
655 #ifdef ULLong |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
656 for(; xb < xbe; xc0++) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
657 if ((y = *xb++)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
658 x = xa; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
659 xc = xc0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
660 carry = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
661 do { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
662 z = *x++ * (ULLong)y + *xc + carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
663 carry = z >> 32; |
|
53207
fe99a562b708
Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents:
53203
diff
changeset
|
664 *xc++ = (ULong)(z & FFFFFFFF); |
|
53185
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 while(x < xae); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
667 *xc = (ULong)carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
668 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
669 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
670 #else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
671 for(; xb < xbe; xb++, xc0++) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
672 if (y = *xb & 0xffff) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
673 x = xa; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
674 xc = xc0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
675 carry = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
676 do { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
677 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
678 carry = z >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
679 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
680 carry = z2 >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
681 Storeinc(xc, z2, z); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
682 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
683 while(x < xae); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
684 *xc = carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
685 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
686 if (y = *xb >> 16) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
687 x = xa; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
688 xc = xc0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
689 carry = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
690 z2 = *xc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
691 do { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
692 z = (*x & 0xffff) * y + (*xc >> 16) + carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
693 carry = z >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
694 Storeinc(xc, z, z2); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
695 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
696 carry = z2 >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
697 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
698 while(x < xae); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
699 *xc = z2; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
700 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
701 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
702 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
703 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
|
704 c->wds = wc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
705 return c; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
706 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
707 |
|
58402
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
708 #ifndef Py_USING_MEMORY_DEBUGGER |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
709 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
710 /* 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
|
711 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
712 static Bigint *p5s; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
713 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
714 /* 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
|
715 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
|
716 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
|
717 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
718 static Bigint * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
719 pow5mult(Bigint *b, int k) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
720 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
721 Bigint *b1, *p5, *p51; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
722 int i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
723 static int p05[3] = { 5, 25, 125 }; |
|
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 if ((i = k & 3)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
726 b = multadd(b, p05[i-1], 0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
727 if (b == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
728 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
729 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
730 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
731 if (!(k >>= 2)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
732 return b; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
733 p5 = p5s; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
734 if (!p5) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
735 /* first time */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
736 p5 = i2b(625); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
737 if (p5 == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
738 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
739 return NULL; |
|
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 p5s = p5; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
742 p5->next = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
743 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
744 for(;;) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
745 if (k & 1) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
746 b1 = mult(b, p5); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
747 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
748 b = b1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
749 if (b == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
750 return NULL; |
|
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 (!(k >>= 1)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
753 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
754 p51 = p5->next; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
755 if (!p51) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
756 p51 = mult(p5,p5); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
757 if (p51 == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
758 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
759 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
760 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
761 p51->next = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
762 p5->next = p51; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
763 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
764 p5 = p51; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
765 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
766 return b; |
|
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 |
|
58402
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
769 #else |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
770 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
771 /* 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
|
772 the benefit of memory debugging tools like Valgrind. */ |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
773 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
774 static Bigint * |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
775 pow5mult(Bigint *b, int k) |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
776 { |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
777 Bigint *b1, *p5, *p51; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
778 int i; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
779 static int p05[3] = { 5, 25, 125 }; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
780 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
781 if ((i = k & 3)) { |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
782 b = multadd(b, p05[i-1], 0); |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
783 if (b == NULL) |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
784 return NULL; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
785 } |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
786 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
787 if (!(k >>= 2)) |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
788 return b; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
789 p5 = i2b(625); |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
790 if (p5 == NULL) { |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
791 Bfree(b); |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
792 return NULL; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
793 } |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
794 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
795 for(;;) { |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
796 if (k & 1) { |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
797 b1 = mult(b, p5); |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
798 Bfree(b); |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
799 b = b1; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
800 if (b == NULL) { |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
801 Bfree(p5); |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
802 return NULL; |
|
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 } |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
805 if (!(k >>= 1)) |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
806 break; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
807 p51 = mult(p5, p5); |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
808 Bfree(p5); |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
809 p5 = p51; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
810 if (p5 == NULL) { |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
811 Bfree(b); |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
812 return NULL; |
|
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 } |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
815 Bfree(p5); |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
816 return b; |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
817 } |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
818 |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
819 #endif /* Py_USING_MEMORY_DEBUGGER */ |
|
3e629471850a
Merged revisions 77589 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58391
diff
changeset
|
820 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
821 /* 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
|
822 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
|
823 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
|
824 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
825 static Bigint * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
826 lshift(Bigint *b, int k) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
827 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
828 int i, k1, n, n1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
829 Bigint *b1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
830 ULong *x, *x1, *xe, z; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
831 |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
832 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
|
833 return b; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
834 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
835 n = k >> 5; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
836 k1 = b->k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
837 n1 = n + b->wds + 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
838 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
|
839 k1++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
840 b1 = Balloc(k1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
841 if (b1 == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
842 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
843 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
844 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
845 x1 = b1->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
846 for(i = 0; i < n; i++) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
847 *x1++ = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
848 x = b->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
849 xe = x + b->wds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
850 if (k &= 0x1f) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
851 k1 = 32 - k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
852 z = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
853 do { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
854 *x1++ = *x << k | z; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
855 z = *x++ >> k1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
856 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
857 while(x < xe); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
858 if ((*x1 = z)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
859 ++n1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
860 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
861 else do |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
862 *x1++ = *x++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
863 while(x < xe); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
864 b1->wds = n1 - 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
865 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
866 return b1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
867 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
868 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
869 /* 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
|
870 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
|
871 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
872 static int |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
873 cmp(Bigint *a, Bigint *b) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
874 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
875 ULong *xa, *xa0, *xb, *xb0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
876 int i, j; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
877 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
878 i = a->wds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
879 j = b->wds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
880 #ifdef DEBUG |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
881 if (i > 1 && !a->x[i-1]) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
882 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
|
883 if (j > 1 && !b->x[j-1]) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
884 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
|
885 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
886 if (i -= j) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
887 return i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
888 xa0 = a->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
889 xa = xa0 + j; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
890 xb0 = b->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
891 xb = xb0 + j; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
892 for(;;) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
893 if (*--xa != *--xb) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
894 return *xa < *xb ? -1 : 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
895 if (xa <= xa0) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
896 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
897 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
898 return 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
899 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
900 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
901 /* 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
|
902 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
|
903 result is set appropriately. */ |
|
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 static Bigint * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
906 diff(Bigint *a, Bigint *b) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
907 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
908 Bigint *c; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
909 int i, wa, wb; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
910 ULong *xa, *xae, *xb, *xbe, *xc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
911 #ifdef ULLong |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
912 ULLong borrow, y; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
913 #else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
914 ULong borrow, y; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
915 ULong z; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
916 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
917 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
918 i = cmp(a,b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
919 if (!i) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
920 c = Balloc(0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
921 if (c == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
922 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
923 c->wds = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
924 c->x[0] = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
925 return c; |
|
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 if (i < 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
928 c = a; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
929 a = b; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
930 b = c; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
931 i = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
932 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
933 else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
934 i = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
935 c = Balloc(a->k); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
936 if (c == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
937 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
938 c->sign = i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
939 wa = a->wds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
940 xa = a->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
941 xae = xa + wa; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
942 wb = b->wds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
943 xb = b->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
944 xbe = xb + wb; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
945 xc = c->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
946 borrow = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
947 #ifdef ULLong |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
948 do { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
949 y = (ULLong)*xa++ - *xb++ - borrow; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
950 borrow = y >> 32 & (ULong)1; |
|
53207
fe99a562b708
Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents:
53203
diff
changeset
|
951 *xc++ = (ULong)(y & FFFFFFFF); |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
952 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
953 while(xb < xbe); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
954 while(xa < xae) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
955 y = *xa++ - borrow; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
956 borrow = y >> 32 & (ULong)1; |
|
53207
fe99a562b708
Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents:
53203
diff
changeset
|
957 *xc++ = (ULong)(y & FFFFFFFF); |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
958 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
959 #else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
960 do { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
961 y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
962 borrow = (y & 0x10000) >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
963 z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
964 borrow = (z & 0x10000) >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
965 Storeinc(xc, z, y); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
966 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
967 while(xb < xbe); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
968 while(xa < xae) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
969 y = (*xa & 0xffff) - borrow; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
970 borrow = (y & 0x10000) >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
971 z = (*xa++ >> 16) - borrow; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
972 borrow = (z & 0x10000) >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
973 Storeinc(xc, z, y); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
974 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
975 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
976 while(!*--xc) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
977 wa--; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
978 c->wds = wa; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
979 return c; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
980 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
981 |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
982 /* 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
|
983 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
|
984 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
985 static double |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
986 ulp(U *x) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
987 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
988 Long L; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
989 U u; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
990 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
991 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
|
992 word0(&u) = L; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
993 word1(&u) = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
994 return dval(&u); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
995 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
996 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
997 /* 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
|
998 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
999 static double |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1000 b2d(Bigint *a, int *e) |
|
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 ULong *xa, *xa0, w, y, z; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1003 int k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1004 U d; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1005 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1006 xa0 = a->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1007 xa = xa0 + a->wds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1008 y = *--xa; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1009 #ifdef DEBUG |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1010 if (!y) Bug("zero y in b2d"); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1011 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1012 k = hi0bits(y); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1013 *e = 32 - k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1014 if (k < Ebits) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1015 word0(&d) = Exp_1 | y >> (Ebits - k); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1016 w = xa > xa0 ? *--xa : 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1017 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
|
1018 goto ret_d; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1019 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1020 z = xa > xa0 ? *--xa : 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1021 if (k -= Ebits) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1022 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
|
1023 y = xa > xa0 ? *--xa : 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1024 word1(&d) = z << k | y >> (32 - k); |
|
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 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1027 word0(&d) = Exp_1 | y; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1028 word1(&d) = z; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1029 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1030 ret_d: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1031 return dval(&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 |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1034 /* 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
|
1035 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
|
1036 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
|
1037 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
|
1038 / 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
|
1039 |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1040 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
|
1041 |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1042 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
|
1043 |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1044 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
|
1045 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
|
1046 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
|
1047 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
|
1048 |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1049 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
|
1050 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
|
1051 |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1052 Returns NULL on failure. |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1053 */ |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1054 |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1055 static Bigint * |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1056 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
|
1057 { |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1058 Bigint *b; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1059 |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1060 b = Balloc(1); |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1061 if (b == NULL) |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1062 return NULL; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1063 |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1064 /* 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
|
1065 b->wds = 2; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1066 b->x[0] = word1(d); |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1067 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
|
1068 *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
|
1069 if (*e < Etiny) |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1070 *e = Etiny; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1071 else |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1072 b->x[1] |= Exp_msk1; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1073 |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1074 /* 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
|
1075 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
|
1076 *e -= scale; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1077 if (*e < Etiny) { |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1078 scale = Etiny - *e; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1079 *e = Etiny; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1080 /* 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
|
1081 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
|
1082 if (scale >= 32) { |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1083 /* 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
|
1084 assert(b->x[0] == 0); |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1085 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
|
1086 b->x[1] = 0; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1087 scale -= 32; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1088 } |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1089 if (scale) { |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1090 /* 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
|
1091 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
|
1092 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
|
1093 b->x[1] >>= scale; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1094 } |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1095 } |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1096 } |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1097 /* Ensure b is normalized. */ |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1098 if (!b->x[1]) |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1099 b->wds = 1; |
|
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 return b; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1102 } |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1103 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1104 /* 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
|
1105 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1106 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
|
1107 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
|
1108 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
|
1109 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1110 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
|
1111 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1112 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1113 static Bigint * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1114 d2b(U *d, int *e, int *bits) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1115 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1116 Bigint *b; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1117 int de, k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1118 ULong *x, y, z; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1119 int i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1120 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1121 b = Balloc(1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1122 if (b == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1123 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1124 x = b->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1125 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1126 z = word0(d) & Frac_mask; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1127 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
|
1128 if ((de = (int)(word0(d) >> Exp_shift))) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1129 z |= Exp_msk1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1130 if ((y = word1(d))) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1131 if ((k = lo0bits(&y))) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1132 x[0] = y | z << (32 - k); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1133 z >>= k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1134 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1135 else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1136 x[0] = y; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1137 i = |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1138 b->wds = (x[1] = z) ? 2 : 1; |
|
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 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1141 k = lo0bits(&z); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1142 x[0] = z; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1143 i = |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1144 b->wds = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1145 k += 32; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1146 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1147 if (de) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1148 *e = de - Bias - (P-1) + k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1149 *bits = P - k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1150 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1151 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1152 *e = de - Bias - (P-1) + 1 + k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1153 *bits = 32*i - hi0bits(x[i-1]); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1154 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1155 return b; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1156 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1157 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1158 /* 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
|
1159 error of up to 2.5 ulps. */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1160 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1161 static double |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1162 ratio(Bigint *a, Bigint *b) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1163 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1164 U da, db; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1165 int k, ka, kb; |
|
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 dval(&da) = b2d(a, &ka); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1168 dval(&db) = b2d(b, &kb); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1169 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
|
1170 if (k > 0) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1171 word0(&da) += k*Exp_msk1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1172 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1173 k = -k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1174 word0(&db) += k*Exp_msk1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1175 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1176 return dval(&da) / dval(&db); |
|
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 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1179 static const double |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1180 tens[] = { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1181 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
|
1182 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
|
1183 1e20, 1e21, 1e22 |
|
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 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1186 static const double |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1187 bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1188 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
|
1189 9007199254740992.*9007199254740992.e-256 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1190 /* = 2^106 * 1e-256 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1191 }; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1192 /* 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
|
1193 /* 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
|
1194 #define Scale_Bit 0x10 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1195 #define n_bigtens 5 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1196 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1197 #define ULbits 32 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1198 #define kshift 5 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1199 #define kmask 31 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1200 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1201 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1202 static int |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1203 dshift(Bigint *b, int p2) |
|
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 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
|
1206 if (p2 > 0) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1207 rv -= p2; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1208 return rv & kmask; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1209 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1210 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1211 /* 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
|
1212 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
|
1213 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
|
1214 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1215 static int |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1216 quorem(Bigint *b, Bigint *S) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1217 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1218 int n; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1219 ULong *bx, *bxe, q, *sx, *sxe; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1220 #ifdef ULLong |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1221 ULLong borrow, carry, y, ys; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1222 #else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1223 ULong borrow, carry, y, ys; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1224 ULong si, z, zs; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1225 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1226 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1227 n = S->wds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1228 #ifdef DEBUG |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1229 /*debug*/ if (b->wds > n) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1230 /*debug*/ Bug("oversize b in quorem"); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1231 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1232 if (b->wds < n) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1233 return 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1234 sx = S->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1235 sxe = sx + --n; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1236 bx = b->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1237 bxe = bx + n; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1238 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
|
1239 #ifdef DEBUG |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1240 /*debug*/ if (q > 9) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1241 /*debug*/ Bug("oversized quotient in quorem"); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1242 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1243 if (q) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1244 borrow = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1245 carry = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1246 do { |
|
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 ys = *sx++ * (ULLong)q + carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1249 carry = ys >> 32; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1250 y = *bx - (ys & FFFFFFFF) - borrow; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1251 borrow = y >> 32 & (ULong)1; |
|
53207
fe99a562b708
Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents:
53203
diff
changeset
|
1252 *bx++ = (ULong)(y & FFFFFFFF); |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1253 #else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1254 si = *sx++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1255 ys = (si & 0xffff) * q + carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1256 zs = (si >> 16) * q + (ys >> 16); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1257 carry = zs >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1258 y = (*bx & 0xffff) - (ys & 0xffff) - borrow; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1259 borrow = (y & 0x10000) >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1260 z = (*bx >> 16) - (zs & 0xffff) - borrow; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1261 borrow = (z & 0x10000) >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1262 Storeinc(bx, z, y); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1263 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1264 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1265 while(sx <= sxe); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1266 if (!*bxe) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1267 bx = b->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1268 while(--bxe > bx && !*bxe) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1269 --n; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1270 b->wds = n; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1271 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1272 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1273 if (cmp(b, S) >= 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1274 q++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1275 borrow = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1276 carry = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1277 bx = b->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1278 sx = S->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1279 do { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1280 #ifdef ULLong |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1281 ys = *sx++ + carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1282 carry = ys >> 32; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1283 y = *bx - (ys & FFFFFFFF) - borrow; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1284 borrow = y >> 32 & (ULong)1; |
|
53207
fe99a562b708
Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents:
53203
diff
changeset
|
1285 *bx++ = (ULong)(y & FFFFFFFF); |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1286 #else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1287 si = *sx++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1288 ys = (si & 0xffff) + carry; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1289 zs = (si >> 16) + (ys >> 16); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1290 carry = zs >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1291 y = (*bx & 0xffff) - (ys & 0xffff) - borrow; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1292 borrow = (y & 0x10000) >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1293 z = (*bx >> 16) - (zs & 0xffff) - borrow; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1294 borrow = (z & 0x10000) >> 16; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1295 Storeinc(bx, z, y); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1296 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1297 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1298 while(sx <= sxe); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1299 bx = b->x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1300 bxe = bx + n; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1301 if (!*bxe) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1302 while(--bxe > bx && !*bxe) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1303 --n; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1304 b->wds = n; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1305 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1306 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1307 return q; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1308 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1309 |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1310 /* 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
|
1311 |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1312 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
|
1313 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
|
1314 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
|
1315 |
|
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
1316 static double |
|
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
1317 sulp(U *x, BCinfo *bc) |
|
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
1318 { |
|
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
1319 U u; |
|
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
1320 |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1321 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
|
1322 /* 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
|
1323 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
|
1324 word1(&u) = 0; |
|
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
1325 return u.d; |
|
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
1326 } |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1327 else { |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1328 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
|
1329 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
|
1330 } |
|
58279
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
1331 } |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1332 |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1333 /* 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
|
1334 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
|
1335 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
|
1336 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
|
1337 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1338 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
|
1339 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
|
1340 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
|
1341 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
|
1342 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
|
1343 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
|
1344 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1345 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
|
1346 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
|
1347 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1348 Inputs: |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1349 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1350 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
|
1351 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1352 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
|
1353 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
|
1354 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
|
1355 the input value. |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1356 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1357 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
|
1358 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
|
1359 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1360 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
|
1361 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
|
1362 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1363 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
|
1364 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
|
1365 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1366 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
|
1367 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
|
1368 bc->nd. |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1369 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1370 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
|
1371 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
|
1372 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1373 Outputs: |
|
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 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
|
1376 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1377 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
|
1378 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1379 static int |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1380 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
|
1381 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1382 Bigint *b, *d; |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1383 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
|
1384 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1385 nd = bc->nd; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1386 nd0 = bc->nd0; |
|
58279
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
1387 p5 = nd + bc->e0; |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1388 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
|
1389 if (b == NULL) |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1390 return -1; |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1391 |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1392 /* 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
|
1393 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
|
1394 odd = b->x[0] & 1; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1395 |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1396 /* 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
|
1397 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
|
1398 b = lshift(b, 1); |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1399 if (b == NULL) |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1400 return -1; |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1401 b->x[0] |= 1; |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1402 p2--; |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1403 |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1404 p2 -= p5; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1405 d = i2b(1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1406 if (d == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1407 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1408 return -1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1409 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1410 /* Arrange for convenient computation of quotients: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1411 * 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
|
1412 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1413 if (p5 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1414 d = pow5mult(d, p5); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1415 if (d == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1416 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1417 return -1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1418 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1419 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1420 else if (p5 < 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1421 b = pow5mult(b, -p5); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1422 if (b == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1423 Bfree(d); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1424 return -1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1425 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1426 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1427 if (p2 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1428 b2 = p2; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1429 d2 = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1430 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1431 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1432 b2 = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1433 d2 = -p2; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1434 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1435 i = dshift(d, d2); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1436 if ((b2 += i) > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1437 b = lshift(b, b2); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1438 if (b == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1439 Bfree(d); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1440 return -1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1441 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1442 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1443 if ((d2 += i) > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1444 d = lshift(d, d2); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1445 if (d == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1446 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1447 return -1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1448 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1449 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1450 |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1451 /* 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
|
1452 * 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
|
1453 * 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
|
1454 if (cmp(b, d) >= 0) |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1455 /* b/d >= 1 */ |
|
58279
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
1456 dd = -1; |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1457 else { |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1458 i = 0; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1459 for(;;) { |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1460 b = multadd(b, 10, 0); |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1461 if (b == NULL) { |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1462 Bfree(d); |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1463 return -1; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1464 } |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1465 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
|
1466 i++; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1467 |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1468 if (dd) |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1469 break; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1470 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
|
1471 /* b/d == 0 */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1472 dd = i < nd; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1473 break; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1474 } |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1475 if (!(i < nd)) { |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1476 /* 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
|
1477 dd = -1; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1478 break; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1479 } |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1480 } |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1481 } |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1482 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1483 Bfree(d); |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1484 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
|
1485 dval(rv) += sulp(rv, bc); |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1486 return 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1487 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1488 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1489 double |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1490 _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
|
1491 { |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1492 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
|
1493 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
|
1494 const char *s, *s0, *s1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1495 double aadj, aadj1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1496 U aadj2, adj, rv, rv0; |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1497 ULong y, z, abs_exp; |
|
58360
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1498 Long L; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1499 BCinfo bc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1500 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1501 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1502 dval(&rv) = 0.; |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1503 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1504 /* Start parsing. */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1505 c = *(s = s00); |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1506 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1507 /* Parse optional sign, if present. */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1508 sign = 0; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1509 switch (c) { |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1510 case '-': |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1511 sign = 1; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1512 /* no break */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1513 case '+': |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1514 c = *++s; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1515 } |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1516 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1517 /* 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
|
1518 s1 = s; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1519 while (c == '0') |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1520 c = *++s; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1521 lz = s != s1; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1522 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1523 /* Point s0 at the first nonzero digit (if any). nd0 will be the position |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1524 of the point relative to s0. nd will be the total number of digits |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1525 ignoring leading zeros. */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1526 s0 = s1 = s; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1527 while ('0' <= c && c <= '9') |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1528 c = *++s; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1529 nd0 = nd = s - s1; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1530 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1531 /* Parse decimal point and following digits. */ |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1532 if (c == '.') { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1533 c = *++s; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1534 if (!nd) { |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1535 s1 = s; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1536 while (c == '0') |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1537 c = *++s; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1538 lz = lz || s != s1; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1539 nd0 -= s - s1; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1540 s0 = s; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1541 } |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1542 s1 = s; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1543 while ('0' <= c && c <= '9') |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1544 c = *++s; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1545 nd += s - s1; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1546 } |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1547 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1548 /* Now lz is true if and only if there were leading zero digits, and nd |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1549 gives the total number of digits ignoring leading zeros. A valid input |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1550 must have at least one digit. */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1551 if (!nd && !lz) { |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1552 if (se) |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1553 *se = (char *)s00; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1554 goto parse_error; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1555 } |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1556 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1557 /* Parse exponent. */ |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1558 e = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1559 if (c == 'e' || c == 'E') { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1560 s00 = s; |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1561 c = *++s; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1562 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1563 /* Exponent sign. */ |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1564 esign = 0; |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1565 switch (c) { |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1566 case '-': |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1567 esign = 1; |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1568 /* no break */ |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1569 case '+': |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1570 c = *++s; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1571 } |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1572 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1573 /* 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
|
1574 s1 = s; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1575 while (c == '0') |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1576 c = *++s; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1577 lz = s != s1; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1578 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1579 /* Get absolute value of the exponent. */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1580 s1 = s; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1581 abs_exp = 0; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1582 while ('0' <= c && c <= '9') { |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1583 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
|
1584 c = *++s; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1585 } |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1586 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1587 /* 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
|
1588 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
|
1589 impossible. */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1590 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
|
1591 e = (int)MAX_ABS_EXP; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1592 else |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1593 e = (int)abs_exp; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1594 if (esign) |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1595 e = -e; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1596 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1597 /* 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
|
1598 if (s == s1 && !lz) |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1599 s = s00; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1600 } |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1601 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1602 /* 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
|
1603 e -= nd - nd0; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1604 if (nd0 <= 0) |
|
58360
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1605 nd0 = nd; |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1606 |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1607 /* 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
|
1608 if (se) |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1609 *se = (char *)s; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1610 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1611 /* 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
|
1612 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
|
1613 if (!nd) |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1614 goto ret; |
|
58360
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1615 for (i = nd; i > 0; ) { |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1616 --i; |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1617 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
|
1618 ++i; |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1619 break; |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1620 } |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1621 } |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1622 e += nd - i; |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1623 nd = i; |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1624 if (nd0 > nd) |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1625 nd0 = nd; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1626 |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1627 /* 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
|
1628 * 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
|
1629 * |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1630 * - 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
|
1631 * |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1632 * - 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
|
1633 * 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
|
1634 * 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
|
1635 * and trailing zeros). |
|
58360
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1636 * |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1637 * - 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
|
1638 * 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
|
1639 * 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
|
1640 * 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
|
1641 * 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
|
1642 * |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1643 * - 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
|
1644 * 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
|
1645 * 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
|
1646 * 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
|
1647 * |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1648 * - 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
|
1649 * |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1650 * - 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
|
1651 */ |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1652 |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1653 /* 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
|
1654 * |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1655 * - 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
|
1656 * significant digits |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1657 * |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1658 * - 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
|
1659 * 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
|
1660 * 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
|
1661 */ |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1662 |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1663 bc.e0 = e1 = e; |
|
58360
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1664 y = z = 0; |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1665 for (i = 0; i < nd; i++) { |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1666 if (i < 9) |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1667 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
|
1668 else if (i < DBL_DIG+1) |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1669 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
|
1670 else |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1671 break; |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1672 } |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1673 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1674 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
|
1675 dval(&rv) = y; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1676 if (k > 9) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1677 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
|
1678 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1679 bd0 = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1680 if (nd <= DBL_DIG |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1681 && Flt_Rounds == 1 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1682 ) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1683 if (!e) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1684 goto ret; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1685 if (e > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1686 if (e <= Ten_pmax) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1687 dval(&rv) *= tens[e]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1688 goto ret; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1689 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1690 i = DBL_DIG - nd; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1691 if (e <= Ten_pmax + i) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1692 /* 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
|
1693 * this for larger i values. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1694 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1695 e -= i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1696 dval(&rv) *= tens[i]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1697 dval(&rv) *= tens[e]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1698 goto ret; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1699 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1700 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1701 else if (e >= -Ten_pmax) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1702 dval(&rv) /= tens[-e]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1703 goto ret; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1704 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1705 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1706 e1 += nd - k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1707 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1708 bc.scale = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1709 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1710 /* Get starting approximation = rv * 10**e1 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1711 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1712 if (e1 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1713 if ((i = e1 & 15)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1714 dval(&rv) *= tens[i]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1715 if (e1 &= ~15) { |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1716 if (e1 > DBL_MAX_10_EXP) |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1717 goto ovfl; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1718 e1 >>= 4; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1719 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
|
1720 if (e1 & 1) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1721 dval(&rv) *= bigtens[j]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1722 /* The last multiplication could overflow. */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1723 word0(&rv) -= P*Exp_msk1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1724 dval(&rv) *= bigtens[j]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1725 if ((z = word0(&rv) & Exp_mask) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1726 > Exp_msk1*(DBL_MAX_EXP+Bias-P)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1727 goto ovfl; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1728 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
|
1729 /* set to largest number */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1730 /* (Can't trust DBL_MAX) */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1731 word0(&rv) = Big0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1732 word1(&rv) = Big1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1733 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1734 else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1735 word0(&rv) += P*Exp_msk1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1736 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1737 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1738 else if (e1 < 0) { |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1739 /* 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
|
1740 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1741 If e1 <= -512, underflow immediately. |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1742 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
|
1743 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1744 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
|
1745 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
|
1746 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
|
1747 not be set. */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1748 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1749 e1 = -e1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1750 if ((i = e1 & 15)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1751 dval(&rv) /= tens[i]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1752 if (e1 >>= 4) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1753 if (e1 >= 1 << n_bigtens) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1754 goto undfl; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1755 if (e1 & Scale_Bit) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1756 bc.scale = 2*P; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1757 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
|
1758 if (e1 & 1) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1759 dval(&rv) *= tinytens[j]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1760 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
|
1761 >> Exp_shift)) > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1762 /* 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
|
1763 if (j >= 32) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1764 word1(&rv) = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1765 if (j >= 53) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1766 word0(&rv) = (P+2)*Exp_msk1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1767 else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1768 word0(&rv) &= 0xffffffff << (j-32); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1769 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1770 else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1771 word1(&rv) &= 0xffffffff << j; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1772 } |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1773 if (!dval(&rv)) |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1774 goto undfl; |
|
53185
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 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1778 /* 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
|
1779 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1780 /* 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
|
1781 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1782 bc.nd = nd; |
|
58279
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
1783 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
|
1784 /* 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
|
1785 /* possibly not being initialized. */ |
|
58279
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
1786 if (nd > STRTOD_DIGLIM) { |
|
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
1787 /* 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
|
1788 /* 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
|
1789 /* in IEEE arithmetic. */ |
|
58360
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1790 |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1791 /* 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
|
1792 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
|
1793 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
|
1794 for (i = 18; i > 0; ) { |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1795 /* 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
|
1796 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
|
1797 --i; |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1798 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
|
1799 ++i; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1800 break; |
|
58360
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1801 } |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1802 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1803 e += nd - i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1804 nd = i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1805 if (nd0 > nd) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1806 nd0 = nd; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1807 if (nd < 9) { /* must recompute y */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1808 y = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1809 for(i = 0; i < nd0; ++i) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1810 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
|
1811 for(; i < nd; ++i) |
|
6351d3d53ded
Merged revisions 77519,77530,77533 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58320
diff
changeset
|
1812 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
|
1813 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1814 } |
|
58320
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1815 bd0 = s2b(s0, nd0, nd, y); |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1816 if (bd0 == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1817 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1818 |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1819 /* Notation for the comments below. Write: |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1820 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1821 - 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
|
1822 decimal input string. |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1823 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1824 - 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
|
1825 Otherwise, set tdv == dv. |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1826 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1827 - 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
|
1828 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
|
1829 in an IEEE 754 double. |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1830 */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1831 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1832 for(;;) { |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1833 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1834 /* 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
|
1835 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1836 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
|
1837 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
|
1838 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
|
1839 approximation if not. |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1840 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1841 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
|
1842 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
|
1843 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
|
1844 |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
|
1845 */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1846 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1847 bd = Balloc(bd0->k); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1848 if (bd == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1849 Bfree(bd0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1850 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1851 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1852 Bcopy(bd, bd0); |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1853 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
|
1854 if (bb == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1855 Bfree(bd); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1856 Bfree(bd0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1857 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1858 } |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1859 /* 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
|
1860 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
|
1861 odd = bb->x[0] & 1; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1862 |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1863 /* 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
|
1864 bs = i2b(1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1865 if (bs == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1866 Bfree(bb); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1867 Bfree(bd); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1868 Bfree(bd0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1869 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1870 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1871 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1872 if (e >= 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1873 bb2 = bb5 = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1874 bd2 = bd5 = e; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1875 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1876 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1877 bb2 = bb5 = -e; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1878 bd2 = bd5 = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1879 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1880 if (bbe >= 0) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1881 bb2 += bbe; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1882 else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1883 bd2 -= bbe; |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1884 bs2 = bb2; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1885 bb2++; |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1886 bd2++; |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1887 |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1888 /* At this stage bd5 - bb5 == e == bd2 - bb2 + bbe, bb2 - bs2 == 1, |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1889 and bs == 1, so: |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1890 |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1891 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
|
1892 srv == bb * 2**bbe = bb * 2**(bbe - bb2 + bb2) |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1893 0.5 ulp(srv) == 2**(bbe-1) = bs * 2**(bbe - bb2 + bs2) |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1894 |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1895 It follows that: |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1896 |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1897 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
|
1898 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
|
1899 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
|
1900 |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1901 for some constant M. (Actually, M == 2**(bb2 - bbe) * 5**bb5, but |
|
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1902 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
|
1903 */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1904 |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
1905 /* 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
|
1906 i = bb2 < bd2 ? bb2 : bd2; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1907 if (i > bs2) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1908 i = bs2; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1909 if (i > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1910 bb2 -= i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1911 bd2 -= i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1912 bs2 -= i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1913 } |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1914 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1915 /* 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
|
1916 if (bb5 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1917 bs = pow5mult(bs, bb5); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1918 if (bs == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1919 Bfree(bb); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1920 Bfree(bd); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1921 Bfree(bd0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1922 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1923 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1924 bb1 = mult(bs, bb); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1925 Bfree(bb); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1926 bb = bb1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1927 if (bb == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1928 Bfree(bs); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1929 Bfree(bd); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1930 Bfree(bd0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1931 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1932 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1933 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1934 if (bb2 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1935 bb = lshift(bb, bb2); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1936 if (bb == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1937 Bfree(bs); |
|
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 (bd5 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1944 bd = pow5mult(bd, bd5); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1945 if (bd == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1946 Bfree(bb); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1947 Bfree(bs); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1948 Bfree(bd0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1949 goto failed_malloc; |
|
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 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1952 if (bd2 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1953 bd = lshift(bd, bd2); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1954 if (bd == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1955 Bfree(bb); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1956 Bfree(bs); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1957 Bfree(bd0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1958 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1959 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1960 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1961 if (bs2 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1962 bs = lshift(bs, bs2); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1963 if (bs == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1964 Bfree(bb); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1965 Bfree(bd); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1966 Bfree(bd0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1967 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1968 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1969 } |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1970 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1971 /* 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
|
1972 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
|
1973 with 0.5 ulp(srv). */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1974 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1975 delta = diff(bb, bd); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1976 if (delta == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1977 Bfree(bb); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1978 Bfree(bs); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1979 Bfree(bd); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1980 Bfree(bd0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1981 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1982 } |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
1983 dsign = delta->sign; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1984 delta->sign = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1985 i = cmp(delta, bs); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1986 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
|
1987 if (dsign) |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
1988 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
|
1989 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1990 /* 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
|
1991 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
|
1992 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
|
1993 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
|
1994 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
|
1995 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
1996 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
|
1997 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
|
1998 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
|
1999 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
|
2000 |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
2001 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
|
2002 /* 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
|
2003 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
|
2004 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
|
2005 /* 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
|
2006 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
|
2007 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
|
2008 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
|
2009 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
|
2010 } |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
2011 } |
|
ce11c1270b69
Merged revisions 77477-77478,77481-77483,77490-77493 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58279
diff
changeset
|
2012 |
|
53185
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 bc.nd = nd; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2015 i = -1; /* Discarded digits make delta smaller. */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2016 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2017 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2018 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2019 if (i < 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2020 /* 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
|
2021 * 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
|
2022 */ |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2023 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
|
2024 || (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
|
2025 ) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2026 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2027 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2028 if (!delta->x[0] && delta->wds <= 1) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2029 /* exact result */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2030 break; |
|
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 delta = lshift(delta,Log2P); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2033 if (delta == NULL) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2034 Bfree(bb); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2035 Bfree(bs); |
|
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 if (cmp(delta, bs) > 0) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2041 goto drop_down; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2042 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2043 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2044 if (i == 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2045 /* exactly half-way between */ |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2046 if (dsign) { |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2047 if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2048 && word1(&rv) == ( |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2049 (bc.scale && |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2050 (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
|
2051 (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
|
2052 0xffffffff)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2053 /*boundary case -- increment exponent*/ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2054 word0(&rv) = (word0(&rv) & Exp_mask) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2055 + Exp_msk1 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2056 ; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2057 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
|
2058 /* dsign = 0; */ |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2059 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2060 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2061 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2062 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
|
2063 drop_down: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2064 /* boundary case -- decrement exponent */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2065 if (bc.scale) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2066 L = word0(&rv) & Exp_mask; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2067 if (L <= (2*P+1)*Exp_msk1) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2068 if (L > (P+2)*Exp_msk1) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2069 /* round even ==> */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2070 /* accept rv */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2071 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2072 /* rv = smallest denormal */ |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2073 if (bc.nd > nd) |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2074 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2075 goto undfl; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2076 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2077 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2078 L = (word0(&rv) & Exp_mask) - Exp_msk1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2079 word0(&rv) = L | Bndry_mask1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2080 word1(&rv) = 0xffffffff; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2081 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2082 } |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
2083 if (!odd) |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2084 break; |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2085 if (dsign) |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
2086 dval(&rv) += sulp(&rv, &bc); |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2087 else { |
|
58467
be12d3621519
Merged revisions 77691,77698,77713-77714 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58427
diff
changeset
|
2088 dval(&rv) -= sulp(&rv, &bc); |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2089 if (!dval(&rv)) { |
|
58279
c32d3b08fcdc
Merged revisions 77410,77421,77450-77451 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58154
diff
changeset
|
2090 if (bc.nd >nd) |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2091 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2092 goto undfl; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2093 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2094 } |
|
68102
e2f96bd29252
Issue #8914: fix various warnings from the Clang static analyzer v254.
Brett Cannon <bcannon@gmail.com>
parents:
61547
diff
changeset
|
2095 /* dsign = 1 - dsign; */ |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2096 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2097 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2098 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
|
2099 if (dsign) |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2100 aadj = aadj1 = 1.; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2101 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
|
2102 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
|
2103 if (bc.nd >nd) |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2104 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2105 goto undfl; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2106 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2107 aadj = 1.; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2108 aadj1 = -1.; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2109 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2110 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2111 /* 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
|
2112 /* rounded down... */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2113 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2114 if (aadj < 2./FLT_RADIX) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2115 aadj = 1./FLT_RADIX; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2116 else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2117 aadj *= 0.5; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2118 aadj1 = -aadj; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2119 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2120 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2121 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2122 aadj *= 0.5; |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2123 aadj1 = dsign ? aadj : -aadj; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2124 if (Flt_Rounds == 0) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2125 aadj1 += 0.5; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2126 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2127 y = word0(&rv) & Exp_mask; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2128 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2129 /* Check for overflow */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2130 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2131 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
|
2132 dval(&rv0) = dval(&rv); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2133 word0(&rv) -= P*Exp_msk1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2134 adj.d = aadj1 * ulp(&rv); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2135 dval(&rv) += adj.d; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2136 if ((word0(&rv) & Exp_mask) >= |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2137 Exp_msk1*(DBL_MAX_EXP+Bias-P)) { |
|
58391
b9888c1339df
Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58360
diff
changeset
|
2138 if (word0(&rv0) == Big0 && word1(&rv0) == Big1) { |
|
b9888c1339df
Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58360
diff
changeset
|
2139 Bfree(bb); |
|
b9888c1339df
Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58360
diff
changeset
|
2140 Bfree(bd); |
|
b9888c1339df
Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58360
diff
changeset
|
2141 Bfree(bs); |
|
b9888c1339df
Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58360
diff
changeset
|
2142 Bfree(bd0); |
|
b9888c1339df
Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58360
diff
changeset
|
2143 Bfree(delta); |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2144 goto ovfl; |
|
58391
b9888c1339df
Merged revisions 77578 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58360
diff
changeset
|
2145 } |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2146 word0(&rv) = Big0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2147 word1(&rv) = Big1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2148 goto cont; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2149 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2150 else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2151 word0(&rv) += P*Exp_msk1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2152 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2153 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2154 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
|
2155 if (aadj <= 0x7fffffff) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2156 if ((z = (ULong)aadj) <= 0) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2157 z = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2158 aadj = z; |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2159 aadj1 = dsign ? aadj : -aadj; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2160 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2161 dval(&aadj2) = aadj1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2162 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
|
2163 aadj1 = dval(&aadj2); |
|
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 adj.d = aadj1 * ulp(&rv); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2166 dval(&rv) += adj.d; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2167 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2168 z = word0(&rv) & Exp_mask; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2169 if (bc.nd == nd) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2170 if (!bc.scale) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2171 if (y == z) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2172 /* Can we stop now? */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2173 L = (Long)aadj; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2174 aadj -= L; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2175 /* The tolerances below are conservative. */ |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2176 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
|
2177 if (aadj < .4999999 || aadj > .5000001) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2178 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2179 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2180 else if (aadj < .4999999/FLT_RADIX) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2181 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2182 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2183 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2184 cont: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2185 Bfree(bb); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2186 Bfree(bd); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2187 Bfree(bs); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2188 Bfree(delta); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2189 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2190 Bfree(bb); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2191 Bfree(bd); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2192 Bfree(bs); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2193 Bfree(bd0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2194 Bfree(delta); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2195 if (bc.nd > nd) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2196 error = bigcomp(&rv, s0, &bc); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2197 if (error) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2198 goto failed_malloc; |
|
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 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2201 if (bc.scale) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2202 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
|
2203 word1(&rv0) = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2204 dval(&rv) *= dval(&rv0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2205 } |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2206 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2207 ret: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2208 return sign ? -dval(&rv) : dval(&rv); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2209 |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2210 parse_error: |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2211 return 0.0; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2212 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2213 failed_malloc: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2214 errno = ENOMEM; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2215 return -1.0; |
|
58427
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2216 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2217 undfl: |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2218 return sign ? -0.0 : 0.0; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2219 |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2220 ovfl: |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2221 errno = ERANGE; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2222 /* Can't trust HUGE_VAL */ |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2223 word0(&rv) = Exp_mask; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2224 word1(&rv) = 0; |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2225 return sign ? -dval(&rv) : dval(&rv); |
|
f38c1196d9ff
Merged revisions 77614-77616,77663 via svnmerge from
Mark Dickinson <dickinsm@gmail.com>
parents:
58402
diff
changeset
|
2226 |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2227 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2228 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2229 static char * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2230 rv_alloc(int i) |
|
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 int j, k, *r; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2233 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2234 j = sizeof(ULong); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2235 for(k = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2236 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
|
2237 j <<= 1) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2238 k++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2239 r = (int*)Balloc(k); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2240 if (r == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2241 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2242 *r = k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2243 return (char *)(r+1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2244 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2245 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2246 static char * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2247 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
|
2248 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2249 char *rv, *t; |
|
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 rv = rv_alloc(n); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2252 if (rv == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2253 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2254 t = rv; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2255 while((*t = *s++)) t++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2256 if (rve) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2257 *rve = t; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2258 return rv; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2259 } |
|
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 /* 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
|
2262 * 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
|
2263 * 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
|
2264 * when MULTIPLE_THREADS is not defined. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2265 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2266 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2267 void |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2268 _Py_dg_freedtoa(char *s) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2269 { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2270 Bigint *b = (Bigint *)((int *)s - 1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2271 b->maxwds = 1 << (b->k = *(int*)b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2272 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2273 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2274 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2275 /* 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
|
2276 * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2277 * 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
|
2278 * 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
|
2279 * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2280 * Modifications: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2281 * 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
|
2282 * 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
|
2283 * 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
|
2284 * 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
|
2285 * 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
|
2286 * 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
|
2287 * 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
|
2288 * 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
|
2289 * 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
|
2290 * 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
|
2291 * 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
|
2292 * 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
|
2293 * inequality. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2294 * 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
|
2295 * quantities. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2296 * 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
|
2297 * 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
|
2298 * to multiple-precision integers. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2299 * 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
|
2300 * 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
|
2301 * 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
|
2302 * 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
|
2303 * 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
|
2304 * "uniformly" distributed input, the probability is |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2305 * 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
|
2306 * calculation. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2307 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2308 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2309 /* 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
|
2310 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
|
2311 call to _Py_dg_freedtoa. */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2312 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2313 char * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2314 _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
|
2315 int *decpt, int *sign, char **rve) |
|
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 /* 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
|
2318 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
|
2319 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
|
2320 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
|
2321 then *decpt is set to 9999. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2322 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2323 mode: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2324 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
|
2325 and rounded to nearest. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2326 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
|
2327 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
|
2328 1e23 whereas mode 1 gives 9.999999999999999e22. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2329 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
|
2330 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
|
2331 that trailing zeros are suppressed. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2332 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
|
2333 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
|
2334 except that trailing zeros are suppressed, and |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2335 ndigits can be negative. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2336 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
|
2337 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
|
2338 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
|
2339 With IEEE arithmetic and compilation with |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2340 -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
|
2341 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
|
2342 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
|
2343 fast floating-point estimate (if applicable). |
|
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 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
|
2346 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2347 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
|
2348 to hold the suppressed trailing zeros. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2349 */ |
|
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 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
|
2352 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
|
2353 spec_case, try_quick; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2354 Long L; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2355 int denorm; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2356 ULong x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2357 Bigint *b, *b1, *delta, *mlo, *mhi, *S; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2358 U d2, eps, u; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2359 double ds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2360 char *s, *s0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2361 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2362 /* 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
|
2363 cleanup easier on error */ |
|
61547
8410f83fd159
Remove unnecessary assignments.
Mark Dickinson <dickinsm@gmail.com>
parents:
58467
diff
changeset
|
2364 mlo = mhi = S = 0; |
|
53185
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2365 s0 = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2366 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2367 u.d = dd; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2368 if (word0(&u) & Sign_bit) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2369 /* 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
|
2370 *sign = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2371 word0(&u) &= ~Sign_bit; /* clear sign bit */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2372 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2373 else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2374 *sign = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2375 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2376 /* quick return for Infinities, NaNs and zeros */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2377 if ((word0(&u) & Exp_mask) == Exp_mask) |
|
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 /* Infinity or NaN */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2380 *decpt = 9999; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2381 if (!word1(&u) && !(word0(&u) & 0xfffff)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2382 return nrv_alloc("Infinity", rve, 8); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2383 return nrv_alloc("NaN", rve, 3); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2384 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2385 if (!dval(&u)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2386 *decpt = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2387 return nrv_alloc("0", rve, 1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2388 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2389 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2390 /* 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
|
2391 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
|
2392 b = d2b(&u, &be, &bbits); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2393 if (b == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2394 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2395 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
|
2396 dval(&d2) = dval(&u); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2397 word0(&d2) &= Frac_mask1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2398 word0(&d2) |= Exp_11; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2399 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2400 /* 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
|
2401 * log10(x) = log(x) / log(10) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2402 * ~=~ 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
|
2403 * 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
|
2404 * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2405 * 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
|
2406 * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2407 * k = (i - Bias)*0.301029995663981 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2408 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2409 * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2410 * 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
|
2411 * 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
|
2412 * 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
|
2413 * 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
|
2414 * (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
|
2415 * 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
|
2416 * 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
|
2417 * 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
|
2418 * (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
|
2419 * but this is probably not worthwhile.) |
|
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 i -= Bias; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2423 denorm = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2424 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2425 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2426 /* d is denormalized */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2427 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2428 i = bbits + be + (Bias + (P-1) - 1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2429 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
|
2430 : word1(&u) << (32 - i); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2431 dval(&d2) = x; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2432 word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2433 i -= (Bias + (P-1) - 1) + 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2434 denorm = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2435 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2436 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
|
2437 i*0.301029995663981; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2438 k = (int)ds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2439 if (ds < 0. && ds != k) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2440 k--; /* want k = floor(ds) */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2441 k_check = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2442 if (k >= 0 && k <= Ten_pmax) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2443 if (dval(&u) < tens[k]) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2444 k--; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2445 k_check = 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 j = bbits - i - 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2448 if (j >= 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2449 b2 = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2450 s2 = j; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2451 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2452 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2453 b2 = -j; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2454 s2 = 0; |
|
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 (k >= 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2457 b5 = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2458 s5 = k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2459 s2 += k; |
|
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 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2462 b2 -= k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2463 b5 = -k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2464 s5 = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2465 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2466 if (mode < 0 || mode > 9) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2467 mode = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2468 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2469 try_quick = 1; |
|
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 if (mode > 5) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2472 mode -= 4; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2473 try_quick = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2474 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2475 leftright = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2476 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
|
2477 /* silence erroneous "gcc -Wall" warning. */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2478 switch(mode) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2479 case 0: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2480 case 1: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2481 i = 18; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2482 ndigits = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2483 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2484 case 2: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2485 leftright = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2486 /* no break */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2487 case 4: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2488 if (ndigits <= 0) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2489 ndigits = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2490 ilim = ilim1 = i = ndigits; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2491 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2492 case 3: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2493 leftright = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2494 /* no break */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2495 case 5: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2496 i = ndigits + k + 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2497 ilim = i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2498 ilim1 = i - 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2499 if (i <= 0) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2500 i = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2501 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2502 s0 = rv_alloc(i); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2503 if (s0 == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2504 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2505 s = s0; |
|
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 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2508 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
|
2509 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2510 /* 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
|
2511 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2512 i = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2513 dval(&d2) = dval(&u); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2514 k0 = k; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2515 ilim0 = ilim; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2516 ieps = 2; /* conservative */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2517 if (k > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2518 ds = tens[k&0xf]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2519 j = k >> 4; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2520 if (j & Bletch) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2521 /* prevent overflows */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2522 j &= Bletch - 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2523 dval(&u) /= bigtens[n_bigtens-1]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2524 ieps++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2525 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2526 for(; j; j >>= 1, i++) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2527 if (j & 1) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2528 ieps++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2529 ds *= bigtens[i]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2530 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2531 dval(&u) /= ds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2532 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2533 else if ((j1 = -k)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2534 dval(&u) *= tens[j1 & 0xf]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2535 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
|
2536 if (j & 1) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2537 ieps++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2538 dval(&u) *= bigtens[i]; |
|
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 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2541 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
|
2542 if (ilim1 <= 0) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2543 goto fast_failed; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2544 ilim = ilim1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2545 k--; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2546 dval(&u) *= 10.; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2547 ieps++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2548 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2549 dval(&eps) = ieps*dval(&u) + 7.; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2550 word0(&eps) -= (P-1)*Exp_msk1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2551 if (ilim == 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2552 S = mhi = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2553 dval(&u) -= 5.; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2554 if (dval(&u) > dval(&eps)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2555 goto one_digit; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2556 if (dval(&u) < -dval(&eps)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2557 goto no_digits; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2558 goto fast_failed; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2559 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2560 if (leftright) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2561 /* Use Steele & White method of only |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2562 * generating digits needed. |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2563 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2564 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
|
2565 for(i = 0;;) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2566 L = (Long)dval(&u); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2567 dval(&u) -= L; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2568 *s++ = '0' + (int)L; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2569 if (dval(&u) < dval(&eps)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2570 goto ret1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2571 if (1. - dval(&u) < dval(&eps)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2572 goto bump_up; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2573 if (++i >= ilim) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2574 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2575 dval(&eps) *= 10.; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2576 dval(&u) *= 10.; |
|
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 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2580 /* Generate ilim digits, then fix them up. */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2581 dval(&eps) *= tens[ilim-1]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2582 for(i = 1;; i++, dval(&u) *= 10.) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2583 L = (Long)(dval(&u)); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2584 if (!(dval(&u) -= L)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2585 ilim = i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2586 *s++ = '0' + (int)L; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2587 if (i == ilim) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2588 if (dval(&u) > 0.5 + dval(&eps)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2589 goto bump_up; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2590 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
|
2591 while(*--s == '0'); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2592 s++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2593 goto ret1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2594 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2595 break; |
|
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 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2598 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2599 fast_failed: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2600 s = s0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2601 dval(&u) = dval(&d2); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2602 k = k0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2603 ilim = ilim0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2604 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2605 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2606 /* Do we have a "small" integer? */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2607 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2608 if (be >= 0 && k <= Int_max) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2609 /* Yes. */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2610 ds = tens[k]; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2611 if (ndigits < 0 && ilim <= 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2612 S = mhi = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2613 if (ilim < 0 || dval(&u) <= 5*ds) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2614 goto no_digits; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2615 goto one_digit; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2616 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2617 for(i = 1;; i++, dval(&u) *= 10.) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2618 L = (Long)(dval(&u) / ds); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2619 dval(&u) -= L*ds; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2620 *s++ = '0' + (int)L; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2621 if (!dval(&u)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2622 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2623 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2624 if (i == ilim) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2625 dval(&u) += dval(&u); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2626 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
|
2627 bump_up: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2628 while(*--s == '9') |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2629 if (s == s0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2630 k++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2631 *s = '0'; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2632 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2633 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2634 ++*s++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2635 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2636 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2637 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2638 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2639 goto ret1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2640 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2641 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2642 m2 = b2; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2643 m5 = b5; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2644 if (leftright) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2645 i = |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2646 denorm ? be + (Bias + (P-1) - 1 + 1) : |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2647 1 + P - bbits; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2648 b2 += i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2649 s2 += i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2650 mhi = i2b(1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2651 if (mhi == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2652 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2653 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2654 if (m2 > 0 && s2 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2655 i = m2 < s2 ? m2 : s2; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2656 b2 -= i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2657 m2 -= i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2658 s2 -= i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2659 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2660 if (b5 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2661 if (leftright) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2662 if (m5 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2663 mhi = pow5mult(mhi, m5); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2664 if (mhi == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2665 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2666 b1 = mult(mhi, b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2667 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2668 b = b1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2669 if (b == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2670 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2671 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2672 if ((j = b5 - m5)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2673 b = pow5mult(b, j); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2674 if (b == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2675 goto failed_malloc; |
|
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 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2678 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2679 b = pow5mult(b, b5); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2680 if (b == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2681 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2682 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2683 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2684 S = i2b(1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2685 if (S == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2686 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2687 if (s5 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2688 S = pow5mult(S, s5); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2689 if (S == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2690 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2691 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2692 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2693 /* 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
|
2694 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2695 spec_case = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2696 if ((mode < 2 || leftright) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2697 ) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2698 if (!word1(&u) && !(word0(&u) & Bndry_mask) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2699 && word0(&u) & (Exp_mask & ~Exp_msk1) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2700 ) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2701 /* The special case */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2702 b2 += Log2P; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2703 s2 += Log2P; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2704 spec_case = 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2705 } |
|
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 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2708 /* Arrange for convenient computation of quotients: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2709 * 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
|
2710 * |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2711 * 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
|
2712 * 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
|
2713 * 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
|
2714 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2715 #define iInc 28 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2716 i = dshift(S, s2); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2717 b2 += i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2718 m2 += i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2719 s2 += i; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2720 if (b2 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2721 b = lshift(b, b2); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2722 if (b == 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 (s2 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2726 S = lshift(S, s2); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2727 if (S == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2728 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2729 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2730 if (k_check) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2731 if (cmp(b,S) < 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2732 k--; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2733 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
|
2734 if (b == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2735 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2736 if (leftright) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2737 mhi = multadd(mhi, 10, 0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2738 if (mhi == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2739 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2740 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2741 ilim = ilim1; |
|
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 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2744 if (ilim <= 0 && (mode == 3 || mode == 5)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2745 if (ilim < 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2746 /* no digits, fcvt style */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2747 no_digits: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2748 k = -1 - ndigits; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2749 goto ret; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2750 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2751 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2752 S = multadd(S, 5, 0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2753 if (S == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2754 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2755 if (cmp(b, S) <= 0) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2756 goto no_digits; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2757 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2758 one_digit: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2759 *s++ = '1'; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2760 k++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2761 goto ret; |
|
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 if (leftright) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2764 if (m2 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2765 mhi = lshift(mhi, m2); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2766 if (mhi == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2767 goto failed_malloc; |
|
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 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2770 /* Compute mlo -- check for special case |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2771 * 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
|
2772 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2773 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2774 mlo = mhi; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2775 if (spec_case) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2776 mhi = Balloc(mhi->k); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2777 if (mhi == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2778 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2779 Bcopy(mhi, mlo); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2780 mhi = lshift(mhi, Log2P); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2781 if (mhi == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2782 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2783 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2784 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2785 for(i = 1;;i++) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2786 dig = quorem(b,S) + '0'; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2787 /* 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
|
2788 * that will round to d? |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2789 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2790 j = cmp(b, mlo); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2791 delta = diff(S, mhi); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2792 if (delta == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2793 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2794 j1 = delta->sign ? 1 : cmp(b, delta); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2795 Bfree(delta); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2796 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
|
2797 ) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2798 if (dig == '9') |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2799 goto round_9_up; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2800 if (j > 0) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2801 dig++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2802 *s++ = dig; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2803 goto ret; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2804 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2805 if (j < 0 || (j == 0 && mode != 1 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2806 && !(word1(&u) & 1) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2807 )) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2808 if (!b->x[0] && b->wds <= 1) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2809 goto accept_dig; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2810 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2811 if (j1 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2812 b = lshift(b, 1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2813 if (b == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2814 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2815 j1 = cmp(b, S); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2816 if ((j1 > 0 || (j1 == 0 && dig & 1)) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2817 && dig++ == '9') |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2818 goto round_9_up; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2819 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2820 accept_dig: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2821 *s++ = dig; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2822 goto ret; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2823 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2824 if (j1 > 0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2825 if (dig == '9') { /* possible if i == 1 */ |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2826 round_9_up: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2827 *s++ = '9'; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2828 goto roundoff; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2829 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2830 *s++ = dig + 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2831 goto ret; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2832 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2833 *s++ = dig; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2834 if (i == ilim) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2835 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2836 b = multadd(b, 10, 0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2837 if (b == 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 if (mlo == mhi) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2840 mlo = mhi = multadd(mhi, 10, 0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2841 if (mlo == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2842 goto failed_malloc; |
|
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 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2845 mlo = multadd(mlo, 10, 0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2846 if (mlo == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2847 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2848 mhi = multadd(mhi, 10, 0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2849 if (mhi == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2850 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2851 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2852 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2853 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2854 else |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2855 for(i = 1;; i++) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2856 *s++ = dig = quorem(b,S) + '0'; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2857 if (!b->x[0] && b->wds <= 1) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2858 goto ret; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2859 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2860 if (i >= ilim) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2861 break; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2862 b = multadd(b, 10, 0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2863 if (b == 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 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2866 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2867 /* Round off last digit */ |
|
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 b = lshift(b, 1); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2870 if (b == NULL) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2871 goto failed_malloc; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2872 j = cmp(b, S); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2873 if (j > 0 || (j == 0 && dig & 1)) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2874 roundoff: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2875 while(*--s == '9') |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2876 if (s == s0) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2877 k++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2878 *s++ = '1'; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2879 goto ret; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2880 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2881 ++*s++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2882 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2883 else { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2884 while(*--s == '0'); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2885 s++; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2886 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2887 ret: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2888 Bfree(S); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2889 if (mhi) { |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2890 if (mlo && mlo != mhi) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2891 Bfree(mlo); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2892 Bfree(mhi); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2893 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2894 ret1: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2895 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2896 *s = 0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2897 *decpt = k + 1; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2898 if (rve) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2899 *rve = s; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2900 return s0; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2901 failed_malloc: |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2902 if (S) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2903 Bfree(S); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2904 if (mlo && mlo != mhi) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2905 Bfree(mlo); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2906 if (mhi) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2907 Bfree(mhi); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2908 if (b) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2909 Bfree(b); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2910 if (s0) |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2911 _Py_dg_freedtoa(s0); |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2912 return NULL; |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2913 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2914 #ifdef __cplusplus |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2915 } |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2916 #endif |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2917 |
|
97ae7a709c1d
Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff
changeset
|
2918 #endif /* PY_NO_SHORT_FLOAT_REPR */ |
