~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WTF/wtf/dtoa/double-conversion.cc

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2010 the V8 project authors. All rights reserved.
 
2
// Redistribution and use in source and binary forms, with or without
 
3
// modification, are permitted provided that the following conditions are
 
4
// met:
 
5
//
 
6
//     * Redistributions of source code must retain the above copyright
 
7
//       notice, this list of conditions and the following disclaimer.
 
8
//     * Redistributions in binary form must reproduce the above
 
9
//       copyright notice, this list of conditions and the following
 
10
//       disclaimer in the documentation and/or other materials provided
 
11
//       with the distribution.
 
12
//     * Neither the name of Google Inc. nor the names of its
 
13
//       contributors may be used to endorse or promote products derived
 
14
//       from this software without specific prior written permission.
 
15
//
 
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 
 
28
#include "config.h"
 
29
 
 
30
#include <limits.h>
 
31
#include <math.h>
 
32
 
 
33
#include "double-conversion.h"
 
34
 
 
35
#include "bignum-dtoa.h"
 
36
#include "double.h"
 
37
#include "fast-dtoa.h"
 
38
#include "fixed-dtoa.h"
 
39
#include "strtod.h"
 
40
#include "utils.h"
 
41
 
 
42
namespace WTF {
 
43
 
 
44
namespace double_conversion {
 
45
    
 
46
    const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
 
47
        int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
 
48
        static DoubleToStringConverter converter(flags,
 
49
                                                 "Infinity",
 
50
                                                 "NaN",
 
51
                                                 'e',
 
52
                                                 -6, 21,
 
53
                                                 6, 0);
 
54
        return converter;
 
55
    }
 
56
    
 
57
    
 
58
    bool DoubleToStringConverter::HandleSpecialValues(
 
59
                                                      double value,
 
60
                                                      StringBuilder* result_builder) const {
 
61
        Double double_inspect(value);
 
62
        if (double_inspect.IsInfinite()) {
 
63
            if (infinity_symbol_ == NULL) return false;
 
64
            if (value < 0) {
 
65
                result_builder->AddCharacter('-');
 
66
            }
 
67
            result_builder->AddString(infinity_symbol_);
 
68
            return true;
 
69
        }
 
70
        if (double_inspect.IsNan()) {
 
71
            if (nan_symbol_ == NULL) return false;
 
72
            result_builder->AddString(nan_symbol_);
 
73
            return true;
 
74
        }
 
75
        return false;
 
76
    }
 
77
    
 
78
    
 
79
    void DoubleToStringConverter::CreateExponentialRepresentation(
 
80
                                                                  const char* decimal_digits,
 
81
                                                                  int length,
 
82
                                                                  int exponent,
 
83
                                                                  StringBuilder* result_builder) const {
 
84
        ASSERT(length != 0);
 
85
        result_builder->AddCharacter(decimal_digits[0]);
 
86
        if (length != 1) {
 
87
            result_builder->AddCharacter('.');
 
88
            result_builder->AddSubstring(&decimal_digits[1], length-1);
 
89
        }
 
90
        result_builder->AddCharacter(exponent_character_);
 
91
        if (exponent < 0) {
 
92
            result_builder->AddCharacter('-');
 
93
            exponent = -exponent;
 
94
        } else {
 
95
            if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
 
96
                result_builder->AddCharacter('+');
 
97
            }
 
98
        }
 
99
        if (exponent == 0) {
 
100
            result_builder->AddCharacter('0');
 
101
            return;
 
102
        }
 
103
        ASSERT(exponent < 1e4);
 
104
        const int kMaxExponentLength = 5;
 
105
        char buffer[kMaxExponentLength + 1];
 
106
        int first_char_pos = kMaxExponentLength;
 
107
        buffer[first_char_pos] = '\0';
 
108
        while (exponent > 0) {
 
109
            buffer[--first_char_pos] = '0' + (exponent % 10);
 
110
            exponent /= 10;
 
111
        }
 
112
        result_builder->AddSubstring(&buffer[first_char_pos],
 
113
                                     kMaxExponentLength - first_char_pos);
 
114
    }
 
