annotate Python/dtoa.c @ 53787:c6376d3fa968

Issue #5920: Changed format.__float__ and complex.__float__ to use a precision of 12 when using the empty presentation type. This more closely matches str()'s behavior and reduces surprises when adding alignment flags to an empty format string. Patch by Mark Dickinson.
author Eric Smith <eric@trueblade.com>
date Tue, 05 May 2009 14:04:18 +0000
parents 13a82a710f19
children 4501b638fc3f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1 /****************************************************************
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
3 * The author of this software is David M. Gay.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
4 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
5 * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
6 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
7 * Permission to use, copy, modify, and distribute this software for any
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
8 * purpose without fee is hereby granted, provided that this entire notice
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
9 * is included in all copies of any software which is or includes a copy
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
10 * or modification of this software and in all copies of the supporting
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
11 * documentation for such software.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
12 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
13 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
14 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
15 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
16 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
17 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
18 ***************************************************************/
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
19
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
20 /****************************************************************
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
21 * This is dtoa.c by David M. Gay, downloaded from
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
22 * http://www.netlib.org/fp/dtoa.c on April 15, 2009 and modified for
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
23 * inclusion into the Python core by Mark E. T. Dickinson and Eric V. Smith.
53203
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
24 *
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
25 * Please remember to check http://www.netlib.org/fp regularly (and especially
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
26 * before any Python release) for bugfixes and updates.
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
27 *
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
28 * The major modifications from Gay's original code are as follows:
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
29 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
30 * 0. The original code has been specialized to Python's needs by removing
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
31 * many of the #ifdef'd sections. In particular, code to support VAX and
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
32 * IBM floating-point formats, hex NaNs, hex floats, locale-aware
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
33 * treatment of the decimal point, and setting of the inexact flag have
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
34 * been removed.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
35 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
36 * 1. We use PyMem_Malloc and PyMem_Free in place of malloc and free.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
37 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
38 * 2. The public functions strtod, dtoa and freedtoa all now have
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
39 * a _Py_dg_ prefix.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
40 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
41 * 3. Instead of assuming that PyMem_Malloc always succeeds, we thread
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
42 * PyMem_Malloc failures through the code. The functions
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
43 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
44 * Balloc, multadd, s2b, i2b, mult, pow5mult, lshift, diff, d2b
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
45 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
46 * of return type *Bigint all return NULL to indicate a malloc failure.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
47 * Similarly, rv_alloc and nrv_alloc (return type char *) return NULL on
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
48 * failure. bigcomp now has return type int (it used to be void) and
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
49 * returns -1 on failure and 0 otherwise. _Py_dg_dtoa returns NULL
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
50 * on failure. _Py_dg_strtod indicates failure due to malloc failure
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
51 * by returning -1.0, setting errno=ENOMEM and *se to s00.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
52 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
53 * 4. The static variable dtoa_result has been removed. Callers of
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
54 * _Py_dg_dtoa are expected to call _Py_dg_freedtoa to free
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
55 * the memory allocated by _Py_dg_dtoa.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
56 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
57 * 5. The code has been reformatted to better fit with Python's
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
58 * C style guide (PEP 7).
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
59 *
53203
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
60 * 6. A bug in the memory allocation has been fixed: to avoid FREEing memory
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
61 * that hasn't been MALLOC'ed, private_mem should only be used when k <=
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
62 * Kmax.
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
63 *
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53207
diff changeset
64 * 7. _Py_dg_strtod has been modified so that it doesn't accept strings with
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53207
diff changeset
65 * leading whitespace.
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53207
diff changeset
66 *
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
67 ***************************************************************/
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
68
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
69 /* Please send bug reports for the original dtoa.c code to David M. Gay (dmg
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
70 * at acm dot org, with " at " changed at "@" and " dot " changed to ".").
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
71 * Please report bugs for this modified version using the Python issue tracker
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
72 * (http://bugs.python.org). */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
73
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
74 /* On a machine with IEEE extended-precision registers, it is
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
75 * necessary to specify double-precision (53-bit) rounding precision
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
76 * before invoking strtod or dtoa. If the machine uses (the equivalent
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
77 * of) Intel 80x87 arithmetic, the call
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
78 * _control87(PC_53, MCW_PC);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
79 * does this with many compilers. Whether this or another call is
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
80 * appropriate depends on the compiler; for this to work, it may be
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
81 * necessary to #include "float.h" or another system-dependent header
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
82 * file.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
83 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
84
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
85 /* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
86 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
87 * This strtod returns a nearest machine number to the input decimal
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
88 * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
89 * broken by the IEEE round-even rule. Otherwise ties are broken by
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
90 * biased rounding (add half and chop).
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
91 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
92 * Inspired loosely by William D. Clinger's paper "How to Read Floating
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
93 * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
94 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
95 * Modifications:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
96 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
97 * 1. We only require IEEE, IBM, or VAX double-precision
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
98 * arithmetic (not IEEE double-extended).
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
99 * 2. We get by with floating-point arithmetic in a case that
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
100 * Clinger missed -- when we're computing d * 10^n
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
101 * for a small integer d and the integer n is not too
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
102 * much larger than 22 (the maximum integer k for which
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
103 * we can represent 10^k exactly), we may be able to
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
104 * compute (d*10^k) * 10^(e-k) with just one roundoff.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
105 * 3. Rather than a bit-at-a-time adjustment of the binary
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
106 * result in the hard case, we use floating-point
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
107 * arithmetic to determine the adjustment to within
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
108 * one bit; only in really hard cases do we need to
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
109 * compute a second residual.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
110 * 4. Because of 3., we don't need a large table of powers of 10
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
111 * for ten-to-e (just some small tables, e.g. of 10^k
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
112 * for 0 <= k <= 22).
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
113 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
114
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
115 /* Linking of Python's #defines to Gay's #defines starts here. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
116
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
117 #include "Python.h"
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
118
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
119 /* if PY_NO_SHORT_FLOAT_REPR is defined, then don't even try to compile
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
120 the following code */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
121 #ifndef PY_NO_SHORT_FLOAT_REPR
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
122
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
123 #include "float.h"
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
124
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
125 #define MALLOC PyMem_Malloc
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
126 #define FREE PyMem_Free
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
127
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
128 /* This code should also work for ARM mixed-endian format on little-endian
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
129 machines, where doubles have byte order 45670123 (in increasing address
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
130 order, 0 being the least significant byte). */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
131 #ifdef DOUBLE_IS_LITTLE_ENDIAN_IEEE754
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
132 # define IEEE_8087
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
133 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
134 #if defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) || \
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
135 defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
136 # define IEEE_MC68k
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
137 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
138 #if defined(IEEE_8087) + defined(IEEE_MC68k) != 1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
139 #error "Exactly one of IEEE_8087 or IEEE_MC68k should be defined."
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
140 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
141
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
142 /* The code below assumes that the endianness of integers matches the
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
143 endianness of the two 32-bit words of a double. Check this. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
144 #if defined(WORDS_BIGENDIAN) && (defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) || \
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
145 defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
146 #error "doubles and ints have incompatible endianness"
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
147 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
148
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
149 #if !defined(WORDS_BIGENDIAN) && defined(DOUBLE_IS_BIG_ENDIAN_IEEE754)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
150 #error "doubles and ints have incompatible endianness"
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
151 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
152
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
153
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
154 #if defined(HAVE_UINT32_T) && defined(HAVE_INT32_T)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
155 typedef PY_UINT32_T ULong;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
156 typedef PY_INT32_T Long;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
157 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
158 #error "Failed to find an exact-width 32-bit integer type"
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
159 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
160
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
161 #if defined(HAVE_UINT64_T)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
162 #define ULLong PY_UINT64_T
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
163 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
164 #undef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
165 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
166
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
167 #undef DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
168 #ifdef Py_DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
169 #define DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
170 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
171
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
172 /* End Python #define linking */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
173
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
174 #ifdef DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
175 #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
176 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
177
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
178 #ifndef PRIVATE_MEM
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
179 #define PRIVATE_MEM 2304
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
180 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
181 #define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
182 static double private_mem[PRIVATE_mem], *pmem_next = private_mem;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
183
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
184 #ifdef __cplusplus
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
185 extern "C" {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
186 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
187
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
188 typedef union { double d; ULong L[2]; } U;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
189
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
190 #ifdef IEEE_8087
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
191 #define word0(x) (x)->L[1]
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
192 #define word1(x) (x)->L[0]
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
193 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
194 #define word0(x) (x)->L[0]
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
195 #define word1(x) (x)->L[1]
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
196 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
197 #define dval(x) (x)->d
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
198
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
199 #ifndef STRTOD_DIGLIM
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
200 #define STRTOD_DIGLIM 40
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
201 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
202
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
203 #ifdef DIGLIM_DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
204 extern int strtod_diglim;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
205 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
206 #define strtod_diglim STRTOD_DIGLIM
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
207 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
208
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
209 /* 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
210 * 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
211 * #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
212 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
213 #if defined(IEEE_8087)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
214 #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
215 ((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
216 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
217 #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
218 ((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
219 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
220
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
221 /* #define P DBL_MANT_DIG */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
222 /* 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
223 /* 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
224 /* 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
225 /* 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
226
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
227 #define Exp_shift 20
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
228 #define Exp_shift1 20
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
229 #define Exp_msk1 0x100000
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
230 #define Exp_msk11 0x100000
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
231 #define Exp_mask 0x7ff00000
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
232 #define P 53
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
233 #define Nbits 53
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
234 #define Bias 1023
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
235 #define Emax 1023
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
236 #define Emin (-1022)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
237 #define Exp_1 0x3ff00000
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
238 #define Exp_11 0x3ff00000
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
239 #define Ebits 11
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
240 #define Frac_mask 0xfffff
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
241 #define Frac_mask1 0xfffff
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
242 #define Ten_pmax 22
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
243 #define Bletch 0x10
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
244 #define Bndry_mask 0xfffff
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
245 #define Bndry_mask1 0xfffff
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
246 #define LSB 1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
247 #define Sign_bit 0x80000000
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
248 #define Log2P 1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
249 #define Tiny0 0
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
250 #define Tiny1 1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
251 #define Quick_max 14
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
252 #define Int_max 14
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
253
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
254 #ifndef Flt_Rounds
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
255 #ifdef FLT_ROUNDS
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
256 #define Flt_Rounds FLT_ROUNDS
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
257 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
258 #define Flt_Rounds 1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
259 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
260 #endif /*Flt_Rounds*/
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
261
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
262 #define Rounding Flt_Rounds
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
263
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
264 #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
265 #define Big1 0xffffffff
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
266
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
267 #ifndef NAN_WORD0
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
268 #define NAN_WORD0 0x7ff80000
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
269 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
270
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
271 #ifndef NAN_WORD1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
272 #define NAN_WORD1 0
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
273 #endif
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 /* 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
277
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
278 typedef struct BCinfo BCinfo;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
279 struct
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
280 BCinfo {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
281 int dp0, dp1, dplen, dsign, e0, inexact;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
282 int nd, nd0, rounding, scale, uflchk;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
283 };
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 #define FFFFFFFF 0xffffffffUL
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 #define Kmax 7
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
288
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
289 /* 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
290 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
291 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
292 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
293
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
294 The Bigint fields are as follows:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
295
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
296 - 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
297 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
298 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
299 - 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
300 - 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
301 (usually maxwds == 2**k)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
302 - 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
303 (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
304 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
305 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
306 - 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
307 - 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
308 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
309 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
310
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
311 struct
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
312 Bigint {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
313 struct Bigint *next;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
314 int k, maxwds, sign, wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
315 ULong x[1];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
316 };
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 typedef struct Bigint Bigint;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
319
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
320 /* 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
321 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
322 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
323 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
324
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
325 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
326 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
327 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
328 in preference to using MALLOC.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
329
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
330 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
331 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
332 FREE.
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 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
335 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
336 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
337 performance on impact. */
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 static Bigint *freelist[Kmax+1];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
340
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
341 /* 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
342
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
343 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
344 Balloc(int k)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
345 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
346 int x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
347 Bigint *rv;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
348 unsigned int len;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
349
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
350 if (k <= Kmax && (rv = freelist[k]))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
351 freelist[k] = rv->next;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
352 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
353 x = 1 << k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
354 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
355 /sizeof(double);
53203
ab06a38b590c Add reminder to dtoa.c to check for updates regularly.
Mark Dickinson <dickinsm@gmail.com>
parents: 53185
diff changeset
356 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
357 rv = (Bigint*)pmem_next;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
358 pmem_next += len;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
359 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
360 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
361 rv = (Bigint*)MALLOC(len*sizeof(double));
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
362 if (rv == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
363 return NULL;
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 rv->k = k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
366 rv->maxwds = x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
367 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
368 rv->sign = rv->wds = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
369 return rv;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
370 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
371
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
372 /* Free a Bigint allocated with Balloc */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
373
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
374 static void
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
375 Bfree(Bigint *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 if (v) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
378 if (v->k > Kmax)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
379 FREE((void*)v);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
380 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
381 v->next = freelist[v->k];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
382 freelist[v->k] = v;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
383 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
384 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
385 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
386
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
387 #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
388 y->wds*sizeof(Long) + 2*sizeof(int))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
389
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
390 /* 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
391 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
392 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
393
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
394 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
395 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
396 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
397 int i, wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
398 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
399 ULong *x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
400 ULLong carry, y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
401 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
402 ULong carry, *x, y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
403 ULong xi, z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
404 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
405 Bigint *b1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
406
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
407 wds = b->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
408 x = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
409 i = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
410 carry = a;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
411 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
412 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
413 y = *x * (ULLong)m + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
414 carry = y >> 32;
53207
fe99a562b708 Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents: 53203
diff changeset
415 *x++ = (ULong)(y & FFFFFFFF);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
416 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
417 xi = *x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
418 y = (xi & 0xffff) * m + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
419 z = (xi >> 16) * m + (y >> 16);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
420 carry = z >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
421 *x++ = (z << 16) + (y & 0xffff);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
422 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
423 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
424 while(++i < wds);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
425 if (carry) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
426 if (wds >= b->maxwds) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
427 b1 = Balloc(b->k+1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
428 if (b1 == NULL){
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
429 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
430 return NULL;
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 Bcopy(b1, b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
433 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
434 b = b1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
435 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
436 b->x[wds++] = (ULong)carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
437 b->wds = wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
438 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
439 return b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
440 }
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 /* 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
443 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
444 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
445 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
446 NULL on failure. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
447
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
448 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
449 s2b(const char *s, int nd0, int nd, ULong y9, int dplen)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
450 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
451 Bigint *b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
452 int i, k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
453 Long x, y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
454
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
455 x = (nd + 8) / 9;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
456 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
457 b = Balloc(k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
458 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
459 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
460 b->x[0] = y9;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
461 b->wds = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
462
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
463 i = 9;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
464 if (9 < nd0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
465 s += 9;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
466 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
467 b = multadd(b, 10, *s++ - '0');
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
468 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
469 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
470 } while(++i < nd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
471 s += dplen;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
472 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
473 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
474 s += dplen + 9;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
475 for(; i < nd; i++) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
476 b = multadd(b, 10, *s++ - '0');
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
477 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
478 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
479 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
480 return b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
481 }
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 /* 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
484
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
485 static int
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
486 hi0bits(ULong x)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
487 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
488 int k = 0;
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 if (!(x & 0xffff0000)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
491 k = 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
492 x <<= 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
493 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
494 if (!(x & 0xff000000)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
495 k += 8;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
496 x <<= 8;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
497 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
498 if (!(x & 0xf0000000)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
499 k += 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
500 x <<= 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
501 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
502 if (!(x & 0xc0000000)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
503 k += 2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
504 x <<= 2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
505 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
506 if (!(x & 0x80000000)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
507 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
508 if (!(x & 0x40000000))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
509 return 32;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
510 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
511 return k;
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
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
514 /* 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
515 number of bits. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
516
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
517 static int
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
518 lo0bits(ULong *y)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
519 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
520 int k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
521 ULong x = *y;
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 & 7) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
524 if (x & 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
525 return 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
526 if (x & 2) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
527 *y = x >> 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
528 return 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
529 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
530 *y = x >> 2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
531 return 2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
532 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
533 k = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
534 if (!(x & 0xffff)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
535 k = 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
536 x >>= 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
537 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
538 if (!(x & 0xff)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
539 k += 8;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
540 x >>= 8;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
541 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
542 if (!(x & 0xf)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
543 k += 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
544 x >>= 4;
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 if (!(x & 0x3)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
547 k += 2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
548 x >>= 2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
549 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
550 if (!(x & 1)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
551 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
552 x >>= 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
553 if (!x)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
554 return 32;
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 *y = x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
557 return k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
558 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
559
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
560 /* 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
561
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
562 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
563 i2b(int i)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
564 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
565 Bigint *b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
566
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
567 b = Balloc(1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
568 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
569 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
570 b->x[0] = i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
571 b->wds = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
572 return b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
573 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
574
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
575 /* 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
576 the signs of a and b. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
577
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
578 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
579 mult(Bigint *a, Bigint *b)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
580 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
581 Bigint *c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
582 int k, wa, wb, wc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
583 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
584 ULong y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
585 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
586 ULLong carry, z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
587 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
588 ULong carry, z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
589 ULong z2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
590 #endif
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 if (a->wds < b->wds) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
593 c = a;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
594 a = b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
595 b = c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
596 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
597 k = a->k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
598 wa = a->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
599 wb = b->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
600 wc = wa + wb;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
601 if (wc > a->maxwds)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
602 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
603 c = Balloc(k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
604 if (c == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
605 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
606 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
607 *x = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
608 xa = a->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
609 xae = xa + wa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
610 xb = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
611 xbe = xb + wb;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
612 xc0 = c->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
613 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
614 for(; xb < xbe; xc0++) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
615 if ((y = *xb++)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
616 x = xa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
617 xc = xc0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
618 carry = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
619 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
620 z = *x++ * (ULLong)y + *xc + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
621 carry = z >> 32;
53207
fe99a562b708 Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents: 53203
diff changeset
622 *xc++ = (ULong)(z & FFFFFFFF);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
623 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
624 while(x < xae);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
625 *xc = (ULong)carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
626 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
627 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
628 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
629 for(; xb < xbe; xb++, xc0++) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
630 if (y = *xb & 0xffff) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
631 x = xa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
632 xc = xc0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
633 carry = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
634 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
635 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
636 carry = z >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
637 z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
638 carry = z2 >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
639 Storeinc(xc, z2, z);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
640 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
641 while(x < xae);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
642 *xc = carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
643 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
644 if (y = *xb >> 16) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
645 x = xa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
646 xc = xc0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
647 carry = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
648 z2 = *xc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
649 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
650 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
651 carry = z >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
652 Storeinc(xc, z, z2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
653 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
654 carry = z2 >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
655 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
656 while(x < xae);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
657 *xc = z2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
658 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
659 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
660 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
661 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
662 c->wds = wc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
663 return c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
664 }
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 /* 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
667
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
668 static Bigint *p5s;
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 /* 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
671 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
672 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
673
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
674 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
675 pow5mult(Bigint *b, int k)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
676 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
677 Bigint *b1, *p5, *p51;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
678 int i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
679 static int p05[3] = { 5, 25, 125 };
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
680
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
681 if ((i = k & 3)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
682 b = multadd(b, p05[i-1], 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
683 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
684 return NULL;
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
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
687 if (!(k >>= 2))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
688 return b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
689 p5 = p5s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
690 if (!p5) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
691 /* first time */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
692 p5 = i2b(625);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
693 if (p5 == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
694 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
695 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
696 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
697 p5s = p5;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
698 p5->next = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
699 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
700 for(;;) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
701 if (k & 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
702 b1 = mult(b, p5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
703 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
704 b = b1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
705 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
706 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
707 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
708 if (!(k >>= 1))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
709 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
710 p51 = p5->next;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
711 if (!p51) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
712 p51 = mult(p5,p5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
713 if (p51 == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
714 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
715 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
716 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
717 p51->next = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
718 p5->next = p51;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
719 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
720 p5 = p51;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
721 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
722 return b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
723 }
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 /* 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
726 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
727 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
728
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
729 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
730 lshift(Bigint *b, int k)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
731 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
732 int i, k1, n, n1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
733 Bigint *b1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
734 ULong *x, *x1, *xe, z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
735
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
736 n = k >> 5;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
737 k1 = b->k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
738 n1 = n + b->wds + 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
739 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
740 k1++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
741 b1 = Balloc(k1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
742 if (b1 == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
743 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
744 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
745 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
746 x1 = b1->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
747 for(i = 0; i < n; i++)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
748 *x1++ = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
749 x = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
750 xe = x + b->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
751 if (k &= 0x1f) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
752 k1 = 32 - k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
753 z = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
754 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
755 *x1++ = *x << k | z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
756 z = *x++ >> k1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
757 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
758 while(x < xe);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
759 if ((*x1 = z))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
760 ++n1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
761 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
762 else do
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
763 *x1++ = *x++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
764 while(x < xe);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
765 b1->wds = n1 - 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
766 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
767 return b1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
768 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
769
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
770 /* 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
771 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
772
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
773 static int
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
774 cmp(Bigint *a, Bigint *b)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
775 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
776 ULong *xa, *xa0, *xb, *xb0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
777 int i, j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
778
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
779 i = a->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
780 j = b->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
781 #ifdef DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
782 if (i > 1 && !a->x[i-1])
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
783 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
784 if (j > 1 && !b->x[j-1])
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
785 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
786 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
787 if (i -= j)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
788 return i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
789 xa0 = a->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
790 xa = xa0 + j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
791 xb0 = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
792 xb = xb0 + j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
793 for(;;) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
794 if (*--xa != *--xb)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
795 return *xa < *xb ? -1 : 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
796 if (xa <= xa0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
797 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
798 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
799 return 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
800 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
801
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
802 /* 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
803 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
804 result is set appropriately. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
805
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
806 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
807 diff(Bigint *a, Bigint *b)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
808 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
809 Bigint *c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
810 int i, wa, wb;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
811 ULong *xa, *xae, *xb, *xbe, *xc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
812 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
813 ULLong borrow, y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
814 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
815 ULong borrow, y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
816 ULong z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
817 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
818
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
819 i = cmp(a,b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
820 if (!i) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
821 c = Balloc(0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
822 if (c == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
823 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
824 c->wds = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
825 c->x[0] = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
826 return c;
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 if (i < 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
829 c = a;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
830 a = b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
831 b = c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
832 i = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
833 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
834 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
835 i = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
836 c = Balloc(a->k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
837 if (c == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
838 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
839 c->sign = i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
840 wa = a->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
841 xa = a->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
842 xae = xa + wa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
843 wb = b->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
844 xb = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
845 xbe = xb + wb;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
846 xc = c->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
847 borrow = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
848 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
849 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
850 y = (ULLong)*xa++ - *xb++ - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
851 borrow = y >> 32 & (ULong)1;
53207
fe99a562b708 Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents: 53203
diff changeset
852 *xc++ = (ULong)(y & FFFFFFFF);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
853 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
854 while(xb < xbe);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
855 while(xa < xae) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
856 y = *xa++ - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
857 borrow = y >> 32 & (ULong)1;
53207
fe99a562b708 Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents: 53203
diff changeset
858 *xc++ = (ULong)(y & FFFFFFFF);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
859 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
860 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
861 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
862 y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
863 borrow = (y & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
864 z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
865 borrow = (z & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
866 Storeinc(xc, z, y);
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 while(xb < xbe);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
869 while(xa < xae) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
870 y = (*xa & 0xffff) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
871 borrow = (y & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
872 z = (*xa++ >> 16) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
873 borrow = (z & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
874 Storeinc(xc, z, y);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
875 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
876 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
877 while(!*--xc)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
878 wa--;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
879 c->wds = wa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
880 return c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
881 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
882
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
883 /* Given a positive normal double x, return the difference between x and the next
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
884 double up. Doesn't give correct results for subnormals. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
885
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
886 static double
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
887 ulp(U *x)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
888 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
889 Long L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
890 U u;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
891
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
892 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
893 word0(&u) = L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
894 word1(&u) = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
895 return dval(&u);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
896 }
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 /* 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
899
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
900 static double
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
901 b2d(Bigint *a, int *e)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
902 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
903 ULong *xa, *xa0, w, y, z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
904 int k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
905 U d;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
906
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
907 xa0 = a->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
908 xa = xa0 + a->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
909 y = *--xa;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
910 #ifdef DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
911 if (!y) Bug("zero y in b2d");
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
912 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
913 k = hi0bits(y);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
914 *e = 32 - k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
915 if (k < Ebits) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
916 word0(&d) = Exp_1 | y >> (Ebits - k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
917 w = xa > xa0 ? *--xa : 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
918 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
919 goto ret_d;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
920 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
921 z = xa > xa0 ? *--xa : 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
922 if (k -= Ebits) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
923 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
924 y = xa > xa0 ? *--xa : 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
925 word1(&d) = z << k | y >> (32 - k);
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 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
928 word0(&d) = Exp_1 | y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
929 word1(&d) = z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
930 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
931 ret_d:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
932 return dval(&d);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
933 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
934
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
935 /* 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
936
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
937 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
938 such that fabs(d) = b * 2**e. On return, *bbits gives the number of
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
939 significant bits of e; that is, 2**(*bbits-1) <= b < 2**(*bbits).
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
940
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
941 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
942 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
943
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
944
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
945 static Bigint *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
946 d2b(U *d, int *e, int *bits)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
947 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
948 Bigint *b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
949 int de, k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
950 ULong *x, y, z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
951 int i;
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 b = Balloc(1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
954 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
955 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
956 x = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
957
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
958 z = word0(d) & Frac_mask;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
959 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
960 if ((de = (int)(word0(d) >> Exp_shift)))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
961 z |= Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
962 if ((y = word1(d))) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
963 if ((k = lo0bits(&y))) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
964 x[0] = y | z << (32 - k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
965 z >>= k;
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 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
968 x[0] = y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
969 i =
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
970 b->wds = (x[1] = z) ? 2 : 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
971 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
972 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
973 k = lo0bits(&z);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
974 x[0] = z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
975 i =
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
976 b->wds = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
977 k += 32;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
978 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
979 if (de) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
980 *e = de - Bias - (P-1) + k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
981 *bits = P - k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
982 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
983 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
984 *e = de - Bias - (P-1) + 1 + k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
985 *bits = 32*i - hi0bits(x[i-1]);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
986 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
987 return b;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
988 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
989
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
990 /* 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
991 error of up to 2.5 ulps. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
992
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
993 static double
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
994 ratio(Bigint *a, Bigint *b)
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 U da, db;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
997 int k, ka, kb;
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 dval(&da) = b2d(a, &ka);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1000 dval(&db) = b2d(b, &kb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1001 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
1002 if (k > 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1003 word0(&da) += k*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1004 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1005 k = -k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1006 word0(&db) += k*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1007 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1008 return dval(&da) / dval(&db);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1009 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1010
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1011 static const double
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1012 tens[] = {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1013 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
1014 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
1015 1e20, 1e21, 1e22
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1016 };
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1017
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1018 static const double
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1019 bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1020 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
1021 9007199254740992.*9007199254740992.e-256
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1022 /* = 2^106 * 1e-256 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1023 };
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1024 /* 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
1025 /* 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
1026 #define Scale_Bit 0x10
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1027 #define n_bigtens 5
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1028
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1029 /* case insensitive string match, for recognising 'inf[inity]' and
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1030 'nan' strings. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1031
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1032 static int
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1033 match(const char **sp, char *t)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1034 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1035 int c, d;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1036 const char *s = *sp;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1037
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1038 while((d = *t++)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1039 if ((c = *++s) >= 'A' && c <= 'Z')
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1040 c += 'a' - 'A';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1041 if (c != d)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1042 return 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1043 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1044 *sp = s + 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1045 return 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1046 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1047
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1048 #define ULbits 32
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1049 #define kshift 5
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1050 #define kmask 31
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1051
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1052
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1053 static int
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1054 dshift(Bigint *b, int p2)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1055 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1056 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
1057 if (p2 > 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1058 rv -= p2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1059 return rv & kmask;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1060 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1061
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1062 /* 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
1063 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
1064 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
1065
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1066 static int
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1067 quorem(Bigint *b, Bigint *S)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1068 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1069 int n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1070 ULong *bx, *bxe, q, *sx, *sxe;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1071 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1072 ULLong borrow, carry, y, ys;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1073 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1074 ULong borrow, carry, y, ys;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1075 ULong si, z, zs;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1076 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1077
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1078 n = S->wds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1079 #ifdef DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1080 /*debug*/ if (b->wds > n)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1081 /*debug*/ Bug("oversize b in quorem");
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1082 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1083 if (b->wds < n)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1084 return 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1085 sx = S->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1086 sxe = sx + --n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1087 bx = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1088 bxe = bx + n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1089 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
1090 #ifdef DEBUG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1091 /*debug*/ if (q > 9)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1092 /*debug*/ Bug("oversized quotient in quorem");
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1093 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1094 if (q) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1095 borrow = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1096 carry = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1097 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1098 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1099 ys = *sx++ * (ULLong)q + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1100 carry = ys >> 32;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1101 y = *bx - (ys & FFFFFFFF) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1102 borrow = y >> 32 & (ULong)1;
53207
fe99a562b708 Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents: 53203
diff changeset
1103 *bx++ = (ULong)(y & FFFFFFFF);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1104 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1105 si = *sx++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1106 ys = (si & 0xffff) * q + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1107 zs = (si >> 16) * q + (ys >> 16);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1108 carry = zs >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1109 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1110 borrow = (y & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1111 z = (*bx >> 16) - (zs & 0xffff) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1112 borrow = (z & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1113 Storeinc(bx, z, y);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1114 #endif
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 while(sx <= sxe);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1117 if (!*bxe) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1118 bx = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1119 while(--bxe > bx && !*bxe)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1120 --n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1121 b->wds = n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1122 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1123 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1124 if (cmp(b, S) >= 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1125 q++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1126 borrow = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1127 carry = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1128 bx = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1129 sx = S->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1130 do {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1131 #ifdef ULLong
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1132 ys = *sx++ + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1133 carry = ys >> 32;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1134 y = *bx - (ys & FFFFFFFF) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1135 borrow = y >> 32 & (ULong)1;
53207
fe99a562b708 Silence compiler warnings on VS8.0
Mark Dickinson <dickinsm@gmail.com>
parents: 53203
diff changeset
1136 *bx++ = (ULong)(y & FFFFFFFF);
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1137 #else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1138 si = *sx++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1139 ys = (si & 0xffff) + carry;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1140 zs = (si >> 16) + (ys >> 16);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1141 carry = zs >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1142 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1143 borrow = (y & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1144 z = (*bx >> 16) - (zs & 0xffff) - borrow;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1145 borrow = (z & 0x10000) >> 16;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1146 Storeinc(bx, z, y);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1147 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1148 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1149 while(sx <= sxe);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1150 bx = b->x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1151 bxe = bx + n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1152 if (!*bxe) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1153 while(--bxe > bx && !*bxe)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1154 --n;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1155 b->wds = n;
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 return q;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1159 }
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
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1162 /* return 0 on success, -1 on failure */
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 static int
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1165 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
1166 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1167 Bigint *b, *d;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1168 int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1169
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1170 dsign = bc->dsign;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1171 nd = bc->nd;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1172 nd0 = bc->nd0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1173 p5 = nd + bc->e0 - 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1174 speccase = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1175 if (rv->d == 0.) { /* special case: value near underflow-to-zero */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1176 /* threshold was rounded to zero */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1177 b = i2b(1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1178 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1179 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1180 p2 = Emin - P + 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1181 bbits = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1182 word0(rv) = (P+2) << Exp_shift;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1183 i = 0;
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 speccase = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1186 --p2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1187 dsign = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1188 goto have_i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1189 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1190 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1191 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1192 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1193 b = d2b(rv, &p2, &bbits);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1194 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1195 return -1;
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 p2 -= bc->scale;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1198 /* floor(log2(rv)) == bbits - 1 + p2 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1199 /* Check for denormal case. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1200 i = P - bbits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1201 if (i > (j = P - Emin - 1 + p2)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1202 i = j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1203 }
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 b = lshift(b, ++i);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1206 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1207 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1208 b->x[0] |= 1;
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 have_i:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1211 p2 -= p5 + i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1212 d = i2b(1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1213 if (d == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1214 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1215 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1216 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1217 /* Arrange for convenient computation of quotients:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1218 * 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
1219 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1220 if (p5 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1221 d = pow5mult(d, p5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1222 if (d == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1223 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1224 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1225 }
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 else if (p5 < 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1228 b = pow5mult(b, -p5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1229 if (b == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1230 Bfree(d);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1231 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1232 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1233 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1234 if (p2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1235 b2 = p2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1236 d2 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1237 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1238 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1239 b2 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1240 d2 = -p2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1241 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1242 i = dshift(d, d2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1243 if ((b2 += i) > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1244 b = lshift(b, b2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1245 if (b == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1246 Bfree(d);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1247 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1248 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1249 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1250 if ((d2 += i) > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1251 d = lshift(d, d2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1252 if (d == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1253 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1254 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1255 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1256 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1257
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1258 /* Now b/d = exactly half-way between the two floating-point values */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1259 /* on either side of the input string. Compute first digit of b/d. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1260
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1261 if (!(dig = quorem(b,d))) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1262 b = multadd(b, 10, 0); /* very unlikely */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1263 if (b == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1264 Bfree(d);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1265 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1266 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1267 dig = quorem(b,d);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1268 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1269
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1270 /* Compare b/d with s0 */
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 assert(nd > 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1273 dd = 9999; /* silence gcc compiler warning */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1274 for(i = 0; i < nd0; ) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1275 if ((dd = s0[i++] - '0' - dig))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1276 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1277 if (!b->x[0] && b->wds == 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1278 if (i < nd)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1279 dd = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1280 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1281 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1282 b = multadd(b, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1283 if (b == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1284 Bfree(d);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1285 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1286 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1287 dig = quorem(b,d);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1288 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1289 for(j = bc->dp1; i++ < nd;) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1290 if ((dd = s0[j++] - '0' - dig))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1291 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1292 if (!b->x[0] && b->wds == 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1293 if (i < nd)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1294 dd = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1295 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1296 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1297 b = multadd(b, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1298 if (b == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1299 Bfree(d);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1300 return -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1301 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1302 dig = quorem(b,d);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1303 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1304 if (b->x[0] || b->wds > 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1305 dd = -1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1306 ret:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1307 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1308 Bfree(d);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1309 if (speccase) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1310 if (dd <= 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1311 rv->d = 0.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1312 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1313 else if (dd < 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1314 if (!dsign) /* does not happen for round-near */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1315 retlow1:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1316 dval(rv) -= ulp(rv);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1317 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1318 else if (dd > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1319 if (dsign) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1320 rethi1:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1321 dval(rv) += ulp(rv);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1322 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1323 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1324 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1325 /* Exact half-way case: apply round-even rule. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1326 if (word1(rv) & 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1327 if (dsign)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1328 goto rethi1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1329 goto retlow1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1330 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1331 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1332
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1333 return 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1334 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1335
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1336 double
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1337 _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
1338 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1339 int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1, error;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1340 int esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1341 const char *s, *s0, *s1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1342 double aadj, aadj1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1343 Long L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1344 U aadj2, adj, rv, rv0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1345 ULong y, z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1346 BCinfo bc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1347 Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1348
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1349 sign = nz0 = nz = bc.dplen = bc.uflchk = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1350 dval(&rv) = 0.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1351 for(s = s00;;s++) switch(*s) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1352 case '-':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1353 sign = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1354 /* no break */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1355 case '+':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1356 if (*++s)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1357 goto break2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1358 /* no break */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1359 case 0:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1360 goto ret0;
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53207
diff changeset
1361 /* modify original dtoa.c so that it doesn't accept leading whitespace
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1362 case '\t':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1363 case '\n':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1364 case '\v':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1365 case '\f':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1366 case '\r':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1367 case ' ':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1368 continue;
53707
13a82a710f19 Issue #5914: Add new C-API function PyOS_string_to_double, to complement
Mark Dickinson <dickinsm@gmail.com>
parents: 53207
diff changeset
1369 */
53185
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1370 default:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1371 goto break2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1372 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1373 break2:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1374 if (*s == '0') {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1375 nz0 = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1376 while(*++s == '0') ;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1377 if (!*s)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1378 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1379 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1380 s0 = s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1381 y = z = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1382 for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1383 if (nd < 9)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1384 y = 10*y + c - '0';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1385 else if (nd < 16)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1386 z = 10*z + c - '0';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1387 nd0 = nd;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1388 bc.dp0 = bc.dp1 = s - s0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1389 if (c == '.') {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1390 c = *++s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1391 bc.dp1 = s - s0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1392 bc.dplen = bc.dp1 - bc.dp0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1393 if (!nd) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1394 for(; c == '0'; c = *++s)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1395 nz++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1396 if (c > '0' && c <= '9') {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1397 s0 = s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1398 nf += nz;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1399 nz = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1400 goto have_dig;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1401 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1402 goto dig_done;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1403 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1404 for(; c >= '0' && c <= '9'; c = *++s) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1405 have_dig:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1406 nz++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1407 if (c -= '0') {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1408 nf += nz;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1409 for(i = 1; i < nz; i++)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1410 if (nd++ < 9)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1411 y *= 10;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1412 else if (nd <= DBL_DIG + 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1413 z *= 10;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1414 if (nd++ < 9)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1415 y = 10*y + c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1416 else if (nd <= DBL_DIG + 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1417 z = 10*z + c;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1418 nz = 0;
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 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1421 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1422 dig_done:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1423 e = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1424 if (c == 'e' || c == 'E') {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1425 if (!nd && !nz && !nz0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1426 goto ret0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1427 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1428 s00 = s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1429 esign = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1430 switch(c = *++s) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1431 case '-':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1432 esign = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1433 case '+':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1434 c = *++s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1435 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1436 if (c >= '0' && c <= '9') {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1437 while(c == '0')
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1438 c = *++s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1439 if (c > '0' && c <= '9') {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1440 L = c - '0';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1441 s1 = s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1442 while((c = *++s) >= '0' && c <= '9')
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1443 L = 10*L + c - '0';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1444 if (s - s1 > 8 || L > 19999)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1445 /* Avoid confusion from exponents
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1446 * so large that e might overflow.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1447 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1448 e = 19999; /* safe for 16 bit ints */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1449 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1450 e = (int)L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1451 if (esign)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1452 e = -e;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1453 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1454 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1455 e = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1456 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1457 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1458 s = s00;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1459 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1460 if (!nd) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1461 if (!nz && !nz0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1462 /* Check for Nan and Infinity */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1463 if (!bc.dplen)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1464 switch(c) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1465 case 'i':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1466 case 'I':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1467 if (match(&s,"nf")) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1468 --s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1469 if (!match(&s,"inity"))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1470 ++s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1471 word0(&rv) = 0x7ff00000;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1472 word1(&rv) = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1473 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1474 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1475 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1476 case 'n':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1477 case 'N':
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1478 if (match(&s, "an")) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1479 word0(&rv) = NAN_WORD0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1480 word1(&rv) = NAN_WORD1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1481 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1482 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1483 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1484 ret0:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1485 s = s00;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1486 sign = 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 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1489 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1490 bc.e0 = e1 = e -= nf;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1491
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1492 /* Now we have nd0 digits, starting at s0, followed by a
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1493 * decimal point, followed by nd-nd0 digits. The number we're
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1494 * after is the integer represented by those digits times
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1495 * 10**e */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1496
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1497 if (!nd0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1498 nd0 = nd;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1499 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
1500 dval(&rv) = y;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1501 if (k > 9) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1502 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
1503 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1504 bd0 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1505 if (nd <= DBL_DIG
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1506 && Flt_Rounds == 1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1507 ) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1508 if (!e)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1509 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1510 if (e > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1511 if (e <= Ten_pmax) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1512 dval(&rv) *= tens[e];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1513 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1514 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1515 i = DBL_DIG - nd;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1516 if (e <= Ten_pmax + i) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1517 /* 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
1518 * this for larger i values.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1519 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1520 e -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1521 dval(&rv) *= tens[i];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1522 dval(&rv) *= tens[e];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1523 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1524 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1525 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1526 else if (e >= -Ten_pmax) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1527 dval(&rv) /= tens[-e];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1528 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1529 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1530 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1531 e1 += nd - k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1532
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1533 bc.scale = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1534
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1535 /* Get starting approximation = rv * 10**e1 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1536
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1537 if (e1 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1538 if ((i = e1 & 15))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1539 dval(&rv) *= tens[i];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1540 if (e1 &= ~15) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1541 if (e1 > DBL_MAX_10_EXP) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1542 ovfl:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1543 errno = ERANGE;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1544 /* Can't trust HUGE_VAL */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1545 word0(&rv) = Exp_mask;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1546 word1(&rv) = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1547 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1548 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1549 e1 >>= 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1550 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
1551 if (e1 & 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1552 dval(&rv) *= bigtens[j];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1553 /* The last multiplication could overflow. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1554 word0(&rv) -= P*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1555 dval(&rv) *= bigtens[j];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1556 if ((z = word0(&rv) & Exp_mask)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1557 > Exp_msk1*(DBL_MAX_EXP+Bias-P))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1558 goto ovfl;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1559 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
1560 /* set to largest number */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1561 /* (Can't trust DBL_MAX) */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1562 word0(&rv) = Big0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1563 word1(&rv) = Big1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1564 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1565 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1566 word0(&rv) += P*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1567 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1568 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1569 else if (e1 < 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1570 e1 = -e1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1571 if ((i = e1 & 15))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1572 dval(&rv) /= tens[i];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1573 if (e1 >>= 4) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1574 if (e1 >= 1 << n_bigtens)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1575 goto undfl;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1576 if (e1 & Scale_Bit)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1577 bc.scale = 2*P;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1578 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
1579 if (e1 & 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1580 dval(&rv) *= tinytens[j];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1581 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
1582 >> Exp_shift)) > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1583 /* 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
1584 if (j >= 32) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1585 word1(&rv) = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1586 if (j >= 53)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1587 word0(&rv) = (P+2)*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1588 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1589 word0(&rv) &= 0xffffffff << (j-32);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1590 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1591 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1592 word1(&rv) &= 0xffffffff << j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1593 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1594 if (!dval(&rv)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1595 undfl:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1596 dval(&rv) = 0.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1597 errno = ERANGE;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1598 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1599 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1600 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1601 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1602
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1603 /* 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
1604
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1605 /* 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
1606
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1607 bc.nd = nd;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1608 bc.nd0 = nd0; /* Only needed if nd > strtod_diglim, but done here */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1609 /* 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
1610 /* possibly not being initialized. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1611 if (nd > strtod_diglim) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1612 /* ASSERT(strtod_diglim >= 18); 18 == one more than the */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1613 /* 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
1614 /* in IEEE arithmetic. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1615 i = j = 18;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1616 if (i > nd0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1617 j += bc.dplen;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1618 for(;;) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1619 if (--j <= bc.dp1 && j >= bc.dp0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1620 j = bc.dp0 - 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1621 if (s0[j] != '0')
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1622 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1623 --i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1624 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1625 e += nd - i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1626 nd = i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1627 if (nd0 > nd)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1628 nd0 = nd;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1629 if (nd < 9) { /* must recompute y */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1630 y = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1631 for(i = 0; i < nd0; ++i)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1632 y = 10*y + s0[i] - '0';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1633 for(j = bc.dp1; i < nd; ++i)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1634 y = 10*y + s0[j++] - '0';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1635 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1636 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1637 bd0 = s2b(s0, nd0, nd, y, bc.dplen);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1638 if (bd0 == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1639 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1640
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1641 for(;;) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1642 bd = Balloc(bd0->k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1643 if (bd == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1644 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1645 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1646 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1647 Bcopy(bd, bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1648 bb = d2b(&rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1649 if (bb == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1650 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1651 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1652 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1653 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1654 bs = i2b(1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1655 if (bs == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1656 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1657 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1658 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1659 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1660 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1661
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1662 if (e >= 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1663 bb2 = bb5 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1664 bd2 = bd5 = e;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1665 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1666 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1667 bb2 = bb5 = -e;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1668 bd2 = bd5 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1669 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1670 if (bbe >= 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1671 bb2 += bbe;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1672 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1673 bd2 -= bbe;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1674 bs2 = bb2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1675 j = bbe - bc.scale;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1676 i = j + bbbits - 1; /* logb(rv) */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1677 if (i < Emin) /* denormal */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1678 j += P - Emin;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1679 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1680 j = P + 1 - bbbits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1681 bb2 += j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1682 bd2 += j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1683 bd2 += bc.scale;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1684 i = bb2 < bd2 ? bb2 : bd2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1685 if (i > bs2)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1686 i = bs2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1687 if (i > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1688 bb2 -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1689 bd2 -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1690 bs2 -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1691 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1692 if (bb5 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1693 bs = pow5mult(bs, bb5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1694 if (bs == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1695 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1696 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1697 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1698 goto failed_malloc;
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 bb1 = mult(bs, bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1701 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1702 bb = bb1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1703 if (bb == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1704 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1705 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1706 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1707 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1708 }
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 if (bb2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1711 bb = lshift(bb, bb2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1712 if (bb == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1713 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1714 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1715 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1716 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1717 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1718 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1719 if (bd5 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1720 bd = pow5mult(bd, bd5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1721 if (bd == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1722 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1723 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1724 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1725 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1726 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1727 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1728 if (bd2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1729 bd = lshift(bd, bd2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1730 if (bd == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1731 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1732 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1733 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1734 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1735 }
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 if (bs2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1738 bs = lshift(bs, bs2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1739 if (bs == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1740 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1741 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1742 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1743 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1744 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1745 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1746 delta = diff(bb, bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1747 if (delta == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1748 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1749 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1750 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1751 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1752 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1753 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1754 bc.dsign = delta->sign;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1755 delta->sign = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1756 i = cmp(delta, bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1757 if (bc.nd > nd && i <= 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1758 if (bc.dsign)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1759 break; /* Must use bigcomp(). */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1760 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1761 bc.nd = nd;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1762 i = -1; /* Discarded digits make delta smaller. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1763 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1764 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1765
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1766 if (i < 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1767 /* 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
1768 * 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
1769 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1770 if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1771 || (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
1772 ) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1773 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1774 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1775 if (!delta->x[0] && delta->wds <= 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1776 /* exact result */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1777 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1778 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1779 delta = lshift(delta,Log2P);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1780 if (delta == NULL) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1781 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1782 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1783 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1784 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1785 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1786 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1787 if (cmp(delta, bs) > 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1788 goto drop_down;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1789 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1790 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1791 if (i == 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1792 /* exactly half-way between */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1793 if (bc.dsign) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1794 if ((word0(&rv) & Bndry_mask1) == Bndry_mask1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1795 && word1(&rv) == (
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1796 (bc.scale &&
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1797 (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
1798 (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
1799 0xffffffff)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1800 /*boundary case -- increment exponent*/
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1801 word0(&rv) = (word0(&rv) & Exp_mask)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1802 + Exp_msk1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1803 ;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1804 word1(&rv) = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1805 bc.dsign = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1806 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1807 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1808 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1809 else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1810 drop_down:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1811 /* boundary case -- decrement exponent */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1812 if (bc.scale) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1813 L = word0(&rv) & Exp_mask;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1814 if (L <= (2*P+1)*Exp_msk1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1815 if (L > (P+2)*Exp_msk1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1816 /* round even ==> */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1817 /* accept rv */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1818 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1819 /* rv = smallest denormal */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1820 if (bc.nd >nd) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1821 bc.uflchk = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1822 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1823 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1824 goto undfl;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1825 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1826 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1827 L = (word0(&rv) & Exp_mask) - Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1828 word0(&rv) = L | Bndry_mask1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1829 word1(&rv) = 0xffffffff;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1830 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1831 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1832 if (!(word1(&rv) & LSB))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1833 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1834 if (bc.dsign)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1835 dval(&rv) += ulp(&rv);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1836 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1837 dval(&rv) -= ulp(&rv);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1838 if (!dval(&rv)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1839 if (bc.nd >nd) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1840 bc.uflchk = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1841 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1842 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1843 goto undfl;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1844 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1845 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1846 bc.dsign = 1 - bc.dsign;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1847 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1848 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1849 if ((aadj = ratio(delta, bs)) <= 2.) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1850 if (bc.dsign)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1851 aadj = aadj1 = 1.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1852 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
1853 if (word1(&rv) == Tiny1 && !word0(&rv)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1854 if (bc.nd >nd) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1855 bc.uflchk = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1856 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1857 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1858 goto undfl;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1859 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1860 aadj = 1.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1861 aadj1 = -1.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1862 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1863 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1864 /* 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
1865 /* rounded down... */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1866
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1867 if (aadj < 2./FLT_RADIX)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1868 aadj = 1./FLT_RADIX;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1869 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1870 aadj *= 0.5;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1871 aadj1 = -aadj;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1872 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1873 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1874 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1875 aadj *= 0.5;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1876 aadj1 = bc.dsign ? aadj : -aadj;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1877 if (Flt_Rounds == 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1878 aadj1 += 0.5;
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 y = word0(&rv) & Exp_mask;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1881
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1882 /* Check for overflow */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1883
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1884 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
1885 dval(&rv0) = dval(&rv);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1886 word0(&rv) -= P*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1887 adj.d = aadj1 * ulp(&rv);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1888 dval(&rv) += adj.d;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1889 if ((word0(&rv) & Exp_mask) >=
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1890 Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1891 if (word0(&rv0) == Big0 && word1(&rv0) == Big1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1892 goto ovfl;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1893 word0(&rv) = Big0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1894 word1(&rv) = Big1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1895 goto cont;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1896 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1897 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1898 word0(&rv) += P*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1899 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1900 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1901 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
1902 if (aadj <= 0x7fffffff) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1903 if ((z = (ULong)aadj) <= 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1904 z = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1905 aadj = z;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1906 aadj1 = bc.dsign ? aadj : -aadj;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1907 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1908 dval(&aadj2) = aadj1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1909 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
1910 aadj1 = dval(&aadj2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1911 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1912 adj.d = aadj1 * ulp(&rv);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1913 dval(&rv) += adj.d;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1914 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1915 z = word0(&rv) & Exp_mask;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1916 if (bc.nd == nd) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1917 if (!bc.scale)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1918 if (y == z) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1919 /* Can we stop now? */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1920 L = (Long)aadj;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1921 aadj -= L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1922 /* The tolerances below are conservative. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1923 if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1924 if (aadj < .4999999 || aadj > .5000001)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1925 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1926 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1927 else if (aadj < .4999999/FLT_RADIX)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1928 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1929 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1930 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1931 cont:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1932 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1933 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1934 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1935 Bfree(delta);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1936 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1937 Bfree(bb);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1938 Bfree(bd);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1939 Bfree(bs);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1940 Bfree(bd0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1941 Bfree(delta);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1942 if (bc.nd > nd) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1943 error = bigcomp(&rv, s0, &bc);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1944 if (error)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1945 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1946 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1947
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1948 if (bc.scale) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1949 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
1950 word1(&rv0) = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1951 dval(&rv) *= dval(&rv0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1952 /* try to avoid the bug of testing an 8087 register value */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1953 if (!(word0(&rv) & Exp_mask))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1954 errno = ERANGE;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1955 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1956 ret:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1957 if (se)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1958 *se = (char *)s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1959 return sign ? -dval(&rv) : dval(&rv);
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 failed_malloc:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1962 if (se)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1963 *se = (char *)s00;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1964 errno = ENOMEM;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1965 return -1.0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1966 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1967
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1968 static char *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1969 rv_alloc(int i)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1970 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1971 int j, k, *r;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1972
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1973 j = sizeof(ULong);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1974 for(k = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1975 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
1976 j <<= 1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1977 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1978 r = (int*)Balloc(k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1979 if (r == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1980 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1981 *r = k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1982 return (char *)(r+1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1983 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1984
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1985 static char *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1986 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
1987 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1988 char *rv, *t;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1989
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1990 rv = rv_alloc(n);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1991 if (rv == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1992 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1993 t = rv;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1994 while((*t = *s++)) t++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1995 if (rve)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1996 *rve = t;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1997 return rv;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1998 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
1999
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2000 /* 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
2001 * 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
2002 * 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
2003 * when MULTIPLE_THREADS is not defined.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2004 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2005
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2006 void
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2007 _Py_dg_freedtoa(char *s)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2008 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2009 Bigint *b = (Bigint *)((int *)s - 1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2010 b->maxwds = 1 << (b->k = *(int*)b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2011 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2012 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2013
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2014 /* 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
2015 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2016 * 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
2017 * 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
2018 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2019 * Modifications:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2020 * 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
2021 * 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
2022 * 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
2023 * 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
2024 * 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
2025 * 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
2026 * 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
2027 * 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
2028 * 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
2029 * 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
2030 * 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
2031 * 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
2032 * inequality.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2033 * 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
2034 * quantities.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2035 * 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
2036 * 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
2037 * to multiple-precision integers.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2038 * 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
2039 * 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
2040 * 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
2041 * 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
2042 * 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
2043 * "uniformly" distributed input, the probability is
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2044 * 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
2045 * calculation.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2046 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2047
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2048 /* 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
2049 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
2050 call to _Py_dg_freedtoa. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2051
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2052 char *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2053 _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
2054 int *decpt, int *sign, char **rve)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2055 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2056 /* 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
2057 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
2058 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
2059 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
2060 then *decpt is set to 9999.
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 mode:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2063 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
2064 and rounded to nearest.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2065 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
2066 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
2067 1e23 whereas mode 1 gives 9.999999999999999e22.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2068 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
2069 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
2070 that trailing zeros are suppressed.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2071 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
2072 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
2073 except that trailing zeros are suppressed, and
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2074 ndigits can be negative.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2075 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
2076 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
2077 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
2078 With IEEE arithmetic and compilation with
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2079 -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
2080 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
2081 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
2082 fast floating-point estimate (if applicable).
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2083
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2084 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
2085
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2086 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
2087 to hold the suppressed trailing zeros.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2088 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2089
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2090 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
2091 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
2092 spec_case, try_quick;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2093 Long L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2094 int denorm;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2095 ULong x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2096 Bigint *b, *b1, *delta, *mlo, *mhi, *S;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2097 U d2, eps, u;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2098 double ds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2099 char *s, *s0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2100
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2101 /* 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
2102 cleanup easier on error */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2103 mlo = mhi = b = S = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2104 s0 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2105
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2106 u.d = dd;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2107 if (word0(&u) & Sign_bit) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2108 /* 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
2109 *sign = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2110 word0(&u) &= ~Sign_bit; /* clear sign bit */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2111 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2112 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2113 *sign = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2114
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2115 /* quick return for Infinities, NaNs and zeros */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2116 if ((word0(&u) & Exp_mask) == Exp_mask)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2117 {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2118 /* Infinity or NaN */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2119 *decpt = 9999;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2120 if (!word1(&u) && !(word0(&u) & 0xfffff))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2121 return nrv_alloc("Infinity", rve, 8);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2122 return nrv_alloc("NaN", rve, 3);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2123 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2124 if (!dval(&u)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2125 *decpt = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2126 return nrv_alloc("0", rve, 1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2127 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2128
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2129 /* 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
2130 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
2131 b = d2b(&u, &be, &bbits);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2132 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2133 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2134 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
2135 dval(&d2) = dval(&u);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2136 word0(&d2) &= Frac_mask1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2137 word0(&d2) |= Exp_11;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2138
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2139 /* 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
2140 * log10(x) = log(x) / log(10)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2141 * ~=~ 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
2142 * 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
2143 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2144 * 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
2145 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2146 * k = (i - Bias)*0.301029995663981
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2147 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2148 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2149 * 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
2150 * 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
2151 * 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
2152 * 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
2153 * (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
2154 * 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
2155 * 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
2156 * 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
2157 * (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
2158 * but this is probably not worthwhile.)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2159 */
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 i -= Bias;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2162 denorm = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2163 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2164 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2165 /* d is denormalized */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2166
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2167 i = bbits + be + (Bias + (P-1) - 1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2168 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
2169 : word1(&u) << (32 - i);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2170 dval(&d2) = x;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2171 word0(&d2) -= 31*Exp_msk1; /* adjust exponent */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2172 i -= (Bias + (P-1) - 1) + 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2173 denorm = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2174 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2175 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
2176 i*0.301029995663981;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2177 k = (int)ds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2178 if (ds < 0. && ds != k)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2179 k--; /* want k = floor(ds) */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2180 k_check = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2181 if (k >= 0 && k <= Ten_pmax) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2182 if (dval(&u) < tens[k])
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2183 k--;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2184 k_check = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2185 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2186 j = bbits - i - 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2187 if (j >= 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2188 b2 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2189 s2 = j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2190 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2191 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2192 b2 = -j;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2193 s2 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2194 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2195 if (k >= 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2196 b5 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2197 s5 = k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2198 s2 += k;
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 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2201 b2 -= k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2202 b5 = -k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2203 s5 = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2204 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2205 if (mode < 0 || mode > 9)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2206 mode = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2207
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2208 try_quick = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2209
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2210 if (mode > 5) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2211 mode -= 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2212 try_quick = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2213 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2214 leftright = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2215 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
2216 /* silence erroneous "gcc -Wall" warning. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2217 switch(mode) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2218 case 0:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2219 case 1:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2220 i = 18;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2221 ndigits = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2222 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2223 case 2:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2224 leftright = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2225 /* no break */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2226 case 4:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2227 if (ndigits <= 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2228 ndigits = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2229 ilim = ilim1 = i = ndigits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2230 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2231 case 3:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2232 leftright = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2233 /* no break */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2234 case 5:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2235 i = ndigits + k + 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2236 ilim = i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2237 ilim1 = i - 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2238 if (i <= 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2239 i = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2240 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2241 s0 = rv_alloc(i);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2242 if (s0 == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2243 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2244 s = s0;
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
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2247 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
2248
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2249 /* 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
2250
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2251 i = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2252 dval(&d2) = dval(&u);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2253 k0 = k;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2254 ilim0 = ilim;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2255 ieps = 2; /* conservative */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2256 if (k > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2257 ds = tens[k&0xf];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2258 j = k >> 4;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2259 if (j & Bletch) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2260 /* prevent overflows */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2261 j &= Bletch - 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2262 dval(&u) /= bigtens[n_bigtens-1];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2263 ieps++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2264 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2265 for(; j; j >>= 1, i++)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2266 if (j & 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2267 ieps++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2268 ds *= bigtens[i];
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 dval(&u) /= ds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2271 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2272 else if ((j1 = -k)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2273 dval(&u) *= tens[j1 & 0xf];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2274 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
2275 if (j & 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2276 ieps++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2277 dval(&u) *= bigtens[i];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2278 }
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 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
2281 if (ilim1 <= 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2282 goto fast_failed;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2283 ilim = ilim1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2284 k--;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2285 dval(&u) *= 10.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2286 ieps++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2287 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2288 dval(&eps) = ieps*dval(&u) + 7.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2289 word0(&eps) -= (P-1)*Exp_msk1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2290 if (ilim == 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2291 S = mhi = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2292 dval(&u) -= 5.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2293 if (dval(&u) > dval(&eps))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2294 goto one_digit;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2295 if (dval(&u) < -dval(&eps))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2296 goto no_digits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2297 goto fast_failed;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2298 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2299 if (leftright) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2300 /* Use Steele & White method of only
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2301 * generating digits needed.
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2302 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2303 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
2304 for(i = 0;;) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2305 L = (Long)dval(&u);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2306 dval(&u) -= L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2307 *s++ = '0' + (int)L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2308 if (dval(&u) < dval(&eps))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2309 goto ret1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2310 if (1. - dval(&u) < dval(&eps))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2311 goto bump_up;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2312 if (++i >= ilim)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2313 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2314 dval(&eps) *= 10.;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2315 dval(&u) *= 10.;
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 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2318 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2319 /* Generate ilim digits, then fix them up. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2320 dval(&eps) *= tens[ilim-1];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2321 for(i = 1;; i++, dval(&u) *= 10.) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2322 L = (Long)(dval(&u));
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2323 if (!(dval(&u) -= L))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2324 ilim = i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2325 *s++ = '0' + (int)L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2326 if (i == ilim) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2327 if (dval(&u) > 0.5 + dval(&eps))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2328 goto bump_up;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2329 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
2330 while(*--s == '0');
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2331 s++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2332 goto ret1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2333 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2334 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2335 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2336 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2337 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2338 fast_failed:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2339 s = s0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2340 dval(&u) = dval(&d2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2341 k = k0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2342 ilim = ilim0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2343 }
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 /* Do we have a "small" integer? */
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 if (be >= 0 && k <= Int_max) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2348 /* Yes. */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2349 ds = tens[k];
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2350 if (ndigits < 0 && ilim <= 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2351 S = mhi = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2352 if (ilim < 0 || dval(&u) <= 5*ds)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2353 goto no_digits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2354 goto one_digit;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2355 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2356 for(i = 1;; i++, dval(&u) *= 10.) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2357 L = (Long)(dval(&u) / ds);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2358 dval(&u) -= L*ds;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2359 *s++ = '0' + (int)L;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2360 if (!dval(&u)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2361 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2362 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2363 if (i == ilim) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2364 dval(&u) += dval(&u);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2365 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
2366 bump_up:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2367 while(*--s == '9')
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2368 if (s == s0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2369 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2370 *s = '0';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2371 break;
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 ++*s++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2374 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2375 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2376 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2377 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2378 goto ret1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2379 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2380
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2381 m2 = b2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2382 m5 = b5;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2383 if (leftright) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2384 i =
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2385 denorm ? be + (Bias + (P-1) - 1 + 1) :
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2386 1 + P - bbits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2387 b2 += i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2388 s2 += i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2389 mhi = i2b(1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2390 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2391 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2392 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2393 if (m2 > 0 && s2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2394 i = m2 < s2 ? m2 : s2;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2395 b2 -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2396 m2 -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2397 s2 -= i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2398 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2399 if (b5 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2400 if (leftright) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2401 if (m5 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2402 mhi = pow5mult(mhi, m5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2403 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2404 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2405 b1 = mult(mhi, b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2406 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2407 b = b1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2408 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2409 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2410 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2411 if ((j = b5 - m5)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2412 b = pow5mult(b, j);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2413 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2414 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2415 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2416 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2417 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2418 b = pow5mult(b, b5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2419 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2420 goto failed_malloc;
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 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2423 S = i2b(1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2424 if (S == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2425 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2426 if (s5 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2427 S = pow5mult(S, s5);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2428 if (S == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2429 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2430 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2431
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2432 /* 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
2433
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2434 spec_case = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2435 if ((mode < 2 || leftright)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2436 ) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2437 if (!word1(&u) && !(word0(&u) & Bndry_mask)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2438 && word0(&u) & (Exp_mask & ~Exp_msk1)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2439 ) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2440 /* The special case */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2441 b2 += Log2P;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2442 s2 += Log2P;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2443 spec_case = 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2444 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2445 }
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 /* Arrange for convenient computation of quotients:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2448 * 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
2449 *
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2450 * 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
2451 * 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
2452 * 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
2453 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2454 if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2455 i = 32 - i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2456 #define iInc 28
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2457 i = dshift(S, s2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2458 b2 += i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2459 m2 += i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2460 s2 += i;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2461 if (b2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2462 b = lshift(b, b2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2463 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2464 goto failed_malloc;
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 (s2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2467 S = lshift(S, s2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2468 if (S == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2469 goto failed_malloc;
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 (k_check) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2472 if (cmp(b,S) < 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2473 k--;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2474 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
2475 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2476 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2477 if (leftright) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2478 mhi = multadd(mhi, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2479 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2480 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2481 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2482 ilim = ilim1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2483 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2484 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2485 if (ilim <= 0 && (mode == 3 || mode == 5)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2486 if (ilim < 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2487 /* no digits, fcvt style */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2488 no_digits:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2489 k = -1 - ndigits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2490 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2491 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2492 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2493 S = multadd(S, 5, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2494 if (S == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2495 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2496 if (cmp(b, S) <= 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2497 goto no_digits;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2498 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2499 one_digit:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2500 *s++ = '1';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2501 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2502 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2503 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2504 if (leftright) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2505 if (m2 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2506 mhi = lshift(mhi, m2);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2507 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2508 goto failed_malloc;
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
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2511 /* Compute mlo -- check for special case
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2512 * 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
2513 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2514
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2515 mlo = mhi;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2516 if (spec_case) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2517 mhi = Balloc(mhi->k);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2518 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2519 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2520 Bcopy(mhi, mlo);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2521 mhi = lshift(mhi, Log2P);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2522 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2523 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2524 }
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(i = 1;;i++) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2527 dig = quorem(b,S) + '0';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2528 /* 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
2529 * that will round to d?
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 j = cmp(b, mlo);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2532 delta = diff(S, mhi);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2533 if (delta == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2534 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2535 j1 = delta->sign ? 1 : cmp(b, delta);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2536 Bfree(delta);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2537 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
2538 ) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2539 if (dig == '9')
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2540 goto round_9_up;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2541 if (j > 0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2542 dig++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2543 *s++ = dig;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2544 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2545 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2546 if (j < 0 || (j == 0 && mode != 1
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2547 && !(word1(&u) & 1)
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 if (!b->x[0] && b->wds <= 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2550 goto accept_dig;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2551 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2552 if (j1 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2553 b = lshift(b, 1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2554 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2555 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2556 j1 = cmp(b, S);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2557 if ((j1 > 0 || (j1 == 0 && dig & 1))
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2558 && dig++ == '9')
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2559 goto round_9_up;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2560 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2561 accept_dig:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2562 *s++ = dig;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2563 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2564 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2565 if (j1 > 0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2566 if (dig == '9') { /* possible if i == 1 */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2567 round_9_up:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2568 *s++ = '9';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2569 goto roundoff;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2570 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2571 *s++ = dig + 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2572 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2573 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2574 *s++ = dig;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2575 if (i == ilim)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2576 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2577 b = multadd(b, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2578 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2579 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2580 if (mlo == mhi) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2581 mlo = mhi = multadd(mhi, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2582 if (mlo == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2583 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2584 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2585 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2586 mlo = multadd(mlo, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2587 if (mlo == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2588 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2589 mhi = multadd(mhi, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2590 if (mhi == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2591 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2592 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2593 }
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 else
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2596 for(i = 1;; i++) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2597 *s++ = dig = quorem(b,S) + '0';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2598 if (!b->x[0] && b->wds <= 1) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2599 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2600 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2601 if (i >= ilim)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2602 break;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2603 b = multadd(b, 10, 0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2604 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2605 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2606 }
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 /* Round off last digit */
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2609
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2610 b = lshift(b, 1);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2611 if (b == NULL)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2612 goto failed_malloc;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2613 j = cmp(b, S);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2614 if (j > 0 || (j == 0 && dig & 1)) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2615 roundoff:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2616 while(*--s == '9')
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2617 if (s == s0) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2618 k++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2619 *s++ = '1';
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2620 goto ret;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2621 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2622 ++*s++;
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 else {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2625 while(*--s == '0');
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2626 s++;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2627 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2628 ret:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2629 Bfree(S);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2630 if (mhi) {
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2631 if (mlo && mlo != mhi)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2632 Bfree(mlo);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2633 Bfree(mhi);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2634 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2635 ret1:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2636 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2637 *s = 0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2638 *decpt = k + 1;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2639 if (rve)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2640 *rve = s;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2641 return s0;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2642 failed_malloc:
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2643 if (S)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2644 Bfree(S);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2645 if (mlo && mlo != mhi)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2646 Bfree(mlo);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2647 if (mhi)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2648 Bfree(mhi);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2649 if (b)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2650 Bfree(b);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2651 if (s0)
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2652 _Py_dg_freedtoa(s0);
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2653 return NULL;
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2654 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2655 #ifdef __cplusplus
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2656 }
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2657 #endif
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2658
97ae7a709c1d Issue #1580: use short float repr where possible.
Mark Dickinson <dickinsm@gmail.com>
parents:
diff changeset
2659 #endif /* PY_NO_SHORT_FLOAT_REPR */