Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: third_party/WebKit/Source/wtf/dtoa.cpp

Issue 1611343002: wtf reformat test Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: pydent Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/wtf/dtoa.h ('k') | third_party/WebKit/Source/wtf/dtoa/bignum.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /**************************************************************** 1 /****************************************************************
2 * 2 *
3 * The author of this software is David M. Gay. 3 * The author of this software is David M. Gay.
4 * 4 *
5 * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. 5 * Copyright (c) 1991, 2000, 2001 by Lucent Technologies.
6 * Copyright (C) 2002, 2005, 2006, 2007, 2008, 2010, 2012 Apple Inc. All rights reserved. 6 * Copyright (C) 2002, 2005, 2006, 2007, 2008, 2010, 2012 Apple Inc. All rights reserved.
7 * 7 *
8 * Permission to use, copy, modify, and distribute this software for any 8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose without fee is hereby granted, provided that this entire notice 9 * purpose without fee is hereby granted, provided that this entire notice
10 * is included in all copies of any software which is or includes a copy 10 * is included in all copies of any software which is or includes a copy
(...skipping 23 matching lines...) Expand all
34 34
35 #include "wtf/dtoa.h" 35 #include "wtf/dtoa.h"
36 36
37 #include "wtf/CPU.h" 37 #include "wtf/CPU.h"
38 #include "wtf/MathExtras.h" 38 #include "wtf/MathExtras.h"
39 #include "wtf/ThreadingPrimitives.h" 39 #include "wtf/ThreadingPrimitives.h"
40 #include "wtf/Vector.h" 40 #include "wtf/Vector.h"
41 #include <string.h> 41 #include <string.h>
42 42
43 #if COMPILER(MSVC) 43 #if COMPILER(MSVC)
44 #pragma warning(disable: 4244) 44 #pragma warning(disable : 4244)
45 #pragma warning(disable: 4245) 45 #pragma warning(disable : 4245)
46 #pragma warning(disable: 4554) 46 #pragma warning(disable : 4554)
47 #endif 47 #endif
48 48
49 namespace WTF { 49 namespace WTF {
50 50
51 Mutex* s_dtoaP5Mutex; 51 Mutex* s_dtoaP5Mutex;
52 52
53 typedef union { 53 typedef union {
54 double d; 54 double d;
55 uint32_t L[2]; 55 uint32_t L[2];
56 } U; 56 } U;
57 57
58 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) 58 #if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN)
59 #define word0(x) (x)->L[0] 59 #define word0(x) (x)->L[0]
60 #define word1(x) (x)->L[1] 60 #define word1(x) (x)->L[1]
61 #else 61 #else
62 #define word0(x) (x)->L[1] 62 #define word0(x) (x)->L[1]
63 #define word1(x) (x)->L[0] 63 #define word1(x) (x)->L[0]
64 #endif 64 #endif
65 #define dval(x) (x)->d 65 #define dval(x) (x)->d
66 66
67 #define Exp_shift 20 67 #define Exp_shift 20
68 #define Exp_shift1 20 68 #define Exp_shift1 20
69 #define Exp_msk1 0x100000 69 #define Exp_msk1 0x100000
70 #define Exp_msk11 0x100000 70 #define Exp_msk11 0x100000
71 #define Exp_mask 0x7ff00000 71 #define Exp_mask 0x7ff00000
72 #define P 53 72 #define P 53
73 #define Bias 1023 73 #define Bias 1023
74 #define Emin (-1022) 74 #define Emin (-1022)
75 #define Exp_1 0x3ff00000 75 #define Exp_1 0x3ff00000
76 #define Exp_11 0x3ff00000 76 #define Exp_11 0x3ff00000
77 #define Ebits 11 77 #define Ebits 11
78 #define Frac_mask 0xfffff 78 #define Frac_mask 0xfffff
79 #define Frac_mask1 0xfffff 79 #define Frac_mask1 0xfffff
80 #define Ten_pmax 22 80 #define Ten_pmax 22
81 #define Bletch 0x10 81 #define Bletch 0x10
82 #define Bndry_mask 0xfffff 82 #define Bndry_mask 0xfffff
83 #define Bndry_mask1 0xfffff 83 #define Bndry_mask1 0xfffff
84 #define LSB 1 84 #define LSB 1
85 #define Sign_bit 0x80000000 85 #define Sign_bit 0x80000000
86 #define Log2P 1 86 #define Log2P 1
87 #define Tiny0 0 87 #define Tiny0 0
88 #define Tiny1 1 88 #define Tiny1 1
89 #define Quick_max 14 89 #define Quick_max 14
90 #define Int_max 14 90 #define Int_max 14
91 91
92 #define rounded_product(a, b) a *= b 92 #define rounded_product(a, b) a *= b
93 #define rounded_quotient(a, b) a /= b 93 #define rounded_quotient(a, b) a /= b
94 94
95 #define Big0 (Frac_mask1 | Exp_msk1 * (DBL_MAX_EXP + Bias - 1)) 95 #define Big0 (Frac_mask1 | Exp_msk1 * (DBL_MAX_EXP + Bias - 1))
96 #define Big1 0xffffffff 96 #define Big1 0xffffffff
97 97
98 #if CPU(X86_64) 98 #if CPU(X86_64)
99 // FIXME: should we enable this on all 64-bit CPUs? 99 // FIXME: should we enable this on all 64-bit CPUs?
100 // 64-bit emulation provided by the compiler is likely to be slower than dtoa ow n code on 32-bit hardware. 100 // 64-bit emulation provided by the compiler is likely to be slower than dtoa ow n code on 32-bit hardware.
101 #define USE_LONG_LONG 101 #define USE_LONG_LONG
102 #endif 102 #endif
103 103
104 #ifndef USE_LONG_LONG 104 #ifndef USE_LONG_LONG
105 /* The following definition of Storeinc is appropriate for MIPS processors. 105 /* The following definition of Storeinc is appropriate for MIPS processors.
106 * An alternative that might be better on some machines is 106 * An alternative that might be better on some machines is
107 * *p++ = high << 16 | low & 0xffff; 107 * *p++ = high << 16 | low & 0xffff;
108 */ 108 */
109 static ALWAYS_INLINE uint32_t* storeInc(uint32_t* p, uint16_t high, uint16_t low ) 109 static ALWAYS_INLINE uint32_t* storeInc(uint32_t* p,
110 uint16_t high,
111 uint16_t low) {
112 uint16_t* p16 = reinterpret_cast<uint16_t*>(p);
113 #if CPU(BIG_ENDIAN)
114 p16[0] = high;
115 p16[1] = low;
116 #else
117 p16[1] = high;
118 p16[0] = low;
119 #endif
120 return p + 1;
121 }
122 #endif
123
124 struct BigInt {
125 BigInt() : sign(0) {}
126 int sign;
127
128 void clear() {
129 sign = 0;
130 m_words.clear();
131 }
132
133 size_t size() const { return m_words.size(); }
134
135 void resize(size_t s) { m_words.resize(s); }
136
137 uint32_t* words() { return m_words.data(); }
138
139 const uint32_t* words() const { return m_words.data(); }
140
141 void append(uint32_t w) { m_words.append(w); }
142
143 Vector<uint32_t, 16> m_words;
144 };
145
146 static void multadd(BigInt& b, int m, int a) /* multiply by m and add a */
110 { 147 {
111 uint16_t* p16 = reinterpret_cast<uint16_t*>(p); 148 #ifdef USE_LONG_LONG
112 #if CPU(BIG_ENDIAN) 149 unsigned long long carry;
113 p16[0] = high; 150 #else
114 p16[1] = low; 151 uint32_t carry;
115 #else 152 #endif
116 p16[1] = high; 153
117 p16[0] = low; 154 int wds = b.size();
118 #endif 155 uint32_t* x = b.words();
119 return p + 1; 156 int i = 0;
120 } 157 carry = a;
121 #endif 158 do {
122 159 #ifdef USE_LONG_LONG
123 struct BigInt { 160 unsigned long long y = *x * (unsigned long long)m + carry;
124 BigInt() : sign(0) { } 161 carry = y >> 32;
125 int sign; 162 *x++ = (uint32_t)y & 0xffffffffUL;
126 163 #else
127 void clear() 164 uint32_t xi = *x;
128 { 165 uint32_t y = (xi & 0xffff) * m + carry;
129 sign = 0; 166 uint32_t z = (xi >> 16) * m + (y >> 16);
130 m_words.clear(); 167 carry = z >> 16;
131 } 168 *x++ = (z << 16) + (y & 0xffff);
132 169 #endif
133 size_t size() const 170 } while (++i < wds);
134 { 171
135 return m_words.size(); 172 if (carry)
136 } 173 b.append((uint32_t)carry);
137 174 }
138 void resize(size_t s) 175
139 { 176 static int hi0bits(uint32_t x) {
140 m_words.resize(s); 177 int k = 0;
141 } 178
142 179 if (!(x & 0xffff0000)) {
143 uint32_t* words() 180 k = 16;
144 { 181 x <<= 16;
145 return m_words.data(); 182 }
146 } 183 if (!(x & 0xff000000)) {
147 184 k += 8;
148 const uint32_t* words() const 185 x <<= 8;
149 { 186 }
150 return m_words.data(); 187 if (!(x & 0xf0000000)) {
151 } 188 k += 4;
152 189 x <<= 4;
153 void append(uint32_t w) 190 }
154 { 191 if (!(x & 0xc0000000)) {
155 m_words.append(w); 192 k += 2;
156 } 193 x <<= 2;
157 194 }
158 Vector<uint32_t, 16> m_words; 195 if (!(x & 0x80000000)) {
159 }; 196 k++;
160 197 if (!(x & 0x40000000))
161 static void multadd(BigInt& b, int m, int a) /* multiply by m and add a */ 198 return 32;
162 { 199 }
163 #ifdef USE_LONG_LONG 200 return k;
164 unsigned long long carry; 201 }
165 #else 202
166 uint32_t carry; 203 static int lo0bits(uint32_t* y) {
167 #endif 204 int k;
168 205 uint32_t x = *y;
169 int wds = b.size(); 206
170 uint32_t* x = b.words(); 207 if (x & 7) {
171 int i = 0; 208 if (x & 1)
172 carry = a; 209 return 0;
173 do { 210 if (x & 2) {
174 #ifdef USE_LONG_LONG 211 *y = x >> 1;
175 unsigned long long y = *x * (unsigned long long)m + carry; 212 return 1;
176 carry = y >> 32; 213 }
177 *x++ = (uint32_t)y & 0xffffffffUL; 214 *y = x >> 2;
178 #else 215 return 2;
179 uint32_t xi = *x; 216 }
180 uint32_t y = (xi & 0xffff) * m + carry; 217 k = 0;
181 uint32_t z = (xi >> 16) * m + (y >> 16); 218 if (!(x & 0xffff)) {
219 k = 16;
220 x >>= 16;
221 }
222 if (!(x & 0xff)) {
223 k += 8;
224 x >>= 8;
225 }
226 if (!(x & 0xf)) {
227 k += 4;
228 x >>= 4;
229 }
230 if (!(x & 0x3)) {
231 k += 2;
232 x >>= 2;
233 }
234 if (!(x & 1)) {
235 k++;
236 x >>= 1;
237 if (!x)
238 return 32;
239 }
240 *y = x;
241 return k;
242 }
243
244 static void i2b(BigInt& b, int i) {
245 b.sign = 0;
246 b.resize(1);
247 b.words()[0] = i;
248 }
249
250 static void mult(BigInt& aRef, const BigInt& bRef) {
251 const BigInt* a = &aRef;
252 const BigInt* b = &bRef;
253 BigInt c;
254 int wa, wb, wc;
255 const uint32_t* x = 0;
256 const uint32_t* xa;
257 const uint32_t* xb;
258 const uint32_t* xae;
259 const uint32_t* xbe;
260 uint32_t* xc;
261 uint32_t* xc0;
262 uint32_t y;
263 #ifdef USE_LONG_LONG
264 unsigned long long carry, z;
265 #else
266 uint32_t carry, z;
267 #endif
268
269 if (a->size() < b->size()) {
270 const BigInt* tmp = a;
271 a = b;
272 b = tmp;
273 }
274
275 wa = a->size();
276 wb = b->size();
277 wc = wa + wb;
278 c.resize(wc);
279
280 for (xc = c.words(), xa = xc + wc; xc < xa; xc++)
281 *xc = 0;
282 xa = a->words();
283 xae = xa + wa;
284 xb = b->words();
285 xbe = xb + wb;
286 xc0 = c.words();
287 #ifdef USE_LONG_LONG
288 for (; xb < xbe; xc0++) {
289 if ((y = *xb++)) {
290 x = xa;
291 xc = xc0;
292 carry = 0;
293 do {
294 z = *x++ * (unsigned long long)y + *xc + carry;
295 carry = z >> 32;
296 *xc++ = (uint32_t)z & 0xffffffffUL;
297 } while (x < xae);
298 *xc = (uint32_t)carry;
299 }
300 }
301 #else
302 for (; xb < xbe; xb++, xc0++) {
303 if ((y = *xb & 0xffff)) {
304 x = xa;
305 xc = xc0;
306 carry = 0;
307 do {
308 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
182 carry = z >> 16; 309 carry = z >> 16;
183 *x++ = (z << 16) + (y & 0xffff); 310 uint32_t z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
184 #endif 311 carry = z2 >> 16;
185 } while (++i < wds); 312 xc = storeInc(xc, z2, z);
186 313 } while (x < xae);
187 if (carry) 314 *xc = carry;
188 b.append((uint32_t)carry); 315 }
189 } 316 if ((y = *xb >> 16)) {
190 317 x = xa;
191 static int hi0bits(uint32_t x) 318 xc = xc0;
192 { 319 carry = 0;
193 int k = 0; 320 uint32_t z2 = *xc;
194 321 do {
195 if (!(x & 0xffff0000)) { 322 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
196 k = 16; 323 carry = z >> 16;
197 x <<= 16; 324 xc = storeInc(xc, z, z2);
198 } 325 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
199 if (!(x & 0xff000000)) { 326 carry = z2 >> 16;
200 k += 8; 327 } while (x < xae);
201 x <<= 8; 328 *xc = z2;
202 } 329 }
203 if (!(x & 0xf0000000)) { 330 }
204 k += 4; 331 #endif
205 x <<= 4; 332 for (xc0 = c.words(), xc = xc0 + wc; wc > 0 && !*--xc; --wc) {
206 } 333 }
207 if (!(x & 0xc0000000)) { 334 c.resize(wc);
208 k += 2; 335 aRef = c;
209 x <<= 2;
210 }
211 if (!(x & 0x80000000)) {
212 k++;
213 if (!(x & 0x40000000))
214 return 32;
215 }
216 return k;
217 }
218
219 static int lo0bits(uint32_t* y)
220 {
221 int k;
222 uint32_t x = *y;
223
224 if (x & 7) {
225 if (x & 1)
226 return 0;
227 if (x & 2) {
228 *y = x >> 1;
229 return 1;
230 }
231 *y = x >> 2;
232 return 2;
233 }
234 k = 0;
235 if (!(x & 0xffff)) {
236 k = 16;
237 x >>= 16;
238 }
239 if (!(x & 0xff)) {
240 k += 8;
241 x >>= 8;
242 }
243 if (!(x & 0xf)) {
244 k += 4;
245 x >>= 4;
246 }
247 if (!(x & 0x3)) {
248 k += 2;
249 x >>= 2;
250 }
251 if (!(x & 1)) {
252 k++;
253 x >>= 1;
254 if (!x)
255 return 32;
256 }
257 *y = x;
258 return k;
259 }
260
261 static void i2b(BigInt& b, int i)
262 {
263 b.sign = 0;
264 b.resize(1);
265 b.words()[0] = i;
266 }
267
268 static void mult(BigInt& aRef, const BigInt& bRef)
269 {
270 const BigInt* a = &aRef;
271 const BigInt* b = &bRef;
272 BigInt c;
273 int wa, wb, wc;
274 const uint32_t* x = 0;
275 const uint32_t* xa;
276 const uint32_t* xb;
277 const uint32_t* xae;
278 const uint32_t* xbe;
279 uint32_t* xc;
280 uint32_t* xc0;
281 uint32_t y;
282 #ifdef USE_LONG_LONG
283 unsigned long long carry, z;
284 #else
285 uint32_t carry, z;
286 #endif
287
288 if (a->size() < b->size()) {
289 const BigInt* tmp = a;
290 a = b;
291 b = tmp;
292 }
293
294 wa = a->size();
295 wb = b->size();
296 wc = wa + wb;
297 c.resize(wc);
298
299 for (xc = c.words(), xa = xc + wc; xc < xa; xc++)
300 *xc = 0;
301 xa = a->words();
302 xae = xa + wa;
303 xb = b->words();
304 xbe = xb + wb;
305 xc0 = c.words();
306 #ifdef USE_LONG_LONG
307 for (; xb < xbe; xc0++) {
308 if ((y = *xb++)) {
309 x = xa;
310 xc = xc0;
311 carry = 0;
312 do {
313 z = *x++ * (unsigned long long)y + *xc + carry;
314 carry = z >> 32;
315 *xc++ = (uint32_t)z & 0xffffffffUL;
316 } while (x < xae);
317 *xc = (uint32_t)carry;
318 }
319 }
320 #else
321 for (; xb < xbe; xb++, xc0++) {
322 if ((y = *xb & 0xffff)) {
323 x = xa;
324 xc = xc0;
325 carry = 0;
326 do {
327 z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
328 carry = z >> 16;
329 uint32_t z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
330 carry = z2 >> 16;
331 xc = storeInc(xc, z2, z);
332 } while (x < xae);
333 *xc = carry;
334 }
335 if ((y = *xb >> 16)) {
336 x = xa;
337 xc = xc0;
338 carry = 0;
339 uint32_t z2 = *xc;
340 do {
341 z = (*x & 0xffff) * y + (*xc >> 16) + carry;
342 carry = z >> 16;
343 xc = storeInc(xc, z, z2);
344 z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
345 carry = z2 >> 16;
346 } while (x < xae);
347 *xc = z2;
348 }
349 }
350 #endif
351 for (xc0 = c.words(), xc = xc0 + wc; wc > 0 && !*--xc; --wc) { }
352 c.resize(wc);
353 aRef = c;
354 } 336 }
355 337
356 struct P5Node { 338 struct P5Node {
357 WTF_MAKE_NONCOPYABLE(P5Node); USING_FAST_MALLOC(P5Node); 339 WTF_MAKE_NONCOPYABLE(P5Node);
358 public: 340 USING_FAST_MALLOC(P5Node);
359 P5Node() { } 341
360 BigInt val; 342 public:
361 P5Node* next; 343 P5Node() {}
344 BigInt val;
345 P5Node* next;
362 }; 346 };
363 347
364 static P5Node* p5s; 348 static P5Node* p5s;
365 static int p5sCount; 349 static int p5sCount;
366 350
367 static ALWAYS_INLINE void pow5mult(BigInt& b, int k) 351 static ALWAYS_INLINE void pow5mult(BigInt& b, int k) {
368 { 352 static int p05[3] = {5, 25, 125};
369 static int p05[3] = { 5, 25, 125 }; 353
370 354 if (int i = k & 3)
371 if (int i = k & 3) 355 multadd(b, p05[i - 1], 0);
372 multadd(b, p05[i - 1], 0); 356
373 357 if (!(k >>= 2))
374 if (!(k >>= 2)) 358 return;
375 return; 359
376 360 s_dtoaP5Mutex->lock();
377 s_dtoaP5Mutex->lock(); 361 P5Node* p5 = p5s;
378 P5Node* p5 = p5s; 362
379 363 if (!p5) {
380 if (!p5) { 364 /* first time */
381 /* first time */ 365 p5 = new P5Node;
382 p5 = new P5Node; 366 i2b(p5->val, 625);
383 i2b(p5->val, 625); 367 p5->next = 0;
384 p5->next = 0; 368 p5s = p5;
385 p5s = p5; 369 p5sCount = 1;
386 p5sCount = 1; 370 }
387 } 371
388 372 int p5sCountLocal = p5sCount;
389 int p5sCountLocal = p5sCount; 373 s_dtoaP5Mutex->unlock();
390 s_dtoaP5Mutex->unlock(); 374 int p5sUsed = 0;
391 int p5sUsed = 0; 375
392 376 for (;;) {
393 for (;;) { 377 if (k & 1)
394 if (k & 1) 378 mult(b, p5->val);
395 mult(b, p5->val); 379
396 380 if (!(k >>= 1))
397 if (!(k >>= 1)) 381 break;
398 break; 382
399 383 if (++p5sUsed == p5sCountLocal) {
400 if (++p5sUsed == p5sCountLocal) { 384 s_dtoaP5Mutex->lock();
401 s_dtoaP5Mutex->lock(); 385 if (p5sUsed == p5sCount) {
402 if (p5sUsed == p5sCount) { 386 ASSERT(!p5->next);
403 ASSERT(!p5->next); 387 p5->next = new P5Node;
404 p5->next = new P5Node; 388 p5->next->next = 0;
405 p5->next->next = 0; 389 p5->next->val = p5->val;
406 p5->next->val = p5->val; 390 mult(p5->next->val, p5->next->val);
407 mult(p5->next->val, p5->next->val); 391 ++p5sCount;
408 ++p5sCount; 392 }
409 } 393
410 394 p5sCountLocal = p5sCount;
411 p5sCountLocal = p5sCount; 395 s_dtoaP5Mutex->unlock();
412 s_dtoaP5Mutex->unlock(); 396 }
413 } 397 p5 = p5->next;
414 p5 = p5->next; 398 }
415 } 399 }
416 } 400
417 401 static ALWAYS_INLINE void lshift(BigInt& b, int k) {
418 static ALWAYS_INLINE void lshift(BigInt& b, int k) 402 int n = k >> 5;
419 { 403
420 int n = k >> 5; 404 int origSize = b.size();
421 405 int n1 = n + origSize + 1;
422 int origSize = b.size(); 406
423 int n1 = n + origSize + 1; 407 if (k &= 0x1f)
424 408 b.resize(b.size() + n + 1);
425 if (k &= 0x1f) 409 else
426 b.resize(b.size() + n + 1); 410 b.resize(b.size() + n);
427 else 411
428 b.resize(b.size() + n); 412 const uint32_t* srcStart = b.words();
429 413 uint32_t* dstStart = b.words();
430 const uint32_t* srcStart = b.words(); 414 const uint32_t* src = srcStart + origSize - 1;
431 uint32_t* dstStart = b.words(); 415 uint32_t* dst = dstStart + n1 - 1;
432 const uint32_t* src = srcStart + origSize - 1; 416 if (k) {
433 uint32_t* dst = dstStart + n1 - 1; 417 uint32_t hiSubword = 0;
434 if (k) { 418 int s = 32 - k;
435 uint32_t hiSubword = 0; 419 for (; src >= srcStart; --src) {
436 int s = 32 - k; 420 *dst-- = hiSubword | *src >> s;
437 for (; src >= srcStart; --src) { 421 hiSubword = *src << k;
438 *dst-- = hiSubword | *src >> s; 422 }
439 hiSubword = *src << k; 423 *dst = hiSubword;
440 } 424 ASSERT(dst == dstStart + n);
441 *dst = hiSubword; 425
442 ASSERT(dst == dstStart + n); 426 b.resize(origSize + n + !!b.words()[n1 - 1]);
443 427 } else {
444 b.resize(origSize + n + !!b.words()[n1 - 1]);
445 }
446 else {
447 do {
448 *--dst = *src--;
449 } while (src >= srcStart);
450 }
451 for (dst = dstStart + n; dst != dstStart; )
452 *--dst = 0;
453
454 ASSERT(b.size() <= 1 || b.words()[b.size() - 1]);
455 }
456
457 static int cmp(const BigInt& a, const BigInt& b)
458 {
459 const uint32_t *xa, *xa0, *xb, *xb0;
460 int i, j;
461
462 i = a.size();
463 j = b.size();
464 ASSERT(i <= 1 || a.words()[i - 1]);
465 ASSERT(j <= 1 || b.words()[j - 1]);
466 if (i -= j)
467 return i;
468 xa0 = a.words();
469 xa = xa0 + j;
470 xb0 = b.words();
471 xb = xb0 + j;
472 for (;;) {
473 if (*--xa != *--xb)
474 return *xa < *xb ? -1 : 1;
475 if (xa <= xa0)
476 break;
477 }
478 return 0;
479 }
480
481 static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef )
482 {
483 const BigInt* a = &aRef;
484 const BigInt* b = &bRef;
485 int i, wa, wb;
486 uint32_t* xc;
487
488 i = cmp(*a, *b);
489 if (!i) {
490 c.sign = 0;
491 c.resize(1);
492 c.words()[0] = 0;
493 return;
494 }
495 if (i < 0) {
496 const BigInt* tmp = a;
497 a = b;
498 b = tmp;
499 i = 1;
500 } else
501 i = 0;
502
503 wa = a->size();
504 const uint32_t* xa = a->words();
505 const uint32_t* xae = xa + wa;
506 wb = b->size();
507 const uint32_t* xb = b->words();
508 const uint32_t* xbe = xb + wb;
509
510 c.resize(wa);
511 c.sign = i;
512 xc = c.words();
513 #ifdef USE_LONG_LONG
514 unsigned long long borrow = 0;
515 do { 428 do {
516 unsigned long long y = (unsigned long long)*xa++ - *xb++ - borrow; 429 *--dst = *src--;
517 borrow = y >> 32 & (uint32_t)1; 430 } while (src >= srcStart);
518 *xc++ = (uint32_t)y & 0xffffffffUL; 431 }
519 } while (xb < xbe); 432 for (dst = dstStart + n; dst != dstStart;)
520 while (xa < xae) { 433 *--dst = 0;
521 unsigned long long y = *xa++ - borrow; 434
522 borrow = y >> 32 & (uint32_t)1; 435 ASSERT(b.size() <= 1 || b.words()[b.size() - 1]);
523 *xc++ = (uint32_t)y & 0xffffffffUL; 436 }
524 } 437
525 #else 438 static int cmp(const BigInt& a, const BigInt& b) {
526 uint32_t borrow = 0; 439 const uint32_t *xa, *xa0, *xb, *xb0;
527 do { 440 int i, j;
528 uint32_t y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; 441
529 borrow = (y & 0x10000) >> 16; 442 i = a.size();
530 uint32_t z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; 443 j = b.size();
531 borrow = (z & 0x10000) >> 16; 444 ASSERT(i <= 1 || a.words()[i - 1]);
532 xc = storeInc(xc, z, y); 445 ASSERT(j <= 1 || b.words()[j - 1]);
533 } while (xb < xbe); 446 if (i -= j)
534 while (xa < xae) { 447 return i;
535 uint32_t y = (*xa & 0xffff) - borrow; 448 xa0 = a.words();
536 borrow = (y & 0x10000) >> 16; 449 xa = xa0 + j;
537 uint32_t z = (*xa++ >> 16) - borrow; 450 xb0 = b.words();
538 borrow = (z & 0x10000) >> 16; 451 xb = xb0 + j;
539 xc = storeInc(xc, z, y); 452 for (;;) {
540 } 453 if (*--xa != *--xb)
541 #endif 454 return *xa < *xb ? -1 : 1;
542 while (!*--xc) 455 if (xa <= xa0)
543 wa--; 456 break;
544 c.resize(wa); 457 }
545 } 458 return 0;
546 459 }
547 static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits) 460
548 { 461 static ALWAYS_INLINE void diff(BigInt& c,
549 int de, k; 462 const BigInt& aRef,
550 uint32_t* x; 463 const BigInt& bRef) {
551 uint32_t y, z; 464 const BigInt* a = &aRef;
552 int i; 465 const BigInt* b = &bRef;
466 int i, wa, wb;
467 uint32_t* xc;
468
469 i = cmp(*a, *b);
470 if (!i) {
471 c.sign = 0;
472 c.resize(1);
473 c.words()[0] = 0;
474 return;
475 }
476 if (i < 0) {
477 const BigInt* tmp = a;
478 a = b;
479 b = tmp;
480 i = 1;
481 } else
482 i = 0;
483
484 wa = a->size();
485 const uint32_t* xa = a->words();
486 const uint32_t* xae = xa + wa;
487 wb = b->size();
488 const uint32_t* xb = b->words();
489 const uint32_t* xbe = xb + wb;
490
491 c.resize(wa);
492 c.sign = i;
493 xc = c.words();
494 #ifdef USE_LONG_LONG
495 unsigned long long borrow = 0;
496 do {
497 unsigned long long y = (unsigned long long)*xa++ - *xb++ - borrow;
498 borrow = y >> 32 & (uint32_t)1;
499 *xc++ = (uint32_t)y & 0xffffffffUL;
500 } while (xb < xbe);
501 while (xa < xae) {
502 unsigned long long y = *xa++ - borrow;
503 borrow = y >> 32 & (uint32_t)1;
504 *xc++ = (uint32_t)y & 0xffffffffUL;
505 }
506 #else
507 uint32_t borrow = 0;
508 do {
509 uint32_t y = (*xa & 0xffff) - (*xb & 0xffff) - borrow;
510 borrow = (y & 0x10000) >> 16;
511 uint32_t z = (*xa++ >> 16) - (*xb++ >> 16) - borrow;
512 borrow = (z & 0x10000) >> 16;
513 xc = storeInc(xc, z, y);
514 } while (xb < xbe);
515 while (xa < xae) {
516 uint32_t y = (*xa & 0xffff) - borrow;
517 borrow = (y & 0x10000) >> 16;
518 uint32_t z = (*xa++ >> 16) - borrow;
519 borrow = (z & 0x10000) >> 16;
520 xc = storeInc(xc, z, y);
521 }
522 #endif
523 while (!*--xc)
524 wa--;
525 c.resize(wa);
526 }
527
528 static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits) {
529 int de, k;
530 uint32_t* x;
531 uint32_t y, z;
532 int i;
553 #define d0 word0(d) 533 #define d0 word0(d)
554 #define d1 word1(d) 534 #define d1 word1(d)
555 535
556 b.sign = 0; 536 b.sign = 0;
537 b.resize(1);
538 x = b.words();
539
540 z = d0 & Frac_mask;
541 d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
542 if ((de = (int)(d0 >> Exp_shift)))
543 z |= Exp_msk1;
544 if ((y = d1)) {
545 if ((k = lo0bits(&y))) {
546 x[0] = y | (z << (32 - k));
547 z >>= k;
548 } else
549 x[0] = y;
550 if (z) {
551 b.resize(2);
552 x[1] = z;
553 }
554
555 i = b.size();
556 } else {
557 k = lo0bits(&z);
558 x[0] = z;
559 i = 1;
557 b.resize(1); 560 b.resize(1);
558 x = b.words(); 561 k += 32;
559 562 }
560 z = d0 & Frac_mask; 563 if (de) {
561 d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ 564 *e = de - Bias - (P - 1) + k;
562 if ((de = (int)(d0 >> Exp_shift))) 565 *bits = P - k;
563 z |= Exp_msk1; 566 } else {
564 if ((y = d1)) { 567 *e = 0 - Bias - (P - 1) + 1 + k;
565 if ((k = lo0bits(&y))) { 568 *bits = (32 * i) - hi0bits(x[i - 1]);
566 x[0] = y | (z << (32 - k)); 569 }
567 z >>= k;
568 } else
569 x[0] = y;
570 if (z) {
571 b.resize(2);
572 x[1] = z;
573 }
574
575 i = b.size();
576 } else {
577 k = lo0bits(&z);
578 x[0] = z;
579 i = 1;
580 b.resize(1);
581 k += 32;
582 }
583 if (de) {
584 *e = de - Bias - (P - 1) + k;
585 *bits = P - k;
586 } else {
587 *e = 0 - Bias - (P - 1) + 1 + k;
588 *bits = (32 * i) - hi0bits(x[i - 1]);
589 }
590 } 570 }
591 #undef d0 571 #undef d0
592 #undef d1 572 #undef d1
593 573
594 static const double tens[] = { 574 static const double tens[] = {1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7,
595 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 575 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
596 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 576 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
597 1e20, 1e21, 1e22 577
598 }; 578 static const double bigtens[] = {1e16, 1e32, 1e64, 1e128, 1e256};
599
600 static const double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
601 579
602 #define Scale_Bit 0x10 580 #define Scale_Bit 0x10
603 #define n_bigtens 5 581 #define n_bigtens 5
604 582
605 static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) 583 static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) {
606 { 584 size_t n;
607 size_t n; 585 uint32_t* bx;
608 uint32_t* bx; 586 uint32_t* bxe;
609 uint32_t* bxe; 587 uint32_t q;
610 uint32_t q; 588 uint32_t* sx;
611 uint32_t* sx; 589 uint32_t* sxe;
612 uint32_t* sxe; 590 #ifdef USE_LONG_LONG
613 #ifdef USE_LONG_LONG 591 unsigned long long borrow, carry, y, ys;
614 unsigned long long borrow, carry, y, ys; 592 #else
615 #else 593 uint32_t borrow, carry, y, ys;
616 uint32_t borrow, carry, y, ys; 594 uint32_t si, z, zs;
617 uint32_t si, z, zs; 595 #endif
618 #endif 596 ASSERT(b.size() <= 1 || b.words()[b.size() - 1]);
619 ASSERT(b.size() <= 1 || b.words()[b.size() - 1]); 597 ASSERT(S.size() <= 1 || S.words()[S.size() - 1]);
620 ASSERT(S.size() <= 1 || S.words()[S.size() - 1]); 598
621 599 n = S.size();
622 n = S.size(); 600 ASSERT_WITH_MESSAGE(b.size() <= n, "oversize b in quorem");
623 ASSERT_WITH_MESSAGE(b.size() <= n, "oversize b in quorem"); 601 if (b.size() < n)
624 if (b.size() < n) 602 return 0;
625 return 0; 603 sx = S.words();
604 sxe = sx + --n;
605 bx = b.words();
606 bxe = bx + n;
607 q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
608 ASSERT_WITH_MESSAGE(q <= 9, "oversized quotient in quorem");
609 if (q) {
610 borrow = 0;
611 carry = 0;
612 do {
613 #ifdef USE_LONG_LONG
614 ys = *sx++ * (unsigned long long)q + carry;
615 carry = ys >> 32;
616 y = *bx - (ys & 0xffffffffUL) - borrow;
617 borrow = y >> 32 & (uint32_t)1;
618 *bx++ = (uint32_t)y & 0xffffffffUL;
619 #else
620 si = *sx++;
621 ys = (si & 0xffff) * q + carry;
622 zs = (si >> 16) * q + (ys >> 16);
623 carry = zs >> 16;
624 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
625 borrow = (y & 0x10000) >> 16;
626 z = (*bx >> 16) - (zs & 0xffff) - borrow;
627 borrow = (z & 0x10000) >> 16;
628 bx = storeInc(bx, z, y);
629 #endif
630 } while (sx <= sxe);
631 if (!*bxe) {
632 bx = b.words();
633 while (--bxe > bx && !*bxe)
634 --n;
635 b.resize(n);
636 }
637 }
638 if (cmp(b, S) >= 0) {
639 q++;
640 borrow = 0;
641 carry = 0;
642 bx = b.words();
626 sx = S.words(); 643 sx = S.words();
627 sxe = sx + --n; 644 do {
645 #ifdef USE_LONG_LONG
646 ys = *sx++ + carry;
647 carry = ys >> 32;
648 y = *bx - (ys & 0xffffffffUL) - borrow;
649 borrow = y >> 32 & (uint32_t)1;
650 *bx++ = (uint32_t)y & 0xffffffffUL;
651 #else
652 si = *sx++;
653 ys = (si & 0xffff) + carry;
654 zs = (si >> 16) + (ys >> 16);
655 carry = zs >> 16;
656 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
657 borrow = (y & 0x10000) >> 16;
658 z = (*bx >> 16) - (zs & 0xffff) - borrow;
659 borrow = (z & 0x10000) >> 16;
660 bx = storeInc(bx, z, y);
661 #endif
662 } while (sx <= sxe);
628 bx = b.words(); 663 bx = b.words();
629 bxe = bx + n; 664 bxe = bx + n;
630 q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ 665 if (!*bxe) {
631 ASSERT_WITH_MESSAGE(q <= 9, "oversized quotient in quorem"); 666 while (--bxe > bx && !*bxe)
632 if (q) { 667 --n;
633 borrow = 0; 668 b.resize(n);
634 carry = 0; 669 }
635 do { 670 }
636 #ifdef USE_LONG_LONG 671 return q;
637 ys = *sx++ * (unsigned long long)q + carry;
638 carry = ys >> 32;
639 y = *bx - (ys & 0xffffffffUL) - borrow;
640 borrow = y >> 32 & (uint32_t)1;
641 *bx++ = (uint32_t)y & 0xffffffffUL;
642 #else
643 si = *sx++;
644 ys = (si & 0xffff) * q + carry;
645 zs = (si >> 16) * q + (ys >> 16);
646 carry = zs >> 16;
647 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
648 borrow = (y & 0x10000) >> 16;
649 z = (*bx >> 16) - (zs & 0xffff) - borrow;
650 borrow = (z & 0x10000) >> 16;
651 bx = storeInc(bx, z, y);
652 #endif
653 } while (sx <= sxe);
654 if (!*bxe) {
655 bx = b.words();
656 while (--bxe > bx && !*bxe)
657 --n;
658 b.resize(n);
659 }
660 }
661 if (cmp(b, S) >= 0) {
662 q++;
663 borrow = 0;
664 carry = 0;
665 bx = b.words();
666 sx = S.words();
667 do {
668 #ifdef USE_LONG_LONG
669 ys = *sx++ + carry;
670 carry = ys >> 32;
671 y = *bx - (ys & 0xffffffffUL) - borrow;
672 borrow = y >> 32 & (uint32_t)1;
673 *bx++ = (uint32_t)y & 0xffffffffUL;
674 #else
675 si = *sx++;
676 ys = (si & 0xffff) + carry;
677 zs = (si >> 16) + (ys >> 16);
678 carry = zs >> 16;
679 y = (*bx & 0xffff) - (ys & 0xffff) - borrow;
680 borrow = (y & 0x10000) >> 16;
681 z = (*bx >> 16) - (zs & 0xffff) - borrow;
682 borrow = (z & 0x10000) >> 16;
683 bx = storeInc(bx, z, y);
684 #endif
685 } while (sx <= sxe);
686 bx = b.words();
687 bxe = bx + n;
688 if (!*bxe) {
689 while (--bxe > bx && !*bxe)
690 --n;
691 b.resize(n);
692 }
693 }
694 return q;
695 } 672 }
696 673
697 /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. 674 /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
698 * 675 *
699 * Inspired by "How to Print Floating-Point Numbers Accurately" by 676 * Inspired by "How to Print Floating-Point Numbers Accurately" by
700 * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. 677 * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126].
701 * 678 *
702 * Modifications: 679 * Modifications:
703 * 1. Rather than iterating, we use a simple numeric overestimate 680 * 1. Rather than iterating, we use a simple numeric overestimate
704 * to determine k = floor(log10(d)). We scale relevant 681 * to determine k = floor(log10(d)). We scale relevant
(...skipping 17 matching lines...) Expand all
722 * to get by with floating-point arithmetic; we resort to 699 * to get by with floating-point arithmetic; we resort to
723 * multiple-precision integer arithmetic only if we cannot 700 * multiple-precision integer arithmetic only if we cannot
724 * guarantee that the floating-point calculation has given 701 * guarantee that the floating-point calculation has given
725 * the correctly rounded result. For k requested digits and 702 * the correctly rounded result. For k requested digits and
726 * "uniformly" distributed input, the probability is 703 * "uniformly" distributed input, the probability is
727 * something like 10^(k-15) that we must resort to the int32_t 704 * something like 10^(k-15) that we must resort to the int32_t
728 * calculation. 705 * calculation.
729 * 706 *
730 * Note: 'leftright' translates to 'generate shortest possible string'. 707 * Note: 'leftright' translates to 'generate shortest possible string'.
731 */ 708 */
732 template<bool roundingNone, bool roundingSignificantFigures, bool roundingDecima lPlaces, bool leftright> 709 template <bool roundingNone,
733 void dtoa(DtoaBuffer result, double dd, int ndigits, bool& signOut, int& exponen tOut, unsigned& precisionOut) 710 bool roundingSignificantFigures,
734 { 711 bool roundingDecimalPlaces,
735 // Exactly one rounding mode must be specified. 712 bool leftright>
736 ASSERT(roundingNone + roundingSignificantFigures + roundingDecimalPlaces == 1); 713 void dtoa(DtoaBuffer result,
737 // roundingNone only allowed (only sensible?) with leftright set. 714 double dd,
738 ASSERT(!roundingNone || leftright); 715 int ndigits,
716 bool& signOut,
717 int& exponentOut,
718 unsigned& precisionOut) {
719 // Exactly one rounding mode must be specified.
720 ASSERT(roundingNone + roundingSignificantFigures + roundingDecimalPlaces ==
721 1);
722 // roundingNone only allowed (only sensible?) with leftright set.
723 ASSERT(!roundingNone || leftright);
739 724
740 ASSERT(std::isfinite(dd)); 725 ASSERT(std::isfinite(dd));
741 726
742 int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, 727 int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, j, j1, k, k0,
743 j, j1, k, k0, k_check, m2, m5, s2, s5, 728 k_check, m2, m5, s2, s5, spec_case;
744 spec_case; 729 int32_t L;
745 int32_t L; 730 int denorm;
746 int denorm; 731 uint32_t x;
747 uint32_t x; 732 BigInt b, delta, mlo, mhi, S;
748 BigInt b, delta, mlo, mhi, S; 733 U d2, eps, u;
749 U d2, eps, u; 734 double ds;
750 double ds; 735 char* s;
751 char* s; 736 char* s0;
752 char* s0;
753 737
754 u.d = dd; 738 u.d = dd;
755 739
756 /* Infinity or NaN */ 740 /* Infinity or NaN */
757 ASSERT((word0(&u) & Exp_mask) != Exp_mask); 741 ASSERT((word0(&u) & Exp_mask) != Exp_mask);
758 742
759 // JavaScript toString conversion treats -0 as 0. 743 // JavaScript toString conversion treats -0 as 0.
760 if (!dval(&u)) { 744 if (!dval(&u)) {
761 signOut = false; 745 signOut = false;
762 exponentOut = 0; 746 exponentOut = 0;
763 precisionOut = 1; 747 precisionOut = 1;
764 result[0] = '0'; 748 result[0] = '0';
765 result[1] = '\0'; 749 result[1] = '\0';
766 return; 750 return;
767 } 751 }
768 752
769 if (word0(&u) & Sign_bit) { 753 if (word0(&u) & Sign_bit) {
770 signOut = true; 754 signOut = true;
771 word0(&u) &= ~Sign_bit; // clear sign bit 755 word0(&u) &= ~Sign_bit; // clear sign bit
772 } else 756 } else
773 signOut = false; 757 signOut = false;
774 758
775 d2b(b, &u, &be, &bbits); 759 d2b(b, &u, &be, &bbits);
776 if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask >> Exp_shift1)))) { 760 if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask >> Exp_shift1)))) {
777 dval(&d2) = dval(&u); 761 dval(&d2) = dval(&u);
778 word0(&d2) &= Frac_mask1; 762 word0(&d2) &= Frac_mask1;
779 word0(&d2) |= Exp_11; 763 word0(&d2) |= Exp_11;
780 764
781 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 765 /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
782 * log10(x) = log(x) / log(10) 766 * log10(x) = log(x) / log(10)
783 * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) 767 * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
784 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) 768 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
785 * 769 *
786 * This suggests computing an approximation k to log10(d) by 770 * This suggests computing an approximation k to log10(d) by
787 * 771 *
788 * k = (i - Bias)*0.301029995663981 772 * k = (i - Bias)*0.301029995663981
789 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); 773 * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
790 * 774 *
791 * We want k to be too large rather than too small. 775 * We want k to be too large rather than too small.
792 * The error in the first-order Taylor series approximation 776 * The error in the first-order Taylor series approximation
793 * is in our favor, so we just round up the constant enough 777 * is in our favor, so we just round up the constant enough
794 * to compensate for any error in the multiplication of 778 * to compensate for any error in the multiplication of
795 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, 779 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
796 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, 780 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
797 * adding 1e-13 to the constant term more than suffices. 781 * adding 1e-13 to the constant term more than suffices.
798 * Hence we adjust the constant term to 0.1760912590558. 782 * Hence we adjust the constant term to 0.1760912590558.
799 * (We could get a more accurate k by invoking log10, 783 * (We could get a more accurate k by invoking log10,
800 * but this is probably not worthwhile.) 784 * but this is probably not worthwhile.)
801 */ 785 */
802 786
803 i -= Bias; 787 i -= Bias;
804 denorm = 0; 788 denorm = 0;
805 } else { 789 } else {
806 /* d is denormalized */ 790 /* d is denormalized */
807 791
808 i = bbits + be + (Bias + (P - 1) - 1); 792 i = bbits + be + (Bias + (P - 1) - 1);
809 x = (i > 32) ? (word0(&u) << (64 - i)) | (word1(&u) >> (i - 32)) 793 x = (i > 32) ? (word0(&u) << (64 - i)) | (word1(&u) >> (i - 32))
810 : word1(&u) << (32 - i); 794 : word1(&u) << (32 - i);
811 dval(&d2) = x; 795 dval(&d2) = x;
812 word0(&d2) -= 31 * Exp_msk1; /* adjust exponent */ 796 word0(&d2) -= 31 * Exp_msk1; /* adjust exponent */
813 i -= (Bias + (P - 1) - 1) + 1; 797 i -= (Bias + (P - 1) - 1) + 1;
814 denorm = 1; 798 denorm = 1;
815 } 799 }
816 ds = (dval(&d2) - 1.5) * 0.289529654602168 + 0.1760912590558 + (i * 0.301029 995663981); 800 ds = (dval(&d2) - 1.5) * 0.289529654602168 + 0.1760912590558 +
817 k = (int)ds; 801 (i * 0.301029995663981);
818 if (ds < 0. && ds != k) 802 k = (int)ds;
819 k--; /* want k = floor(ds) */ 803 if (ds < 0. && ds != k)
820 k_check = 1; 804 k--; /* want k = floor(ds) */
821 if (k >= 0 && k <= Ten_pmax) { 805 k_check = 1;
822 if (dval(&u) < tens[k]) 806 if (k >= 0 && k <= Ten_pmax) {
823 k--; 807 if (dval(&u) < tens[k])
824 k_check = 0; 808 k--;
825 } 809 k_check = 0;
826 j = bbits - i - 1; 810 }
827 if (j >= 0) { 811 j = bbits - i - 1;
828 b2 = 0; 812 if (j >= 0) {
829 s2 = j; 813 b2 = 0;
830 } else { 814 s2 = j;
831 b2 = -j; 815 } else {
832 s2 = 0; 816 b2 = -j;
833 } 817 s2 = 0;
834 if (k >= 0) { 818 }
835 b5 = 0; 819 if (k >= 0) {
836 s5 = k; 820 b5 = 0;
837 s2 += k; 821 s5 = k;
838 } else { 822 s2 += k;
839 b2 -= k; 823 } else {
840 b5 = -k; 824 b2 -= k;
841 s5 = 0; 825 b5 = -k;
842 } 826 s5 = 0;
843 827 }
844 if (roundingNone) { 828
845 ilim = ilim1 = -1; 829 if (roundingNone) {
846 i = 18; 830 ilim = ilim1 = -1;
847 ndigits = 0; 831 i = 18;
848 } 832 ndigits = 0;
849 if (roundingSignificantFigures) { 833 }
850 if (ndigits <= 0) 834 if (roundingSignificantFigures) {
851 ndigits = 1; 835 if (ndigits <= 0)
852 ilim = ilim1 = i = ndigits; 836 ndigits = 1;
853 } 837 ilim = ilim1 = i = ndigits;
854 if (roundingDecimalPlaces) { 838 }
855 i = ndigits + k + 1; 839 if (roundingDecimalPlaces) {
856 ilim = i; 840 i = ndigits + k + 1;
857 ilim1 = i - 1; 841 ilim = i;
858 if (i <= 0) 842 ilim1 = i - 1;
859 i = 1; 843 if (i <= 0)
860 } 844 i = 1;
861 845 }
862 s = s0 = result; 846
863 847 s = s0 = result;
864 if (ilim >= 0 && ilim <= Quick_max) { 848
865 /* Try to get by with floating-point arithmetic. */ 849 if (ilim >= 0 && ilim <= Quick_max) {
866 850 /* Try to get by with floating-point arithmetic. */
867 i = 0; 851
868 dval(&d2) = dval(&u); 852 i = 0;
869 k0 = k; 853 dval(&d2) = dval(&u);
870 ilim0 = ilim; 854 k0 = k;
871 ieps = 2; /* conservative */ 855 ilim0 = ilim;
872 if (k > 0) { 856 ieps = 2; /* conservative */
873 ds = tens[k & 0xf]; 857 if (k > 0) {
874 j = k >> 4; 858 ds = tens[k & 0xf];
875 if (j & Bletch) { 859 j = k >> 4;
876 /* prevent overflows */ 860 if (j & Bletch) {
877 j &= Bletch - 1; 861 /* prevent overflows */
878 dval(&u) /= bigtens[n_bigtens - 1]; 862 j &= Bletch - 1;
879 ieps++; 863 dval(&u) /= bigtens[n_bigtens - 1];
880 } 864 ieps++;
881 for (; j; j >>= 1, i++) { 865 }
882 if (j & 1) { 866 for (; j; j >>= 1, i++) {
883 ieps++; 867 if (j & 1) {
884 ds *= bigtens[i]; 868 ieps++;
885 } 869 ds *= bigtens[i];
886 }
887 dval(&u) /= ds;
888 } else if ((j1 = -k)) {
889 dval(&u) *= tens[j1 & 0xf];
890 for (j = j1 >> 4; j; j >>= 1, i++) {
891 if (j & 1) {
892 ieps++;
893 dval(&u) *= bigtens[i];
894 }
895 }
896 } 870 }
897 if (k_check && dval(&u) < 1. && ilim > 0) { 871 }
898 if (ilim1 <= 0) 872 dval(&u) /= ds;
899 goto fastFailed; 873 } else if ((j1 = -k)) {
900 ilim = ilim1; 874 dval(&u) *= tens[j1 & 0xf];
901 k--; 875 for (j = j1 >> 4; j; j >>= 1, i++) {
902 dval(&u) *= 10.; 876 if (j & 1) {
903 ieps++; 877 ieps++;
878 dval(&u) *= bigtens[i];
904 } 879 }
905 dval(&eps) = (ieps * dval(&u)) + 7.; 880 }
906 word0(&eps) -= (P - 1) * Exp_msk1; 881 }
907 if (!ilim) { 882 if (k_check && dval(&u) < 1. && ilim > 0) {
908 S.clear(); 883 if (ilim1 <= 0)
909 mhi.clear(); 884 goto fastFailed;
910 dval(&u) -= 5.; 885 ilim = ilim1;
911 if (dval(&u) > dval(&eps)) 886 k--;
912 goto oneDigit; 887 dval(&u) *= 10.;
913 if (dval(&u) < -dval(&eps)) 888 ieps++;
914 goto noDigits; 889 }
915 goto fastFailed; 890 dval(&eps) = (ieps * dval(&u)) + 7.;
916 } 891 word0(&eps) -= (P - 1) * Exp_msk1;
917 if (leftright) { 892 if (!ilim) {
918 /* Use Steele & White method of only 893 S.clear();
894 mhi.clear();
895 dval(&u) -= 5.;
896 if (dval(&u) > dval(&eps))
897 goto oneDigit;
898 if (dval(&u) < -dval(&eps))
899 goto noDigits;
900 goto fastFailed;
901 }
902 if (leftright) {
903 /* Use Steele & White method of only
919 * generating digits needed. 904 * generating digits needed.
920 */ 905 */
921 dval(&eps) = (0.5 / tens[ilim - 1]) - dval(&eps); 906 dval(&eps) = (0.5 / tens[ilim - 1]) - dval(&eps);
922 for (i = 0;;) { 907 for (i = 0;;) {
923 L = (long int)dval(&u); 908 L = (long int)dval(&u);
924 dval(&u) -= L; 909 dval(&u) -= L;
925 *s++ = '0' + (int)L; 910 *s++ = '0' + (int)L;
926 if (dval(&u) < dval(&eps)) 911 if (dval(&u) < dval(&eps))
927 goto ret; 912 goto ret;
928 if (1. - dval(&u) < dval(&eps)) 913 if (1. - dval(&u) < dval(&eps))
929 goto bumpUp; 914 goto bumpUp;
930 if (++i >= ilim) 915 if (++i >= ilim)
931 break; 916 break;
932 dval(&eps) *= 10.; 917 dval(&eps) *= 10.;
933 dval(&u) *= 10.; 918 dval(&u) *= 10.;
919 }
920 } else {
921 /* Generate ilim digits, then fix them up. */
922 dval(&eps) *= tens[ilim - 1];
923 for (i = 1;; i++, dval(&u) *= 10.) {
924 L = (int32_t)(dval(&u));
925 if (!(dval(&u) -= L))
926 ilim = i;
927 *s++ = '0' + (int)L;
928 if (i == ilim) {
929 if (dval(&u) > 0.5 + dval(&eps))
930 goto bumpUp;
931 if (dval(&u) < 0.5 - dval(&eps)) {
932 while (*--s == '0') {
934 } 933 }
935 } else { 934 s++;
936 /* Generate ilim digits, then fix them up. */ 935 goto ret;
937 dval(&eps) *= tens[ilim - 1]; 936 }
938 for (i = 1;; i++, dval(&u) *= 10.) { 937 break;
939 L = (int32_t)(dval(&u)); 938 }
940 if (!(dval(&u) -= L)) 939 }
941 ilim = i; 940 }
942 *s++ = '0' + (int)L; 941 fastFailed:
943 if (i == ilim) { 942 s = s0;
944 if (dval(&u) > 0.5 + dval(&eps)) 943 dval(&u) = dval(&d2);
945 goto bumpUp; 944 k = k0;
946 if (dval(&u) < 0.5 - dval(&eps)) { 945 ilim = ilim0;
947 while (*--s == '0') { } 946 }
948 s++; 947
949 goto ret; 948 /* Do we have a "small" integer? */
950 } 949
951 break; 950 if (be >= 0 && k <= Int_max) {
952 } 951 /* Yes. */
952 ds = tens[k];
953 if (ndigits < 0 && ilim <= 0) {
954 S.clear();
955 mhi.clear();
956 if (ilim < 0 || dval(&u) <= 5 * ds)
957 goto noDigits;
958 goto oneDigit;
959 }
960 for (i = 1;; i++, dval(&u) *= 10.) {
961 L = (int32_t)(dval(&u) / ds);
962 dval(&u) -= L * ds;
963 *s++ = '0' + (int)L;
964 if (!dval(&u)) {
965 break;
966 }
967 if (i == ilim) {
968 dval(&u) += dval(&u);
969 if (dval(&u) > ds || (dval(&u) == ds && (L & 1))) {
970 bumpUp:
971 while (*--s == '9')
972 if (s == s0) {
973 k++;
974 *s = '0';
975 break;
953 } 976 }
977 ++*s++;
954 } 978 }
955 fastFailed: 979 break;
956 s = s0; 980 }
957 dval(&u) = dval(&d2); 981 }
958 k = k0; 982 goto ret;
959 ilim = ilim0; 983 }
960 } 984
961 985 m2 = b2;
962 /* Do we have a "small" integer? */ 986 m5 = b5;
963 987 mhi.clear();
964 if (be >= 0 && k <= Int_max) { 988 mlo.clear();
965 /* Yes. */ 989 if (leftright) {
966 ds = tens[k]; 990 i = denorm ? be + (Bias + (P - 1) - 1 + 1) : 1 + P - bbits;
967 if (ndigits < 0 && ilim <= 0) { 991 b2 += i;
968 S.clear(); 992 s2 += i;
969 mhi.clear(); 993 i2b(mhi, 1);
970 if (ilim < 0 || dval(&u) <= 5 * ds) 994 }
971 goto noDigits; 995 if (m2 > 0 && s2 > 0) {
972 goto oneDigit; 996 i = m2 < s2 ? m2 : s2;
973 } 997 b2 -= i;
974 for (i = 1;; i++, dval(&u) *= 10.) { 998 m2 -= i;
975 L = (int32_t)(dval(&u) / ds); 999 s2 -= i;
976 dval(&u) -= L * ds; 1000 }
977 *s++ = '0' + (int)L; 1001 if (b5 > 0) {
978 if (!dval(&u)) {
979 break;
980 }
981 if (i == ilim) {
982 dval(&u) += dval(&u);
983 if (dval(&u) > ds || (dval(&u) == ds && (L & 1))) {
984 bumpUp:
985 while (*--s == '9')
986 if (s == s0) {
987 k++;
988 *s = '0';
989 break;
990 }
991 ++*s++;
992 }
993 break;
994 }
995 }
996 goto ret;
997 }
998
999 m2 = b2;
1000 m5 = b5;
1001 mhi.clear();
1002 mlo.clear();
1003 if (leftright) { 1002 if (leftright) {
1004 i = denorm ? be + (Bias + (P - 1) - 1 + 1) : 1 + P - bbits; 1003 if (m5 > 0) {
1005 b2 += i; 1004 pow5mult(mhi, m5);
1006 s2 += i; 1005 mult(b, mhi);
1007 i2b(mhi, 1); 1006 }
1008 } 1007 if ((j = b5 - m5))
1009 if (m2 > 0 && s2 > 0) { 1008 pow5mult(b, j);
1010 i = m2 < s2 ? m2 : s2; 1009 } else
1011 b2 -= i; 1010 pow5mult(b, b5);
1012 m2 -= i; 1011 }
1013 s2 -= i; 1012 i2b(S, 1);
1014 } 1013 if (s5 > 0)
1015 if (b5 > 0) { 1014 pow5mult(S, s5);
1016 if (leftright) { 1015
1017 if (m5 > 0) { 1016 /* Check for special case that d is a normalized power of 2. */
1018 pow5mult(mhi, m5); 1017
1019 mult(b, mhi); 1018 spec_case = 0;
1020 } 1019 if ((roundingNone || leftright) && (!word1(&u) && !(word0(&u) & Bndry_mask) &&
1021 if ((j = b5 - m5)) 1020 word0(&u) & (Exp_mask & ~Exp_msk1))) {
1022 pow5mult(b, j); 1021 /* The special case */
1023 } else 1022 b2 += Log2P;
1024 pow5mult(b, b5); 1023 s2 += Log2P;
1025 } 1024 spec_case = 1;
1026 i2b(S, 1); 1025 }
1027 if (s5 > 0) 1026
1028 pow5mult(S, s5); 1027 /* Arrange for convenient computation of quotients:
1029
1030 /* Check for special case that d is a normalized power of 2. */
1031
1032 spec_case = 0;
1033 if ((roundingNone || leftright) && (!word1(&u) && !(word0(&u) & Bndry_mask) && word0(&u) & (Exp_mask & ~Exp_msk1))) {
1034 /* The special case */
1035 b2 += Log2P;
1036 s2 += Log2P;
1037 spec_case = 1;
1038 }
1039
1040 /* Arrange for convenient computation of quotients:
1041 * shift left if necessary so divisor has 4 leading 0 bits. 1028 * shift left if necessary so divisor has 4 leading 0 bits.
1042 * 1029 *
1043 * Perhaps we should just compute leading 28 bits of S once 1030 * Perhaps we should just compute leading 28 bits of S once
1044 * and for all and pass them and a shift to quorem, so it 1031 * and for all and pass them and a shift to quorem, so it
1045 * can do shifts and ors to compute the numerator for q. 1032 * can do shifts and ors to compute the numerator for q.
1046 */ 1033 */
1047 if ((i = ((s5 ? 32 - hi0bits(S.words()[S.size() - 1]) : 1) + s2) & 0x1f)) 1034 if ((i = ((s5 ? 32 - hi0bits(S.words()[S.size() - 1]) : 1) + s2) & 0x1f))
1048 i = 32 - i; 1035 i = 32 - i;
1049 if (i > 4) { 1036 if (i > 4) {
1050 i -= 4; 1037 i -= 4;
1051 b2 += i; 1038 b2 += i;
1052 m2 += i; 1039 m2 += i;
1053 s2 += i; 1040 s2 += i;
1054 } else if (i < 4) { 1041 } else if (i < 4) {
1055 i += 28; 1042 i += 28;
1056 b2 += i; 1043 b2 += i;
1057 m2 += i; 1044 m2 += i;
1058 s2 += i; 1045 s2 += i;
1059 } 1046 }
1060 if (b2 > 0) 1047 if (b2 > 0)
1061 lshift(b, b2); 1048 lshift(b, b2);
1062 if (s2 > 0) 1049 if (s2 > 0)
1063 lshift(S, s2); 1050 lshift(S, s2);
1064 if (k_check) { 1051 if (k_check) {
1065 if (cmp(b, S) < 0) { 1052 if (cmp(b, S) < 0) {
1066 k--; 1053 k--;
1067 multadd(b, 10, 0); /* we botched the k estimate */ 1054 multadd(b, 10, 0); /* we botched the k estimate */
1068 if (leftright) 1055 if (leftright)
1069 multadd(mhi, 10, 0); 1056 multadd(mhi, 10, 0);
1070 ilim = ilim1; 1057 ilim = ilim1;
1071 } 1058 }
1072 } 1059 }
1073 if (ilim <= 0 && roundingDecimalPlaces) { 1060 if (ilim <= 0 && roundingDecimalPlaces) {
1074 if (ilim < 0) 1061 if (ilim < 0)
1075 goto noDigits; 1062 goto noDigits;
1076 multadd(S, 5, 0); 1063 multadd(S, 5, 0);
1077 // For IEEE-754 unbiased rounding this check should be <=, such that 0.5 would flush to zero. 1064 // For IEEE-754 unbiased rounding this check should be <=, such that 0.5 wou ld flush to zero.
1078 if (cmp(b, S) < 0) 1065 if (cmp(b, S) < 0)
1079 goto noDigits; 1066 goto noDigits;
1080 goto oneDigit; 1067 goto oneDigit;
1081 } 1068 }
1082 if (leftright) { 1069 if (leftright) {
1083 if (m2 > 0) 1070 if (m2 > 0)
1084 lshift(mhi, m2); 1071 lshift(mhi, m2);
1085 1072
1086 /* Compute mlo -- check for special case 1073 /* Compute mlo -- check for special case
1087 * that d is a normalized power of 2. 1074 * that d is a normalized power of 2.
1088 */ 1075 */
1089 1076
1090 mlo = mhi; 1077 mlo = mhi;
1091 if (spec_case) 1078 if (spec_case)
1092 lshift(mhi, Log2P); 1079 lshift(mhi, Log2P);
1093 1080
1094 for (i = 1;;i++) { 1081 for (i = 1;; i++) {
1095 dig = quorem(b, S) + '0'; 1082 dig = quorem(b, S) + '0';
1096 /* Do we yet have the shortest decimal string 1083 /* Do we yet have the shortest decimal string
1097 * that will round to d? 1084 * that will round to d?
1098 */ 1085 */
1099 j = cmp(b, mlo); 1086 j = cmp(b, mlo);
1100 diff(delta, S, mhi); 1087 diff(delta, S, mhi);
1101 j1 = delta.sign ? 1 : cmp(b, delta); 1088 j1 = delta.sign ? 1 : cmp(b, delta);
1102 #ifdef DTOA_ROUND_BIASED 1089 #ifdef DTOA_ROUND_BIASED
1103 if (j < 0 || !j) { 1090 if (j < 0 || !j) {
1104 #else 1091 #else
1105 // FIXME: ECMA-262 specifies that equidistant results round away fro m 1092 // FIXME: ECMA-262 specifies that equidistant results round away from
1106 // zero, which probably means we shouldn't be on the unbiased code p ath 1093 // zero, which probably means we shouldn't be on the unbiased code path
1107 // (the (word1(&u) & 1) clause is looking highly suspicious). I have n't 1094 // (the (word1(&u) & 1) clause is looking highly suspicious). I haven't
1108 // yet understood this code well enough to make the call, but we sho uld 1095 // yet understood this code well enough to make the call, but we should
1109 // probably be enabling DTOA_ROUND_BIASED. I think the interesting c orner 1096 // probably be enabling DTOA_ROUND_BIASED. I think the interesting corner
1110 // case to understand is probably "Math.pow(0.5, 24).toString()". 1097 // case to understand is probably "Math.pow(0.5, 24).toString()".
1111 // I believe this value is interesting because I think it is precise ly 1098 // I believe this value is interesting because I think it is precisely
1112 // representable in binary floating point, and its decimal represent ation 1099 // representable in binary floating point, and its decimal representation
1113 // has a single digit that Steele & White reduction can remove, with the 1100 // has a single digit that Steele & White reduction can remove, with the
1114 // value 5 (thus equidistant from the next numbers above and below). 1101 // value 5 (thus equidistant from the next numbers above and below).
1115 // We produce the correct answer using either codepath, and I don't as 1102 // We produce the correct answer using either codepath, and I don't as
1116 // yet understand why. :-) 1103 // yet understand why. :-)
1117 if (!j1 && !(word1(&u) & 1)) { 1104 if (!j1 && !(word1(&u) & 1)) {
1118 if (dig == '9') 1105 if (dig == '9')
1119 goto round9up; 1106 goto round9up;
1120 if (j > 0) 1107 if (j > 0)
1121 dig++; 1108 dig++;
1122 *s++ = dig; 1109 *s++ = dig;
1123 goto ret; 1110 goto ret;
1124 } 1111 }
1125 if (j < 0 || (!j && !(word1(&u) & 1))) { 1112 if (j < 0 || (!j && !(word1(&u) & 1))) {
1126 #endif 1113 #endif
1127 if ((b.words()[0] || b.size() > 1) && (j1 > 0)) { 1114 if ((b.words()[0] || b.size() > 1) && (j1 > 0)) {
1128 lshift(b, 1); 1115 lshift(b, 1);
1129 j1 = cmp(b, S); 1116 j1 = cmp(b, S);
1130 // For IEEE-754 round-to-even, this check should be (j1 > 0 || (!j1 && (dig & 1))), 1117 // For IEEE-754 round-to-even, this check should be (j1 > 0 || (!j1 && (dig & 1))),
1131 // but ECMA-262 specifies that equidistant values (e.g. (.5) .toFixed()) should 1118 // but ECMA-262 specifies that equidistant values (e.g. (.5).toFixed() ) should
1132 // be rounded away from zero. 1119 // be rounded away from zero.
1133 if (j1 >= 0) { 1120 if (j1 >= 0) {
1134 if (dig == '9') 1121 if (dig == '9')
1135 goto round9up; 1122 goto round9up;
1136 dig++; 1123 dig++;
1137 } 1124 }
1138 }
1139 *s++ = dig;
1140 goto ret;
1141 }
1142 if (j1 > 0) {
1143 if (dig == '9') { /* possible if i == 1 */
1144 round9up:
1145 *s++ = '9';
1146 goto roundoff;
1147 }
1148 *s++ = dig + 1;
1149 goto ret;
1150 }
1151 *s++ = dig;
1152 if (i == ilim)
1153 break;
1154 multadd(b, 10, 0);
1155 multadd(mlo, 10, 0);
1156 multadd(mhi, 10, 0);
1157 } 1125 }
1158 } else { 1126 *s++ = dig;
1159 for (i = 1;; i++) { 1127 goto ret;
1160 *s++ = dig = quorem(b, S) + '0'; 1128 }
1161 if (!b.words()[0] && b.size() <= 1) 1129 if (j1 > 0) {
1162 goto ret; 1130 if (dig == '9') { /* possible if i == 1 */
1163 if (i >= ilim) 1131 round9up:
1164 break; 1132 *s++ = '9';
1165 multadd(b, 10, 0); 1133 goto roundoff;
1166 } 1134 }
1167 } 1135 *s++ = dig + 1;
1168 1136 goto ret;
1169 /* Round off last digit */ 1137 }
1170 1138 *s++ = dig;
1171 lshift(b, 1); 1139 if (i == ilim)
1172 j = cmp(b, S); 1140 break;
1173 // For IEEE-754 round-to-even, this check should be (j > 0 || (!j && (dig & 1))), 1141 multadd(b, 10, 0);
1174 // but ECMA-262 specifies that equidistant values (e.g. (.5).toFixed()) shou ld 1142 multadd(mlo, 10, 0);
1175 // be rounded away from zero. 1143 multadd(mhi, 10, 0);
1176 if (j >= 0) { 1144 }
1177 roundoff: 1145 } else {
1178 while (*--s == '9') 1146 for (i = 1;; i++) {
1179 if (s == s0) { 1147 *s++ = dig = quorem(b, S) + '0';
1180 k++; 1148 if (!b.words()[0] && b.size() <= 1)
1181 *s++ = '1'; 1149 goto ret;
1182 goto ret; 1150 if (i >= ilim)
1183 } 1151 break;
1184 ++*s++; 1152 multadd(b, 10, 0);
1185 } else { 1153 }
1186 while (*--s == '0') { } 1154 }
1187 s++; 1155
1188 } 1156 /* Round off last digit */
1189 goto ret; 1157
1158 lshift(b, 1);
1159 j = cmp(b, S);
1160 // For IEEE-754 round-to-even, this check should be (j > 0 || (!j && (dig & 1) )),
1161 // but ECMA-262 specifies that equidistant values (e.g. (.5).toFixed()) should
1162 // be rounded away from zero.
1163 if (j >= 0) {
1164 roundoff:
1165 while (*--s == '9')
1166 if (s == s0) {
1167 k++;
1168 *s++ = '1';
1169 goto ret;
1170 }
1171 ++*s++;
1172 } else {
1173 while (*--s == '0') {
1174 }
1175 s++;
1176 }
1177 goto ret;
1190 noDigits: 1178 noDigits:
1191 exponentOut = 0; 1179 exponentOut = 0;
1192 precisionOut = 1; 1180 precisionOut = 1;
1193 result[0] = '0'; 1181 result[0] = '0';
1194 result[1] = '\0'; 1182 result[1] = '\0';
1195 return; 1183 return;
1196 oneDigit: 1184 oneDigit:
1197 *s++ = '1'; 1185 *s++ = '1';
1198 k++; 1186 k++;
1199 goto ret; 1187 goto ret;
1200 ret: 1188 ret:
1201 ASSERT(s > result); 1189 ASSERT(s > result);
1202 *s = 0; 1190 *s = 0;
1203 exponentOut = k; 1191 exponentOut = k;
1204 precisionOut = s - result; 1192 precisionOut = s - result;
1205 } 1193 }
1206 1194
1207 void dtoa(DtoaBuffer result, double dd, bool& sign, int& exponent, unsigned& pre cision) 1195 void dtoa(DtoaBuffer result,
1208 { 1196 double dd,
1209 // flags are roundingNone, leftright. 1197 bool& sign,
1210 dtoa<true, false, false, true>(result, dd, 0, sign, exponent, precision); 1198 int& exponent,
1211 } 1199 unsigned& precision) {
1212 1200 // flags are roundingNone, leftright.
1213 void dtoaRoundSF(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exp onent, unsigned& precision) 1201 dtoa<true, false, false, true>(result, dd, 0, sign, exponent, precision);
1214 { 1202 }
1215 // flag is roundingSignificantFigures. 1203
1216 dtoa<false, true, false, false>(result, dd, ndigits, sign, exponent, precisi on); 1204 void dtoaRoundSF(DtoaBuffer result,
1217 } 1205 double dd,
1218 1206 int ndigits,
1219 void dtoaRoundDP(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exp onent, unsigned& precision) 1207 bool& sign,
1220 { 1208 int& exponent,
1221 // flag is roundingDecimalPlaces. 1209 unsigned& precision) {
1222 dtoa<false, false, true, false>(result, dd, ndigits, sign, exponent, precisi on); 1210 // flag is roundingSignificantFigures.
1223 } 1211 dtoa<false, true, false, false>(result, dd, ndigits, sign, exponent,
1224 1212 precision);
1225 const char* numberToString(double d, NumberToStringBuffer buffer) 1213 }
1226 { 1214
1227 double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength) ; 1215 void dtoaRoundDP(DtoaBuffer result,
1228 const double_conversion::DoubleToStringConverter& converter = double_convers ion::DoubleToStringConverter::EcmaScriptConverter(); 1216 double dd,
1229 converter.ToShortest(d, &builder); 1217 int ndigits,
1218 bool& sign,
1219 int& exponent,
1220 unsigned& precision) {
1221 // flag is roundingDecimalPlaces.
1222 dtoa<false, false, true, false>(result, dd, ndigits, sign, exponent,
1223 precision);
1224 }
1225
1226 const char* numberToString(double d, NumberToStringBuffer buffer) {
1227 double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength);
1228 const double_conversion::DoubleToStringConverter& converter =
1229 double_conversion::DoubleToStringConverter::EcmaScriptConverter();
1230 converter.ToShortest(d, &builder);
1231 return builder.Finalize();
1232 }
1233
1234 static inline const char* formatStringTruncatingTrailingZerosIfNeeded(
1235 NumberToStringBuffer buffer,
1236 double_conversion::StringBuilder& builder) {
1237 size_t length = builder.position();
1238
1239 // If there is an exponent, stripping trailing zeros would be incorrect.
1240 // FIXME: Zeros should be stripped before the 'e'.
1241 if (memchr(buffer, 'e', length))
1230 return builder.Finalize(); 1242 return builder.Finalize();
1231 } 1243
1232 1244 size_t decimalPointPosition = 0;
1233 static inline const char* formatStringTruncatingTrailingZerosIfNeeded(NumberToSt ringBuffer buffer, double_conversion::StringBuilder& builder) 1245 for (; decimalPointPosition < length; ++decimalPointPosition) {
1234 { 1246 if (buffer[decimalPointPosition] == '.')
1235 size_t length = builder.position(); 1247 break;
1236 1248 }
1237 // If there is an exponent, stripping trailing zeros would be incorrect. 1249
1238 // FIXME: Zeros should be stripped before the 'e'. 1250 // No decimal seperator found, early exit.
1239 if (memchr(buffer, 'e', length)) 1251 if (decimalPointPosition == length)
1240 return builder.Finalize();
1241
1242 size_t decimalPointPosition = 0;
1243 for (; decimalPointPosition < length; ++decimalPointPosition) {
1244 if (buffer[decimalPointPosition] == '.')
1245 break;
1246 }
1247
1248 // No decimal seperator found, early exit.
1249 if (decimalPointPosition == length)
1250 return builder.Finalize();
1251
1252 size_t truncatedLength = length - 1;
1253 for (; truncatedLength > decimalPointPosition; --truncatedLength) {
1254 if (buffer[truncatedLength] != '0')
1255 break;
1256 }
1257
1258 // No trailing zeros found to strip.
1259 if (truncatedLength == length - 1)
1260 return builder.Finalize();
1261
1262 // If we removed all trailing zeros, remove the decimal point as well.
1263 if (truncatedLength == decimalPointPosition) {
1264 ASSERT(truncatedLength > 0);
1265 --truncatedLength;
1266 }
1267
1268 // Truncate the StringBuilder, and return the final result.
1269 builder.SetPosition(truncatedLength + 1);
1270 return builder.Finalize(); 1252 return builder.Finalize();
1271 } 1253
1272 1254 size_t truncatedLength = length - 1;
1273 const char* numberToFixedPrecisionString(double d, unsigned significantFigures, NumberToStringBuffer buffer, bool truncateTrailingZeros) 1255 for (; truncatedLength > decimalPointPosition; --truncatedLength) {
1274 { 1256 if (buffer[truncatedLength] != '0')
1275 // Mimic String::format("%.[precision]g", ...), but use dtoas rounding facil ities. 1257 break;
1276 // "g": Signed value printed in f or e format, whichever is more compact for the given value and precision. 1258 }
1277 // The e format is used only when the exponent of the value is less than -4 or greater than or equal to the 1259
1278 // precision argument. Trailing zeros are truncated, and the decimal point a ppears only if one or more digits follow it. 1260 // No trailing zeros found to strip.
1279 // "precision": The precision specifies the maximum number of significant di gits printed. 1261 if (truncatedLength == length - 1)
1280 double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength) ;
1281 const double_conversion::DoubleToStringConverter& converter = double_convers ion::DoubleToStringConverter::EcmaScriptConverter();
1282 converter.ToPrecision(d, significantFigures, &builder);
1283 if (!truncateTrailingZeros)
1284 return builder.Finalize();
1285 // FIXME: Trailing zeros should never be added in the first place. The
1286 // current implementation does not strip when there is an exponent, eg.
1287 // 1.50000e+10.
1288 return formatStringTruncatingTrailingZerosIfNeeded(buffer, builder);
1289 }
1290
1291 const char* numberToFixedWidthString(double d, unsigned decimalPlaces, NumberToS tringBuffer buffer)
1292 {
1293 // Mimic String::format("%.[precision]f", ...), but use dtoas rounding facil ities.
1294 // "f": Signed value having the form [ - ]dddd.dddd, where dddd is one or mo re decimal digits.
1295 // The number of digits before the decimal point depends on the magnitude of the number, and
1296 // the number of digits after the decimal point depends on the requested pre cision.
1297 // "precision": The precision value specifies the number of digits after the decimal point.
1298 // If a decimal point appears, at least one digit appears before it.
1299 // The value is rounded to the appropriate number of digits.
1300 double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength) ;
1301 const double_conversion::DoubleToStringConverter& converter = double_convers ion::DoubleToStringConverter::EcmaScriptConverter();
1302 converter.ToFixed(d, decimalPlaces, &builder);
1303 return builder.Finalize(); 1262 return builder.Finalize();
1263
1264 // If we removed all trailing zeros, remove the decimal point as well.
1265 if (truncatedLength == decimalPointPosition) {
1266 ASSERT(truncatedLength > 0);
1267 --truncatedLength;
1268 }
1269
1270 // Truncate the StringBuilder, and return the final result.
1271 builder.SetPosition(truncatedLength + 1);
1272 return builder.Finalize();
1273 }
1274
1275 const char* numberToFixedPrecisionString(double d,
1276 unsigned significantFigures,
1277 NumberToStringBuffer buffer,
1278 bool truncateTrailingZeros) {
1279 // Mimic String::format("%.[precision]g", ...), but use dtoas rounding facilit ies.
1280 // "g": Signed value printed in f or e format, whichever is more compact for t he given value and precision.
1281 // The e format is used only when the exponent of the value is less than -4 or greater than or equal to the
1282 // precision argument. Trailing zeros are truncated, and the decimal point app ears only if one or more digits follow it.
1283 // "precision": The precision specifies the maximum number of significant digi ts printed.
1284 double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength);
1285 const double_conversion::DoubleToStringConverter& converter =
1286 double_conversion::DoubleToStringConverter::EcmaScriptConverter();
1287 converter.ToPrecision(d, significantFigures, &builder);
1288 if (!truncateTrailingZeros)
1289 return builder.Finalize();
1290 // FIXME: Trailing zeros should never be added in the first place. The
1291 // current implementation does not strip when there is an exponent, eg.
1292 // 1.50000e+10.
1293 return formatStringTruncatingTrailingZerosIfNeeded(buffer, builder);
1294 }
1295
1296 const char* numberToFixedWidthString(double d,
1297 unsigned decimalPlaces,
1298 NumberToStringBuffer buffer) {
1299 // Mimic String::format("%.[precision]f", ...), but use dtoas rounding facilit ies.
1300 // "f": Signed value having the form [ - ]dddd.dddd, where dddd is one or more decimal digits.
1301 // The number of digits before the decimal point depends on the magnitude of t he number, and
1302 // the number of digits after the decimal point depends on the requested preci sion.
1303 // "precision": The precision value specifies the number of digits after the d ecimal point.
1304 // If a decimal point appears, at least one digit appears before it.
1305 // The value is rounded to the appropriate number of digits.
1306 double_conversion::StringBuilder builder(buffer, NumberToStringBufferLength);
1307 const double_conversion::DoubleToStringConverter& converter =
1308 double_conversion::DoubleToStringConverter::EcmaScriptConverter();
1309 converter.ToFixed(d, decimalPlaces, &builder);
1310 return builder.Finalize();
1304 } 1311 }
1305 1312
1306 namespace Internal { 1313 namespace Internal {
1307 1314
1308 double parseDoubleFromLongString(const UChar* string, size_t length, size_t& par sedLength) 1315 double parseDoubleFromLongString(const UChar* string,
1309 { 1316 size_t length,
1310 Vector<LChar> conversionBuffer(length); 1317 size_t& parsedLength) {
1311 for (size_t i = 0; i < length; ++i) 1318 Vector<LChar> conversionBuffer(length);
1312 conversionBuffer[i] = isASCII(string[i]) ? string[i] : 0; 1319 for (size_t i = 0; i < length; ++i)
1313 return parseDouble(conversionBuffer.data(), length, parsedLength); 1320 conversionBuffer[i] = isASCII(string[i]) ? string[i] : 0;
1314 } 1321 return parseDouble(conversionBuffer.data(), length, parsedLength);
1315 1322 }
1316 } // namespace Internal 1323
1317 1324 } // namespace Internal
1318 } // namespace WTF 1325
1326 } // namespace WTF
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/wtf/dtoa.h ('k') | third_party/WebKit/Source/wtf/dtoa/bignum.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698