115
    
 
116
    
 
117
    void DoubleToStringConverter::CreateDecimalRepresentation(
 
118
                                                              const char* decimal_digits,
 
119
                                                              int length,
 
120
                                                              int decimal_point,
 
121
                                                              int digits_after_point,
 
122
                                                              StringBuilder* result_builder) const {
 
123
        // Create a representation that is padded with zeros if needed.
 
124
        if (decimal_point <= 0) {
 
125
            // "0.00000decimal_rep".
 
126
            result_builder->AddCharacter('0');
 
127
            if (digits_after_point > 0) {
 
128
                result_builder->AddCharacter('.');
 
129
                result_builder->AddPadding('0', -decimal_point);
 
130
                ASSERT(length <= digits_after_point - (-decimal_point));
 
131
                result_builder->AddSubstring(decimal_digits, length);
 
132
                int remaining_digits = digits_after_point - (-decimal_point) - length;
 
133
                result_builder->AddPadding('0', remaining_digits);
 
134
            }
 
135
        } else if (decimal_point >= length) {
 
136
            // "decimal_rep0000.00000" or "decimal_rep.0000"
 
137
            result_builder->AddSubstring(decimal_digits, length);
 
138
            result_builder->AddPadding('0', decimal_point - length);
 
139
            if (digits_after_point > 0) {
 
140
                result_builder->AddCharacter('.');
 
141
                result_builder->AddPadding('0', digits_after_point);
 
142
            }
 
143
        } else {
 
144
            // "decima.l_rep000"
 
145
            ASSERT(digits_after_point > 0);
 
146
            result_builder->AddSubstring(decimal_digits, decimal_point);
 
147
            result_builder->AddCharacter('.');
 
148
            ASSERT(length - decimal_point <= digits_after_point);
 
149
            result_builder->AddSubstring(&decimal_digits[decimal_point],
 
150
                                         length - decimal_point);
 
151
            int remaining_digits = digits_after_point - (length - decimal_point);
 
152
            result_builder->AddPadding('0', remaining_digits);
 
153
        }
 
154
        if (digits_after_point == 0) {
 
155
            if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
 
156
                result_builder->AddCharacter('.');
 
157
            }
 
158
            if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
 
159
                result_builder->AddCharacter('0');
 
160
            }
 
161
        }
 
162
    }
 
163
    
 
164
    
 
165
    bool DoubleToStringConverter::ToShortest(double value,
 
166
                                             StringBuilder* result_builder) const {
 
167
        if (Double(value).IsSpecial()) {
 
168
            return HandleSpecialValues(value, result_builder);
 
169
        }
 
170
        
 
171
        int decimal_point;
 
172
        bool sign;
 
173
        const int kDecimalRepCapacity = kBase10MaximalLength + 1;
 
174
        char decimal_rep[kDecimalRepCapacity];
 
175
        int decimal_rep_length;
 
176
        
 
177
        DoubleToAscii(value, SHORTEST, 0, decimal_rep, kDecimalRepCapacity,
 
178
                      &sign, &decimal_rep_length, &decimal_point);
 
179
        
 
180
        bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
 
181
        if (sign && (value != 0.0 || !unique_zero)) {
 
182
            result_builder->AddCharacter('-');
 
183
        }
 
184
        
 
185
        int exponent = decimal_point - 1;
 
186
        if ((decimal_in_shortest_low_ <= exponent) &&
 
187
            (exponent < decimal_in_shortest_high_)) {
 
188
            CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
 
189
                                        decimal_point,
 
190
                                        Max(0, decimal_rep_length - decimal_point),
 
191
                                        result_builder);
 
192
        } else {
 
193
            CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
 
194
                                            result_builder);
 
