1 // © 2018 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 // From the double-conversion library. Original license:
6 // Copyright 2010 the V8 project authors. All rights reserved.
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following
15 // disclaimer in the documentation and/or other materials provided
16 // with the distribution.
17 // * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 // ICU PATCH: ifdef around UCONFIG_NO_FORMATTING
34 #include "unicode/utypes.h"
35 #if !UCONFIG_NO_FORMATTING
40 // ICU PATCH: Customize header file paths for ICU.
41 // The file fixed-dtoa.h is not needed.
43 #include "double-conversion.h"
45 #include "double-conversion-bignum-dtoa.h"
46 #include "double-conversion-fast-dtoa.h"
47 #include "double-conversion-ieee.h"
48 #include "double-conversion-strtod.h"
49 #include "double-conversion-utils.h"
51 // ICU PATCH: Wrap in ICU namespace
54 namespace double_conversion
{
56 #if 0 // not needed for ICU
57 const DoubleToStringConverter
& DoubleToStringConverter::EcmaScriptConverter() {
58 int flags
= UNIQUE_ZERO
| EMIT_POSITIVE_EXPONENT_SIGN
;
59 static DoubleToStringConverter
converter(flags
,
69 bool DoubleToStringConverter::HandleSpecialValues(
71 StringBuilder
* result_builder
) const {
72 Double
double_inspect(value
);
73 if (double_inspect
.IsInfinite()) {
74 if (infinity_symbol_
== NULL
) return false;
76 result_builder
->AddCharacter('-');
78 result_builder
->AddString(infinity_symbol_
);
81 if (double_inspect
.IsNan()) {
82 if (nan_symbol_
== NULL
) return false;
83 result_builder
->AddString(nan_symbol_
);
90 void DoubleToStringConverter::CreateExponentialRepresentation(
91 const char* decimal_digits
,
94 StringBuilder
* result_builder
) const {
96 result_builder
->AddCharacter(decimal_digits
[0]);
98 result_builder
->AddCharacter('.');
99 result_builder
->AddSubstring(&decimal_digits
[1], length
-1);
101 result_builder
->AddCharacter(exponent_character_
);
103 result_builder
->AddCharacter('-');
104 exponent
= -exponent
;
106 if ((flags_
& EMIT_POSITIVE_EXPONENT_SIGN
) != 0) {
107 result_builder
->AddCharacter('+');
111 result_builder
->AddCharacter('0');
114 ASSERT(exponent
< 1e4
);
115 const int kMaxExponentLength
= 5;
116 char buffer
[kMaxExponentLength
+ 1];
117 buffer
[kMaxExponentLength
] = '\0';
118 int first_char_pos
= kMaxExponentLength
;
119 while (exponent
> 0) {
120 buffer
[--first_char_pos
] = '0' + (exponent
% 10);
123 result_builder
->AddSubstring(&buffer
[first_char_pos
],
124 kMaxExponentLength
- first_char_pos
);
128 void DoubleToStringConverter::CreateDecimalRepresentation(
129 const char* decimal_digits
,
132 int digits_after_point
,
133 StringBuilder
* result_builder
) const {
134 // Create a representation that is padded with zeros if needed.
135 if (decimal_point
<= 0) {
136 // "0.00000decimal_rep" or "0.000decimal_rep00".
137 result_builder
->AddCharacter('0');
138 if (digits_after_point
> 0) {
139 result_builder
->AddCharacter('.');
140 result_builder
->AddPadding('0', -decimal_point
);
141 ASSERT(length
<= digits_after_point
- (-decimal_point
));
142 result_builder
->AddSubstring(decimal_digits
, length
);
143 int remaining_digits
= digits_after_point
- (-decimal_point
) - length
;
144 result_builder
->AddPadding('0', remaining_digits
);
146 } else if (decimal_point
>= length
) {
147 // "decimal_rep0000.00000" or "decimal_rep.0000".
148 result_builder
->AddSubstring(decimal_digits
, length
);
149 result_builder
->AddPadding('0', decimal_point
- length
);
150 if (digits_after_point
> 0) {
151 result_builder
->AddCharacter('.');
152 result_builder
->AddPadding('0', digits_after_point
);
155 // "decima.l_rep000".
156 ASSERT(digits_after_point
> 0);
157 result_builder
->AddSubstring(decimal_digits
, decimal_point
);
158 result_builder
->AddCharacter('.');
159 ASSERT(length
- decimal_point
<= digits_after_point
);
160 result_builder
->AddSubstring(&decimal_digits
[decimal_point
],
161 length
- decimal_point
);
162 int remaining_digits
= digits_after_point
- (length
- decimal_point
);
163 result_builder
->AddPadding('0', remaining_digits
);
165 if (digits_after_point
== 0) {
166 if ((flags_
& EMIT_TRAILING_DECIMAL_POINT
) != 0) {
167 result_builder
->AddCharacter('.');
169 if ((flags_
& EMIT_TRAILING_ZERO_AFTER_POINT
) != 0) {
170 result_builder
->AddCharacter('0');
176 bool DoubleToStringConverter::ToShortestIeeeNumber(
178 StringBuilder
* result_builder
,
179 DoubleToStringConverter::DtoaMode mode
) const {
180 ASSERT(mode
== SHORTEST
|| mode
== SHORTEST_SINGLE
);
181 if (Double(value
).IsSpecial()) {
182 return HandleSpecialValues(value
, result_builder
);
187 const int kDecimalRepCapacity
= kBase10MaximalLength
+ 1;
188 char decimal_rep
[kDecimalRepCapacity
];
189 int decimal_rep_length
;
191 DoubleToAscii(value
, mode
, 0, decimal_rep
, kDecimalRepCapacity
,
192 &sign
, &decimal_rep_length
, &decimal_point
);
194 bool unique_zero
= (flags_
& UNIQUE_ZERO
) != 0;
195 if (sign
&& (value
!= 0.0 || !unique_zero
)) {
196 result_builder
->AddCharacter('-');
199 int exponent
= decimal_point
- 1;
200 if ((decimal_in_shortest_low_
<= exponent
) &&
201 (exponent
< decimal_in_shortest_high_
)) {
202 CreateDecimalRepresentation(decimal_rep
, decimal_rep_length
,
204 Max(0, decimal_rep_length
- decimal_point
),
207 CreateExponentialRepresentation(decimal_rep
, decimal_rep_length
, exponent
,
214 bool DoubleToStringConverter::ToFixed(double value
,
215 int requested_digits
,
216 StringBuilder
* result_builder
) const {
217 ASSERT(kMaxFixedDigitsBeforePoint
== 60);
218 const double kFirstNonFixed
= 1e60
;
220 if (Double(value
).IsSpecial()) {
221 return HandleSpecialValues(value
, result_builder
);
224 if (requested_digits
> kMaxFixedDigitsAfterPoint
) return false;
225 if (value
>= kFirstNonFixed
|| value
<= -kFirstNonFixed
) return false;
227 // Find a sufficiently precise decimal representation of n.
230 // Add space for the '\0' byte.
231 const int kDecimalRepCapacity
=
232 kMaxFixedDigitsBeforePoint
+ kMaxFixedDigitsAfterPoint
+ 1;
233 char decimal_rep
[kDecimalRepCapacity
];
234 int decimal_rep_length
;
235 DoubleToAscii(value
, FIXED
, requested_digits
,
236 decimal_rep
, kDecimalRepCapacity
,
237 &sign
, &decimal_rep_length
, &decimal_point
);
239 bool unique_zero
= ((flags_
& UNIQUE_ZERO
) != 0);
240 if (sign
&& (value
!= 0.0 || !unique_zero
)) {
241 result_builder
->AddCharacter('-');
244 CreateDecimalRepresentation(decimal_rep
, decimal_rep_length
, decimal_point
,
245 requested_digits
, result_builder
);
250 bool DoubleToStringConverter::ToExponential(
252 int requested_digits
,
253 StringBuilder
* result_builder
) const {
254 if (Double(value
).IsSpecial()) {
255 return HandleSpecialValues(value
, result_builder
);
258 if (requested_digits
< -1) return false;
259 if (requested_digits
> kMaxExponentialDigits
) return false;
263 // Add space for digit before the decimal point and the '\0' character.
264 const int kDecimalRepCapacity
= kMaxExponentialDigits
+ 2;
265 ASSERT(kDecimalRepCapacity
> kBase10MaximalLength
);
266 char decimal_rep
[kDecimalRepCapacity
];
267 int decimal_rep_length
;
269 if (requested_digits
== -1) {
270 DoubleToAscii(value
, SHORTEST
, 0,
271 decimal_rep
, kDecimalRepCapacity
,
272 &sign
, &decimal_rep_length
, &decimal_point
);
274 DoubleToAscii(value
, PRECISION
, requested_digits
+ 1,
275 decimal_rep
, kDecimalRepCapacity
,
276 &sign
, &decimal_rep_length
, &decimal_point
);
277 ASSERT(decimal_rep_length
<= requested_digits
+ 1);
279 for (int i
= decimal_rep_length
; i
< requested_digits
+ 1; ++i
) {
280 decimal_rep
[i
] = '0';
282 decimal_rep_length
= requested_digits
+ 1;
285 bool unique_zero
= ((flags_
& UNIQUE_ZERO
) != 0);
286 if (sign
&& (value
!= 0.0 || !unique_zero
)) {
287 result_builder
->AddCharacter('-');
290 int exponent
= decimal_point
- 1;
291 CreateExponentialRepresentation(decimal_rep
,
299 bool DoubleToStringConverter::ToPrecision(double value
,
301 StringBuilder
* result_builder
) const {
302 if (Double(value
).IsSpecial()) {
303 return HandleSpecialValues(value
, result_builder
);
306 if (precision
< kMinPrecisionDigits
|| precision
> kMaxPrecisionDigits
) {
310 // Find a sufficiently precise decimal representation of n.
313 // Add one for the terminating null character.
314 const int kDecimalRepCapacity
= kMaxPrecisionDigits
+ 1;
315 char decimal_rep
[kDecimalRepCapacity
];
316 int decimal_rep_length
;
318 DoubleToAscii(value
, PRECISION
, precision
,
319 decimal_rep
, kDecimalRepCapacity
,
320 &sign
, &decimal_rep_length
, &decimal_point
);
321 ASSERT(decimal_rep_length
<= precision
);
323 bool unique_zero
= ((flags_
& UNIQUE_ZERO
) != 0);
324 if (sign
&& (value
!= 0.0 || !unique_zero
)) {
325 result_builder
->AddCharacter('-');
328 // The exponent if we print the number as x.xxeyyy. That is with the
329 // decimal point after the first digit.
330 int exponent
= decimal_point
- 1;
332 int extra_zero
= ((flags_
& EMIT_TRAILING_ZERO_AFTER_POINT
) != 0) ? 1 : 0;
333 if ((-decimal_point
+ 1 > max_leading_padding_zeroes_in_precision_mode_
) ||
334 (decimal_point
- precision
+ extra_zero
>
335 max_trailing_padding_zeroes_in_precision_mode_
)) {
336 // Fill buffer to contain 'precision' digits.
337 // Usually the buffer is already at the correct length, but 'DoubleToAscii'
338 // is allowed to return less characters.
339 for (int i
= decimal_rep_length
; i
< precision
; ++i
) {
340 decimal_rep
[i
] = '0';
343 CreateExponentialRepresentation(decimal_rep
,
348 CreateDecimalRepresentation(decimal_rep
, decimal_rep_length
, decimal_point
,
349 Max(0, precision
- decimal_point
),
354 #endif // not needed for ICU
357 static BignumDtoaMode
DtoaToBignumDtoaMode(
358 DoubleToStringConverter::DtoaMode dtoa_mode
) {
360 case DoubleToStringConverter::SHORTEST
: return BIGNUM_DTOA_SHORTEST
;
361 case DoubleToStringConverter::SHORTEST_SINGLE
:
362 return BIGNUM_DTOA_SHORTEST_SINGLE
;
363 case DoubleToStringConverter::FIXED
: return BIGNUM_DTOA_FIXED
;
364 case DoubleToStringConverter::PRECISION
: return BIGNUM_DTOA_PRECISION
;
371 void DoubleToStringConverter::DoubleToAscii(double v
,
373 int requested_digits
,
379 Vector
<char> vector(buffer
, buffer_length
);
380 ASSERT(!Double(v
).IsSpecial());
381 ASSERT(mode
== SHORTEST
|| mode
== SHORTEST_SINGLE
|| requested_digits
>= 0);
383 if (Double(v
).Sign() < 0) {
390 if (mode
== PRECISION
&& requested_digits
== 0) {
407 fast_worked
= FastDtoa(v
, FAST_DTOA_SHORTEST
, 0, vector
, length
, point
);
409 #if 0 // not needed for ICU
410 case SHORTEST_SINGLE
:
411 fast_worked
= FastDtoa(v
, FAST_DTOA_SHORTEST_SINGLE
, 0,
412 vector
, length
, point
);
415 fast_worked
= FastFixedDtoa(v
, requested_digits
, vector
, length
, point
);
418 fast_worked
= FastDtoa(v
, FAST_DTOA_PRECISION
, requested_digits
,
419 vector
, length
, point
);
421 #endif // not needed for ICU
426 if (fast_worked
) return;
428 // If the fast dtoa didn't succeed use the slower bignum version.
429 BignumDtoaMode bignum_mode
= DtoaToBignumDtoaMode(mode
);
430 BignumDtoa(v
, bignum_mode
, requested_digits
, vector
, length
, point
);
431 vector
[*length
] = '\0';
435 // Consumes the given substring from the iterator.
436 // Returns false, if the substring does not match.
437 template <class Iterator
>
438 static bool ConsumeSubString(Iterator
* current
,
440 const char* substring
) {
441 ASSERT(**current
== *substring
);
442 for (substring
++; *substring
!= '\0'; substring
++) {
444 if (*current
== end
|| **current
!= *substring
) return false;
451 // Maximum number of significant digits in decimal representation.
452 // The longest possible double in decimal representation is
453 // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
454 // (768 digits). If we parse a number whose first digits are equal to a
455 // mean of 2 adjacent doubles (that could have up to 769 digits) the result
456 // must be rounded to the bigger one unless the tail consists of zeros, so
457 // we don't need to preserve all the digits.
458 const int kMaxSignificantDigits
= 772;
461 static const char kWhitespaceTable7
[] = { 32, 13, 10, 9, 11, 12 };
462 static const int kWhitespaceTable7Length
= ARRAY_SIZE(kWhitespaceTable7
);
465 static const uc16 kWhitespaceTable16
[] = {
466 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
467 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
469 static const int kWhitespaceTable16Length
= ARRAY_SIZE(kWhitespaceTable16
);
473 static bool isWhitespace(int x
) {
475 for (int i
= 0; i
< kWhitespaceTable7Length
; i
++) {
476 if (kWhitespaceTable7
[i
] == x
) return true;
479 for (int i
= 0; i
< kWhitespaceTable16Length
; i
++) {
480 if (kWhitespaceTable16
[i
] == x
) return true;
487 // Returns true if a nonspace found and false if the end has reached.
488 template <class Iterator
>
489 static inline bool AdvanceToNonspace(Iterator
* current
, Iterator end
) {
490 while (*current
!= end
) {
491 if (!isWhitespace(**current
)) return true;
498 static bool isDigit(int x
, int radix
) {
499 return (x
>= '0' && x
<= '9' && x
< '0' + radix
)
500 || (radix
> 10 && x
>= 'a' && x
< 'a' + radix
- 10)
501 || (radix
> 10 && x
>= 'A' && x
< 'A' + radix
- 10);
505 static double SignedZero(bool sign
) {
506 return sign
? -0.0 : 0.0;
510 // Returns true if 'c' is a decimal digit that is valid for the given radix.
512 // The function is small and could be inlined, but VS2012 emitted a warning
513 // because it constant-propagated the radix and concluded that the last
514 // condition was always true. By moving it into a separate function the
515 // compiler wouldn't warn anymore.
517 #pragma optimize("",off)
518 static bool IsDecimalDigitForRadix(int c
, int radix
) {
519 return '0' <= c
&& c
<= '9' && (c
- '0') < radix
;
521 #pragma optimize("",on)
523 static bool inline IsDecimalDigitForRadix(int c
, int radix
) {
524 return '0' <= c
&& c
<= '9' && (c
- '0') < radix
;
527 // Returns true if 'c' is a character digit that is valid for the given radix.
528 // The 'a_character' should be 'a' or 'A'.
530 // The function is small and could be inlined, but VS2012 emitted a warning
531 // because it constant-propagated the radix and concluded that the first
532 // condition was always false. By moving it into a separate function the
533 // compiler wouldn't warn anymore.
534 static bool IsCharacterDigitForRadix(int c
, int radix
, char a_character
) {
535 return radix
> 10 && c
>= a_character
&& c
< a_character
+ radix
- 10;
539 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
540 template <int radix_log_2
, class Iterator
>
541 static double RadixStringToIeee(Iterator
* current
,
544 bool allow_trailing_junk
,
545 double junk_string_value
,
547 bool* result_is_junk
) {
548 ASSERT(*current
!= end
);
550 const int kDoubleSize
= Double::kSignificandSize
;
551 const int kSingleSize
= Single::kSignificandSize
;
552 const int kSignificandSize
= read_as_double
? kDoubleSize
: kSingleSize
;
554 *result_is_junk
= true;
557 while (**current
== '0') {
559 if (*current
== end
) {
560 *result_is_junk
= false;
561 return SignedZero(sign
);
567 const int radix
= (1 << radix_log_2
);
571 if (IsDecimalDigitForRadix(**current
, radix
)) {
572 digit
= static_cast<char>(**current
) - '0';
573 } else if (IsCharacterDigitForRadix(**current
, radix
, 'a')) {
574 digit
= static_cast<char>(**current
) - 'a' + 10;
575 } else if (IsCharacterDigitForRadix(**current
, radix
, 'A')) {
576 digit
= static_cast<char>(**current
) - 'A' + 10;
578 if (allow_trailing_junk
|| !AdvanceToNonspace(current
, end
)) {
581 return junk_string_value
;
585 number
= number
* radix
+ digit
;
586 int overflow
= static_cast<int>(number
>> kSignificandSize
);
588 // Overflow occurred. Need to determine which direction to round the
590 int overflow_bits_count
= 1;
591 while (overflow
> 1) {
592 overflow_bits_count
++;
596 int dropped_bits_mask
= ((1 << overflow_bits_count
) - 1);
597 int dropped_bits
= static_cast<int>(number
) & dropped_bits_mask
;
598 number
>>= overflow_bits_count
;
599 exponent
= overflow_bits_count
;
601 bool zero_tail
= true;
604 if (*current
== end
|| !isDigit(**current
, radix
)) break;
605 zero_tail
= zero_tail
&& **current
== '0';
606 exponent
+= radix_log_2
;
609 if (!allow_trailing_junk
&& AdvanceToNonspace(current
, end
)) {
610 return junk_string_value
;
613 int middle_value
= (1 << (overflow_bits_count
- 1));
614 if (dropped_bits
> middle_value
) {
615 number
++; // Rounding up.
616 } else if (dropped_bits
== middle_value
) {
617 // Rounding to even to consistency with decimals: half-way case rounds
618 // up if significant part is odd and down otherwise.
619 if ((number
& 1) != 0 || !zero_tail
) {
620 number
++; // Rounding up.
624 // Rounding up may cause overflow.
625 if ((number
& ((int64_t)1 << kSignificandSize
)) != 0) {
632 } while (*current
!= end
);
634 ASSERT(number
< ((int64_t)1 << kSignificandSize
));
635 ASSERT(static_cast<int64_t>(static_cast<double>(number
)) == number
);
637 *result_is_junk
= false;
641 if (number
== 0) return -0.0;
644 return static_cast<double>(number
);
648 return Double(DiyFp(number
, exponent
)).value();
651 template <class Iterator
>
652 double StringToDoubleConverter::StringToIeee(
656 int* processed_characters_count
) const {
657 Iterator current
= input
;
658 Iterator end
= input
+ length
;
660 *processed_characters_count
= 0;
662 const bool allow_trailing_junk
= (flags_
& ALLOW_TRAILING_JUNK
) != 0;
663 const bool allow_leading_spaces
= (flags_
& ALLOW_LEADING_SPACES
) != 0;
664 const bool allow_trailing_spaces
= (flags_
& ALLOW_TRAILING_SPACES
) != 0;
665 const bool allow_spaces_after_sign
= (flags_
& ALLOW_SPACES_AFTER_SIGN
) != 0;
667 // To make sure that iterator dereferencing is valid the following
668 // convention is used:
669 // 1. Each '++current' statement is followed by check for equality to 'end'.
670 // 2. If AdvanceToNonspace returned false then current == end.
671 // 3. If 'current' becomes equal to 'end' the function returns or goes to
673 // 4. 'current' is not dereferenced after the 'parsing_done' label.
674 // 5. Code before 'parsing_done' may rely on 'current != end'.
675 if (current
== end
) return empty_string_value_
;
677 if (allow_leading_spaces
|| allow_trailing_spaces
) {
678 if (!AdvanceToNonspace(¤t
, end
)) {
679 *processed_characters_count
= static_cast<int>(current
- input
);
680 return empty_string_value_
;
682 if (!allow_leading_spaces
&& (input
!= current
)) {
683 // No leading spaces allowed, but AdvanceToNonspace moved forward.
684 return junk_string_value_
;
688 // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
689 const int kBufferSize
= kMaxSignificantDigits
+ 10;
690 char buffer
[kBufferSize
]; // NOLINT: size is known at compile time.
693 // Exponent will be adjusted if insignificant digits of the integer part
694 // or insignificant leading zeros of the fractional part are dropped.
696 int significant_digits
= 0;
697 int insignificant_digits
= 0;
698 bool nonzero_digit_dropped
= false;
702 if (*current
== '+' || *current
== '-') {
703 sign
= (*current
== '-');
705 Iterator next_non_space
= current
;
706 // Skip following spaces (if allowed).
707 if (!AdvanceToNonspace(&next_non_space
, end
)) return junk_string_value_
;
708 if (!allow_spaces_after_sign
&& (current
!= next_non_space
)) {
709 return junk_string_value_
;
711 current
= next_non_space
;
714 if (infinity_symbol_
!= NULL
) {
715 if (*current
== infinity_symbol_
[0]) {
716 if (!ConsumeSubString(¤t
, end
, infinity_symbol_
)) {
717 return junk_string_value_
;
720 if (!(allow_trailing_spaces
|| allow_trailing_junk
) && (current
!= end
)) {
721 return junk_string_value_
;
723 if (!allow_trailing_junk
&& AdvanceToNonspace(¤t
, end
)) {
724 return junk_string_value_
;
727 ASSERT(buffer_pos
== 0);
728 *processed_characters_count
= static_cast<int>(current
- input
);
729 return sign
? -Double::Infinity() : Double::Infinity();
733 if (nan_symbol_
!= NULL
) {
734 if (*current
== nan_symbol_
[0]) {
735 if (!ConsumeSubString(¤t
, end
, nan_symbol_
)) {
736 return junk_string_value_
;
739 if (!(allow_trailing_spaces
|| allow_trailing_junk
) && (current
!= end
)) {
740 return junk_string_value_
;
742 if (!allow_trailing_junk
&& AdvanceToNonspace(¤t
, end
)) {
743 return junk_string_value_
;
746 ASSERT(buffer_pos
== 0);
747 *processed_characters_count
= static_cast<int>(current
- input
);
748 return sign
? -Double::NaN() : Double::NaN();
752 bool leading_zero
= false;
753 if (*current
== '0') {
755 if (current
== end
) {
756 *processed_characters_count
= static_cast<int>(current
- input
);
757 return SignedZero(sign
);
762 // It could be hexadecimal value.
763 if ((flags_
& ALLOW_HEX
) && (*current
== 'x' || *current
== 'X')) {
765 if (current
== end
|| !isDigit(*current
, 16)) {
766 return junk_string_value_
; // "0x".
770 double result
= RadixStringToIeee
<4>(¤t
,
777 if (!result_is_junk
) {
778 if (allow_trailing_spaces
) AdvanceToNonspace(¤t
, end
);
779 *processed_characters_count
= static_cast<int>(current
- input
);
784 // Ignore leading zeros in the integer part.
785 while (*current
== '0') {
787 if (current
== end
) {
788 *processed_characters_count
= static_cast<int>(current
- input
);
789 return SignedZero(sign
);
794 bool octal
= leading_zero
&& (flags_
& ALLOW_OCTALS
) != 0;
796 // Copy significant digits of the integer part (if any) to the buffer.
797 while (*current
>= '0' && *current
<= '9') {
798 if (significant_digits
< kMaxSignificantDigits
) {
799 ASSERT(buffer_pos
< kBufferSize
);
800 buffer
[buffer_pos
++] = static_cast<char>(*current
);
801 significant_digits
++;
802 // Will later check if it's an octal in the buffer.
804 insignificant_digits
++; // Move the digit into the exponential part.
805 nonzero_digit_dropped
= nonzero_digit_dropped
|| *current
!= '0';
807 octal
= octal
&& *current
< '8';
809 if (current
== end
) goto parsing_done
;
812 if (significant_digits
== 0) {
816 if (*current
== '.') {
817 if (octal
&& !allow_trailing_junk
) return junk_string_value_
;
818 if (octal
) goto parsing_done
;
821 if (current
== end
) {
822 if (significant_digits
== 0 && !leading_zero
) {
823 return junk_string_value_
;
829 if (significant_digits
== 0) {
831 // Integer part consists of 0 or is absent. Significant digits start after
832 // leading zeros (if any).
833 while (*current
== '0') {
835 if (current
== end
) {
836 *processed_characters_count
= static_cast<int>(current
- input
);
837 return SignedZero(sign
);
839 exponent
--; // Move this 0 into the exponent.
843 // There is a fractional part.
844 // We don't emit a '.', but adjust the exponent instead.
845 while (*current
>= '0' && *current
<= '9') {
846 if (significant_digits
< kMaxSignificantDigits
) {
847 ASSERT(buffer_pos
< kBufferSize
);
848 buffer
[buffer_pos
++] = static_cast<char>(*current
);
849 significant_digits
++;
852 // Ignore insignificant digits in the fractional part.
853 nonzero_digit_dropped
= nonzero_digit_dropped
|| *current
!= '0';
856 if (current
== end
) goto parsing_done
;
860 if (!leading_zero
&& exponent
== 0 && significant_digits
== 0) {
861 // If leading_zeros is true then the string contains zeros.
862 // If exponent < 0 then string was [+-]\.0*...
863 // If significant_digits != 0 the string is not equal to 0.
864 // Otherwise there are no digits in the string.
865 return junk_string_value_
;
868 // Parse exponential part.
869 if (*current
== 'e' || *current
== 'E') {
870 if (octal
&& !allow_trailing_junk
) return junk_string_value_
;
871 if (octal
) goto parsing_done
;
873 if (current
== end
) {
874 if (allow_trailing_junk
) {
877 return junk_string_value_
;
880 char exponen_sign
= '+';
881 if (*current
== '+' || *current
== '-') {
882 exponen_sign
= static_cast<char>(*current
);
884 if (current
== end
) {
885 if (allow_trailing_junk
) {
888 return junk_string_value_
;
893 if (current
== end
|| *current
< '0' || *current
> '9') {
894 if (allow_trailing_junk
) {
897 return junk_string_value_
;
901 const int max_exponent
= INT_MAX
/ 2;
902 ASSERT(-max_exponent
/ 2 <= exponent
&& exponent
<= max_exponent
/ 2);
906 int digit
= *current
- '0';
907 if (num
>= max_exponent
/ 10
908 && !(num
== max_exponent
/ 10 && digit
<= max_exponent
% 10)) {
911 num
= num
* 10 + digit
;
914 } while (current
!= end
&& *current
>= '0' && *current
<= '9');
916 exponent
+= (exponen_sign
== '-' ? -num
: num
);
919 if (!(allow_trailing_spaces
|| allow_trailing_junk
) && (current
!= end
)) {
920 return junk_string_value_
;
922 if (!allow_trailing_junk
&& AdvanceToNonspace(¤t
, end
)) {
923 return junk_string_value_
;
925 if (allow_trailing_spaces
) {
926 AdvanceToNonspace(¤t
, end
);
930 exponent
+= insignificant_digits
;
935 char* start
= buffer
;
936 result
= RadixStringToIeee
<3>(&start
,
943 ASSERT(!result_is_junk
);
944 *processed_characters_count
= static_cast<int>(current
- input
);
948 if (nonzero_digit_dropped
) {
949 buffer
[buffer_pos
++] = '1';
953 ASSERT(buffer_pos
< kBufferSize
);
954 buffer
[buffer_pos
] = '\0';
957 if (read_as_double
) {
958 converted
= Strtod(Vector
<const char>(buffer
, buffer_pos
), exponent
);
960 converted
= Strtof(Vector
<const char>(buffer
, buffer_pos
), exponent
);
962 *processed_characters_count
= static_cast<int>(current
- input
);
963 return sign
? -converted
: converted
;
967 double StringToDoubleConverter::StringToDouble(
970 int* processed_characters_count
) const {
971 return StringToIeee(buffer
, length
, true, processed_characters_count
);
975 double StringToDoubleConverter::StringToDouble(
978 int* processed_characters_count
) const {
979 return StringToIeee(buffer
, length
, true, processed_characters_count
);
983 float StringToDoubleConverter::StringToFloat(
986 int* processed_characters_count
) const {
987 return static_cast<float>(StringToIeee(buffer
, length
, false,
988 processed_characters_count
));
992 float StringToDoubleConverter::StringToFloat(
995 int* processed_characters_count
) const {
996 return static_cast<float>(StringToIeee(buffer
, length
, false,
997 processed_characters_count
));
1000 } // namespace double_conversion
1002 // ICU PATCH: Close ICU namespace
1004 #endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING