1cc36ccd1SDavid Schultz /****************************************************************
2cc36ccd1SDavid Schultz
3cc36ccd1SDavid Schultz The author of this software is David M. Gay.
4cc36ccd1SDavid Schultz
5cc36ccd1SDavid Schultz Copyright (C) 1998 by Lucent Technologies
6cc36ccd1SDavid Schultz All Rights Reserved
7cc36ccd1SDavid Schultz
8cc36ccd1SDavid Schultz Permission to use, copy, modify, and distribute this software and
9cc36ccd1SDavid Schultz its documentation for any purpose and without fee is hereby
10cc36ccd1SDavid Schultz granted, provided that the above copyright notice appear in all
11cc36ccd1SDavid Schultz copies and that both that the copyright notice and this
12cc36ccd1SDavid Schultz permission notice and warranty disclaimer appear in supporting
13cc36ccd1SDavid Schultz documentation, and that the name of Lucent or any of its entities
14cc36ccd1SDavid Schultz not be used in advertising or publicity pertaining to
15cc36ccd1SDavid Schultz distribution of the software without specific, written prior
16cc36ccd1SDavid Schultz permission.
17cc36ccd1SDavid Schultz
18cc36ccd1SDavid Schultz LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19cc36ccd1SDavid Schultz INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
20cc36ccd1SDavid Schultz IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
21cc36ccd1SDavid Schultz SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
22cc36ccd1SDavid Schultz WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
23cc36ccd1SDavid Schultz IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24cc36ccd1SDavid Schultz ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
25cc36ccd1SDavid Schultz THIS SOFTWARE.
26cc36ccd1SDavid Schultz
27cc36ccd1SDavid Schultz ****************************************************************/
28cc36ccd1SDavid Schultz
29c88250a5SDavid Schultz /* Please send bug reports to David M. Gay (dmg at acm dot org,
30c88250a5SDavid Schultz * with " at " changed at "@" and " dot " changed to "."). */
31cc36ccd1SDavid Schultz
32cc36ccd1SDavid Schultz #include "gdtoaimp.h"
33cc36ccd1SDavid Schultz
34cc36ccd1SDavid Schultz #ifndef MULTIPLE_THREADS
35cc36ccd1SDavid Schultz char *dtoa_result;
36cc36ccd1SDavid Schultz #endif
37cc36ccd1SDavid Schultz
38cc36ccd1SDavid Schultz char *
39cc36ccd1SDavid Schultz #ifdef KR_headers
rv_alloc(i)40cc36ccd1SDavid Schultz rv_alloc(i) int i;
41cc36ccd1SDavid Schultz #else
42cc36ccd1SDavid Schultz rv_alloc(int i)
43cc36ccd1SDavid Schultz #endif
44cc36ccd1SDavid Schultz {
45cc36ccd1SDavid Schultz int j, k, *r;
46cc36ccd1SDavid Schultz
47cc36ccd1SDavid Schultz j = sizeof(ULong);
48cc36ccd1SDavid Schultz for(k = 0;
49cc36ccd1SDavid Schultz sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i;
50cc36ccd1SDavid Schultz j <<= 1)
51cc36ccd1SDavid Schultz k++;
52cc36ccd1SDavid Schultz r = (int*)Balloc(k);
53cc36ccd1SDavid Schultz *r = k;
54cc36ccd1SDavid Schultz return
55cc36ccd1SDavid Schultz #ifndef MULTIPLE_THREADS
56cc36ccd1SDavid Schultz dtoa_result =
57cc36ccd1SDavid Schultz #endif
58cc36ccd1SDavid Schultz (char *)(r+1);
59cc36ccd1SDavid Schultz }
60cc36ccd1SDavid Schultz
61cc36ccd1SDavid Schultz char *
62cc36ccd1SDavid Schultz #ifdef KR_headers
nrv_alloc(s,rve,n)63cc36ccd1SDavid Schultz nrv_alloc(s, rve, n) char *s, **rve; int n;
64cc36ccd1SDavid Schultz #else
65cc36ccd1SDavid Schultz nrv_alloc(char *s, char **rve, int n)
66cc36ccd1SDavid Schultz #endif
67cc36ccd1SDavid Schultz {
68cc36ccd1SDavid Schultz char *rv, *t;
69cc36ccd1SDavid Schultz
70cc36ccd1SDavid Schultz t = rv = rv_alloc(n);
71cc36ccd1SDavid Schultz while((*t = *s++) !=0)
72cc36ccd1SDavid Schultz t++;
73cc36ccd1SDavid Schultz if (rve)
74cc36ccd1SDavid Schultz *rve = t;
75cc36ccd1SDavid Schultz return rv;
76cc36ccd1SDavid Schultz }
77cc36ccd1SDavid Schultz
78cc36ccd1SDavid Schultz /* freedtoa(s) must be used to free values s returned by dtoa
79cc36ccd1SDavid Schultz * when MULTIPLE_THREADS is #defined. It should be used in all cases,
80cc36ccd1SDavid Schultz * but for consistency with earlier versions of dtoa, it is optional
81cc36ccd1SDavid Schultz * when MULTIPLE_THREADS is not defined.
82cc36ccd1SDavid Schultz */
83cc36ccd1SDavid Schultz
84cc36ccd1SDavid Schultz void
85cc36ccd1SDavid Schultz #ifdef KR_headers
freedtoa(s)86cc36ccd1SDavid Schultz freedtoa(s) char *s;
87cc36ccd1SDavid Schultz #else
88cc36ccd1SDavid Schultz freedtoa(char *s)
89cc36ccd1SDavid Schultz #endif
90cc36ccd1SDavid Schultz {
91cc36ccd1SDavid Schultz Bigint *b = (Bigint *)((int *)s - 1);
92cc36ccd1SDavid Schultz b->maxwds = 1 << (b->k = *(int*)b);
93cc36ccd1SDavid Schultz Bfree(b);
94cc36ccd1SDavid Schultz #ifndef MULTIPLE_THREADS
95cc36ccd1SDavid Schultz if (s == dtoa_result)
96cc36ccd1SDavid Schultz dtoa_result = 0;
97cc36ccd1SDavid Schultz #endif
98cc36ccd1SDavid Schultz }
99cc36ccd1SDavid Schultz
100cc36ccd1SDavid Schultz int
quorem(b,S)101cc36ccd1SDavid Schultz quorem
102cc36ccd1SDavid Schultz #ifdef KR_headers
103cc36ccd1SDavid Schultz (b, S) Bigint *b, *S;
104cc36ccd1SDavid Schultz #else
105cc36ccd1SDavid Schultz (Bigint *b, Bigint *S)
106cc36ccd1SDavid Schultz #endif
107cc36ccd1SDavid Schultz {
108cc36ccd1SDavid Schultz int n;
109cc36ccd1SDavid Schultz ULong *bx, *bxe, q, *sx, *sxe;
110cc36ccd1SDavid Schultz #ifdef ULLong
111cc36ccd1SDavid Schultz ULLong borrow, carry, y, ys;
112cc36ccd1SDavid Schultz #else
113cc36ccd1SDavid Schultz ULong borrow, carry, y, ys;
114cc36ccd1SDavid Schultz #ifdef Pack_32
115cc36ccd1SDavid Schultz ULong si, z, zs;
116cc36ccd1SDavid Schultz #endif
117cc36ccd1SDavid Schultz #endif
118cc36ccd1SDavid Schultz
119cc36ccd1SDavid Schultz n = S->wds;
120cc36ccd1SDavid Schultz #ifdef DEBUG
121cc36ccd1SDavid Schultz /*debug*/ if (b->wds > n)
122cc36ccd1SDavid Schultz /*debug*/ Bug("oversize b in quorem");
123cc36ccd1SDavid Schultz #endif
124cc36ccd1SDavid Schultz if (b->wds < n)
125cc36ccd1SDavid Schultz return 0;
126cc36ccd1SDavid Schultz sx = S->x;
127cc36ccd1SDavid Schultz sxe = sx + --n;
128cc36ccd1SDavid Schultz bx = b->x;
129cc36ccd1SDavid Schultz bxe = bx + n;
130cc36ccd1SDavid Schultz q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
131cc36ccd1SDavid Schultz #ifdef DEBUG
132cc36ccd1SDavid Schultz /*debug*/ if (q > 9)
133cc36ccd1SDavid Schultz /*debug*/ Bug("oversized quotient in quorem");
134cc36ccd1SDavid Schultz #endif
135cc36ccd1SDavid Schultz if (q) {
136cc36ccd1SDavid Schultz borrow = 0;
137cc36ccd1SDavid Schultz carry = 0;
138cc36ccd1SDavid Schultz do {
139cc36ccd1SDavid Schultz #ifdef ULLong
140cc36ccd1SDavid Schultz ys = *sx++ * (ULLong)q + carry;
141cc36ccd1SDavid Schultz carry = ys >> 32;
142cc36ccd1SDavid Schultz y = *bx - (ys & 0xffffffffUL) - borrow;
143cc36ccd1SDavid Schultz borrow = y >> 32 & 1UL;
144cc36ccd1SDavid Schultz *bx++ = y & 0xffffffffUL;
145cc36ccd1SDavid Schultz #else
146cc36ccd1SDavid Schultz #ifdef Pack_32
147cc36ccd1SDavid Schultz si = *sx++;
148cc36ccd1SDavid Schultz ys = (si & 0xffff) * q + carry;
149cc36ccd1SDavid Schultz zs = (si >> 16) * q + (ys >> 16);
150cc36ccd1SDavid Schultz carry = zs >> 16;
151cc36ccd1SDavid Schultz y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
152cc36ccd1SDavid Schultz borrow = (y & 0x10000) >> 16;
153cc36ccd1SDavid Schultz z = (*bx >> 16) - (zs & 0xffff) - borrow;
154cc36ccd1SDavid Schultz borrow = (z & 0x10000) >> 16;
155cc36ccd1SDavid Schultz Storeinc(bx, z, y);
156cc36ccd1SDavid Schultz #else
157cc36ccd1SDavid Schultz ys = *sx++ * q + carry;
158cc36ccd1SDavid Schultz carry = ys >> 16;
159cc36ccd1SDavid Schultz y = *bx - (ys & 0xffff) - borrow;
160cc36ccd1SDavid Schultz borrow = (y & 0x10000) >> 16;
161cc36ccd1SDavid Schultz *bx++ = y & 0xffff;
162cc36ccd1SDavid Schultz #endif
163cc36ccd1SDavid Schultz #endif
164cc36ccd1SDavid Schultz }
165cc36ccd1SDavid Schultz while(sx <= sxe);
166cc36ccd1SDavid Schultz if (!*bxe) {
167cc36ccd1SDavid Schultz bx = b->x;
168cc36ccd1SDavid Schultz while(--bxe > bx && !*bxe)
169cc36ccd1SDavid Schultz --n;
170cc36ccd1SDavid Schultz b->wds = n;
171cc36ccd1SDavid Schultz }
172cc36ccd1SDavid Schultz }
173cc36ccd1SDavid Schultz if (cmp(b, S) >= 0) {
174cc36ccd1SDavid Schultz q++;
175cc36ccd1SDavid Schultz borrow = 0;
176cc36ccd1SDavid Schultz carry = 0;
177cc36ccd1SDavid Schultz bx = b->x;
178cc36ccd1SDavid Schultz sx = S->x;
179cc36ccd1SDavid Schultz do {
180cc36ccd1SDavid Schultz #ifdef ULLong
181cc36ccd1SDavid Schultz ys = *sx++ + carry;
182cc36ccd1SDavid Schultz carry = ys >> 32;
183cc36ccd1SDavid Schultz y = *bx - (ys & 0xffffffffUL) - borrow;
184cc36ccd1SDavid Schultz borrow = y >> 32 & 1UL;
185cc36ccd1SDavid Schultz *bx++ = y & 0xffffffffUL;
186cc36ccd1SDavid Schultz #else
187cc36ccd1SDavid Schultz #ifdef Pack_32
188cc36ccd1SDavid Schultz si = *sx++;
189cc36ccd1SDavid Schultz ys = (si & 0xffff) + carry;
190cc36ccd1SDavid Schultz zs = (si >> 16) + (ys >> 16);
191cc36ccd1SDavid Schultz carry = zs >> 16;
192cc36ccd1SDavid Schultz y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
193cc36ccd1SDavid Schultz borrow = (y & 0x10000) >> 16;
194cc36ccd1SDavid Schultz z = (*bx >> 16) - (zs & 0xffff) - borrow;
195cc36ccd1SDavid Schultz borrow = (z & 0x10000) >> 16;
196cc36ccd1SDavid Schultz Storeinc(bx, z, y);
197cc36ccd1SDavid Schultz #else
198cc36ccd1SDavid Schultz ys = *sx++ + carry;
199cc36ccd1SDavid Schultz carry = ys >> 16;
200cc36ccd1SDavid Schultz y = *bx - (ys & 0xffff) - borrow;
201cc36ccd1SDavid Schultz borrow = (y & 0x10000) >> 16;
202cc36ccd1SDavid Schultz *bx++ = y & 0xffff;
203cc36ccd1SDavid Schultz #endif
204cc36ccd1SDavid Schultz #endif
205cc36ccd1SDavid Schultz }
206cc36ccd1SDavid Schultz while(sx <= sxe);
207cc36ccd1SDavid Schultz bx = b->x;
208cc36ccd1SDavid Schultz bxe = bx + n;
209cc36ccd1SDavid Schultz if (!*bxe) {
210cc36ccd1SDavid Schultz while(--bxe > bx && !*bxe)
211cc36ccd1SDavid Schultz --n;
212cc36ccd1SDavid Schultz b->wds = n;
213cc36ccd1SDavid Schultz }
214cc36ccd1SDavid Schultz }
215cc36ccd1SDavid Schultz return q;
216cc36ccd1SDavid Schultz }
217