195
        }
 
196
        return true;
 
197
    }
 
198
    
 
199
    
 
200
    bool DoubleToStringConverter::ToFixed(double value,
 
201
                                          int requested_digits,
 
202
                                          StringBuilder* result_builder) const {
 
203
        ASSERT(kMaxFixedDigitsBeforePoint == 60);
 
204
        const double kFirstNonFixed = 1e60;
 
205
        
 
206
        if (Double(value).IsSpecial()) {
 
207
            return HandleSpecialValues(value, result_builder);
 
208
        }
 
209
        
 
210
        if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
 
211
        if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
 
212
        
 
213
        // Find a sufficiently precise decimal representation of n.
 
214
        int decimal_point;
 
215
        bool sign;
 
216
        // Add space for the '\0' byte.
 
217
        const int kDecimalRepCapacity =
 
218
        kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
 
219
        char decimal_rep[kDecimalRepCapacity];
 
220
        int decimal_rep_length;
 
221
        DoubleToAscii(value, FIXED, requested_digits,
 
222
                      decimal_rep, kDecimalRepCapacity,
 
223
                      &sign, &decimal_rep_length, &decimal_point);
 
224
        
 
225
        bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
 
226
        if (sign && (value != 0.0 || !unique_zero)) {
 
227
            result_builder->AddCharacter('-');
 
228
        }
 
229
        
 
230
        CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
 
231
                                    requested_digits, result_builder);
 
232
        return true;
 
233
    }
 
234
    
 
235
    
 
236
    bool DoubleToStringConverter::ToExponential(
 
237
                                                double value,
 
238
                                                int requested_digits,
 
239
                                                StringBuilder* result_builder) const {
 
240
        if (Double(value).IsSpecial()) {
 
241
            return HandleSpecialValues(value, result_builder);
 
242
        }
 
243
        
 
244
        if (requested_digits < -1) return false;
 
245
        if (requested_digits > kMaxExponentialDigits) return false;
 
246
        
 
247
        int decimal_point;
 
248
        bool sign;
 
249
        // Add space for digit before the decimal point and the '\0' character.
 
250
        const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
 
251
        ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
 
252
        char decimal_rep[kDecimalRepCapacity];
 
253
        int decimal_rep_length;
 
254
        
 
255
        if (requested_digits == -1) {
 
256
            DoubleToAscii(value, SHORTEST, 0,
 
257
                          decimal_rep, kDecimalRepCapacity,
 
258
                          &sign, &decimal_rep_length, &decimal_point);
 
259
        } else {
 
260
            DoubleToAscii(value, PRECISION, requested_digits + 1,
 
261
                          decimal_rep, kDecimalRepCapacity,
 
262
                          &sign, &decimal_rep_length, &decimal_point);
 
263
            ASSERT(decimal_rep_length <= requested_digits + 1);
 
264
            
 
265
            for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
 
266
                decimal_rep[i] = '0';
 
267
            }
 
268
            decimal_rep_length = requested_digits + 1;
 
269
        }
 
270
        
 
271
        bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
 
272
        if (sign && (value != 0.0 || !unique_zero)) {
 
273
            result_builder->AddCharacter('-');
 
274
        }
 
275
        
 
276
        int exponent = decimal_point - 1;
 
277
        CreateExponentialRepresentation(decimal_rep,
 
278
                                        decimal_rep_length,
 
279
                                        exponent,
 
280
                                        result_builder);
 
281
        return true;
 
282
    }
 
283
    
 
284
    
 
285
    bool DoubleToStringConverter::ToPrecision(double value,
 
286
                                              int precision,
 
287
                                              StringBuilder* result_builder) const {
 
288
        if (Double(value).IsSpecial()) {
 
289
            return HandleSpecialValues(value, result_builder);
 
290
        }
 
291
        
 
292
        if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
 
293
            return false;
 
294
        }
 
295
        
 
296
        // Find a sufficiently precise decimal representation of n.
 
297
        int decimal_point;
 
298
        bool sign;
 
299
        // Add one for the terminating null character.
 
300
        const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
 
301
        char decimal_rep[kDecimalRepCapacity];
 
302
        int decimal_rep_length;
 
303
        
 
304
        DoubleToAscii(value, PRECISION, precision,
 
305
                      decimal_rep, kDecimalRepCapacity,
 
306
                      &sign, &decimal_rep_length, &decimal_point);
 
307
        ASSERT(decimal_rep_length <= precision);
 
308
        
 
309
        bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
 
310
        if (sign && (value != 0.0 || !unique_zero)) {
 
311
            result_builder->AddCharacter('-');
 
312
        }
 
313
        
 
314
        // The exponent if we print the number as x.xxeyyy. That is with the
 
315
        // decimal point after the first digit.
 
316
        int exponent = decimal_point - 1;
 
317
        
 
318
        int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
 
319
        if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
 
320
            (decimal_point - precision + extra_zero >
 
321
             max_trailing_padding_zeroes_in_precision_mode_)) {
 
322
                // Fill buffer to contain 'precision' digits.
 
323
                // Usually the buffer is already at the correct length, but 'DoubleToAscii'
 
324
                // is allowed to return less characters.
 
325
                for (int i = decimal_rep_length; i < precision; ++i) {
 
326
                    decimal_rep[i] = '0';
 
327
                }
 
328
                
 
329
                CreateExponentialRepresentation(decimal_rep,
 
330
                                                precision,
 
331
                                                exponent,
 
332
                                                result_builder);
 
333
            } else {
 
334
                CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
 
335
                                            Max(0, precision - decimal_point),
 
336
                                            result_builder);
 
337
            }
 
338
        return true;
 
339
    }
 
340
    
 
341
    
 
342
    static BignumDtoaMode DtoaToBignumDtoaMode(
 
343
                                               DoubleToStringConverter::DtoaMode dtoa_mode) {
 
344
        switch (dtoa_mode) {
 
345
            case DoubleToStringConverter::SHORTEST:  return BIGNUM_DTOA_SHORTEST;
 
346
            case DoubleToStringConverter::FIXED:     return BIGNUM_DTOA_FIXED;
 
347
            case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
 
348
            default:
 
349
                UNREACHABLE();
 
350
                return BIGNUM_DTOA_SHORTEST;  // To silence compiler.
 
351
        }
 
352
    }
 
353
    
 
354
    
 
355
    void DoubleToStringConverter::DoubleToAscii(double v,
 
356
                                                DtoaMode mode,
 
357
                                                int requested_digits,
 
358
                                                char* buffer,
 
359
                                                int buffer_length,
 
360
                                                bool* sign,
 
361
                                                int* length,
 
362
                                                int* point) {
 
363
        Vector<char> vector(buffer, buffer_length);
 
364
        ASSERT(!Double(v).IsSpecial());
 
365
        ASSERT(mode == SHORTEST || requested_digits >= 0);
 
366
        
 
367
        if (Double(v).Sign() < 0) {
 
368
            *sign = true;
 
369
            v = -v;
 
370
        } else {
 
371
            *sign = false;
 
372
        }
 
373
        
 
374
        if (mode == PRECISION && requested_digits == 0) {
 
375
            vector[0] = '\0';
 
376
            *length = 0;
 
377
            return;
 
378
        }
 
379
        
 
380
        if (v == 0) {
 
381
            vector[0] = '0';
 
382
            vector[1] = '\0';
 
383
            *length = 1;
 
384
            *point = 1;
 
385
            return;
 
386
        }
 
387
        
 
388
        bool fast_worked;
 
389
        switch (mode) {
 
390
            case SHORTEST:
 
391
                fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
 
392
                break;
 
393
            case FIXED:
 
394
                fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
 
395
                break;
 
396
            case PRECISION:
 
397
                fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
 
398
                                       vector, length, point);
 
399
                break;
 
400
            default:
 
401
                UNREACHABLE();
 
402
                fast_worked = false;
 
403
        }
 
404
        if (fast_worked) return;
 
405
        
 
406
        // If the fast dtoa didn't succeed use the slower bignum version.
 
407
        BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
 
408
        BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
 
409
        vector[*length] = '\0';
 
410
    }
 
411
    
 
412
    
 
413
    // Maximum number of significant digits in decimal representation.
 
414
    // The longest possible double in decimal representation is
 
415
    // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
 
416
    // (768 digits). If we parse a number whose first digits are equal to a
 
417
    // mean of 2 adjacent doubles (that could have up to 769 digits) the result
 
418
    // must be rounded to the bigger one unless the tail consists of zeros, so
 
419
    // we don't need to preserve all the digits.
 
420
    const int kMaxSignificantDigits = 772;
 
421
    
 
422
    
 
423
    static double SignedZero(bool sign) {
 
424
        return sign ? -0.0 : 0.0;
 
425
    }
 
426
    
 
427
    
 
428
    double StringToDoubleConverter::StringToDouble(
 
429
                                                   const char* input,
 
430
                                                   size_t length,
 
431
                                                   size_t* processed_characters_count) {
 
432
        const char* current = input;
 
433
        const char* end = input + length;
 
434
        
 
435
        *processed_characters_count = 0;
 
436
        
 
437
        // To make sure that iterator dereferencing is valid the following
 
438
        // convention is used:
 
439
        // 1. Each '++current' statement is followed by check for equality to 'end'.
 
440
        // 3. If 'current' becomes equal to 'end' the function returns or goes to
 
441
        // 'parsing_done'.
 
442
        // 4. 'current' is not dereferenced after the 'parsing_done' label.
 
443
        // 5. Code before 'parsing_done' may rely on 'current != end'.
 
444
        if (current == end) return 0.0;
 
445
        
 
446
        // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
 
447
        const int kBufferSize = kMaxSignificantDigits + 10;
 
448
        char buffer[kBufferSize];  // NOLINT: size is known at compile time.
 
449
        int buffer_pos = 0;
 
450
        
 
451
        // Exponent will be adjusted if insignificant digits of the integer part
 
452
        // or insignificant leading zeros of the fractional part are dropped.
 
453
        int exponent = 0;
 
454
        int significant_digits = 0;
 
455
        int insignificant_digits = 0;
 
456
        bool nonzero_digit_dropped = false;
 
457
        bool sign = false;
 
458
        
 
459
        if (*current == '+' || *current == '-') {
 
460
            sign = (*current == '-');
 
461
            ++current;
 
462
            if (current == end) return 0.0;
 
463
        }
 
464
        
 
465
        bool leading_zero = false;
 
466
        if (*current == '0') {
 
467
            ++current;
 
468
            if (current == end) {
 
469
                *processed_characters_count = current - input;
 
470
                return SignedZero(sign);
 
471
            }
 
472
            
 
473
            leading_zero = true;
 
474
            
 
475
            // Ignore leading zeros in the integer part.
 
476
            while (*current == '0') {
 
477
                ++current;
 
478
                if (current == end) {
 
479
                    *processed_characters_count = current - input;
 
480
                    return SignedZero(sign);
 
481
                }
 
482
            }
 
483
        }
 
484
        
 
485
        // Copy significant digits of the integer part (if any) to the buffer.
 
486
        while (*current >= '0' && *current <= '9') {
 
487
            if (significant_digits < kMaxSignificantDigits) {
 
488
                ASSERT(buffer_pos < kBufferSize);
 
489
                buffer[buffer_pos++] = static_cast<char>(*current);
 
490
                significant_digits++;
 
491
            } else {
 
492
                insignificant_digits++;  // Move the digit into the exponential part.
 
493
                nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
 
494
            }
 
495
            ++current;
 
496
            if (current == end) goto parsing_done;
 
497
        }
 
498
        
 
499
        if (*current == '.') {
 
500
            ++current;
 
501
            if (current == end) {
 
502
                if (significant_digits == 0 && !leading_zero) {
 
503
                    return 0.0;
 
504
                } else {
 
505
                    goto parsing_done;
 
506
                }
 
507
            }
 
508
            
 
509
            if (significant_digits == 0) {
 
510
                // Integer part consists of 0 or is absent. Significant digits start after
 
511
                // leading zeros (if any).
 
512
                while (*current == '0') {
 
513
                    ++current;
 
514
                    if (current == end) {
 
515
                        *processed_characters_count = current - input;
 
516
                        return SignedZero(sign);
 
517
                    }
 
518
                    exponent--;  // Move this 0 into the exponent.
 
519
                }
 
520
            }
 
521
 
 
522
            // There is a fractional part.
 
523
            while (*current >= '0' && *current <= '9') {
 
524
                if (significant_digits < kMaxSignificantDigits) {
 
525
                    ASSERT(buffer_pos < kBufferSize);
 
526
                    buffer[buffer_pos++] = static_cast<char>(*current);
 
527
                    significant_digits++;
 
528
                    exponent--;
 
529
                } else {
 
530
                    // Ignore insignificant digits in the fractional part.
 
531
                    nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
 
532
                }
 
533
                ++current;
 
534
                if (current == end) goto parsing_done;
 
535
            }
 
536
        }
 
537
        
 
538
        if (!leading_zero && exponent == 0 && significant_digits == 0) {
 
539
            // If leading_zeros is true then the string contains zeros.
 
540
            // If exponent < 0 then string was [+-]\.0*...
 
541
            // If significant_digits != 0 the string is not equal to 0.
 
542
            // Otherwise there are no digits in the string.
 
543
            return 0.0;
 
544
        }
 
545
        
 
546
        // Parse exponential part.
 
547
        if (*current == 'e' || *current == 'E') {
 
548
            ++current;
 
549
            if (current == end) {
 
550
                --current;
 
551
                goto parsing_done;
 
552
            }
 
553
            char sign = 0;
 
554
            if (*current == '+' || *current == '-') {
 
555
                sign = static_cast<char>(*current);
 
556
                ++current;
 
557
                if (current == end) {
 
558
                    current -= 2;
 
559
                    goto parsing_done;
 
560
                }
 
561
            }
 
562
            
 
563
            if (*current < '0' || *current > '9') {
 
564
                if (sign)
 
565
                    --current;
 
566
                --current;
 
567
                goto parsing_done;
 
568
            }
 
569
            
 
570
            const int max_exponent = INT_MAX / 2;
 
571
            ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
 
572
            int num = 0;
 
573
            do {
 
574
                // Check overflow.
 
575
                int digit = *current - '0';
 
576
                if (num >= max_exponent / 10
 
577
                    && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
 
578
                    num = max_exponent;
 
579
                } else {
 
580
                    num = num * 10 + digit;
 
581
                }
 
582
                ++current;
 
583
            } while (current != end && *current >= '0' && *current <= '9');
 
584
            
 
585
            exponent += (sign == '-' ? -num : num);
 
586
        }
 
587
        
 
588
    parsing_done:
 
589
        exponent += insignificant_digits;
 
590
        
 
591
        if (nonzero_digit_dropped) {
 
592
            buffer[buffer_pos++] = '1';
 
593
            exponent--;
 
594
        }
 
595
        
 
596
        ASSERT(buffer_pos < kBufferSize);
 
597
        buffer[buffer_pos] = '\0';
 
598
        
 
599
        double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
 
600
        *processed_characters_count = current - input;
 
601
        return sign? -converted: converted;
 
602
    }
 
603
    
 
604
}  // namespace double_conversion
 
605
 
 
606
} // namespace WTF