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
37 // ICU PATCH: Do not include std::locale.
43 // ICU PATCH: Customize header file paths for ICU.
44 // The file fixed-dtoa.h is not needed.
46 #include "double-conversion.h"
48 #include "double-conversion-bignum-dtoa.h"
49 #include "double-conversion-fast-dtoa.h"
50 #include "double-conversion-ieee.h"
51 #include "double-conversion-strtod.h"
52 #include "double-conversion-utils.h"
54 // ICU PATCH: Wrap in ICU namespace
57 namespace double_conversion
{
59 #if 0 // not needed for ICU
60 const DoubleToStringConverter
& DoubleToStringConverter::EcmaScriptConverter() {
61 int flags
= UNIQUE_ZERO
| EMIT_POSITIVE_EXPONENT_SIGN
;
62 static DoubleToStringConverter
converter(flags
,
72 bool DoubleToStringConverter::HandleSpecialValues(
74 StringBuilder
* result_builder
) const {
75 Double
double_inspect(value
);
76 if (double_inspect
.IsInfinite()) {
77 if (infinity_symbol_
== NULL
) return false;
79 result_builder
->AddCharacter('-');
81 result_builder
->AddString(infinity_symbol_
);
84 if (double_inspect
.IsNan()) {
85 if (nan_symbol_
== NULL
) return false;
86 result_builder
->AddString(nan_symbol_
);
93 void DoubleToStringConverter::CreateExponentialRepresentation(
94 const char* decimal_digits
,
97 StringBuilder
* result_builder
) const {
99 result_builder
->AddCharacter(decimal_digits
[0]);
101 result_builder
->AddCharacter('.');
102 result_builder
->AddSubstring(&decimal_digits
[1], length
-1);
104 result_builder
->AddCharacter(exponent_character_
);
106 result_builder
->AddCharacter('-');
107 exponent
= -exponent
;
109 if ((flags_
& EMIT_POSITIVE_EXPONENT_SIGN
) != 0) {
110 result_builder
->AddCharacter('+');
114 result_builder
->AddCharacter('0');
117 ASSERT(exponent
< 1e4
);
118 const int kMaxExponentLength
= 5;
119 char buffer
[kMaxExponentLength
+ 1];
120 buffer
[kMaxExponentLength
] = '\0';
121 int first_char_pos
= kMaxExponentLength
;
122 while (exponent
> 0) {
123 buffer
[--first_char_pos
] = '0' + (exponent
% 10);
126 result_builder
->AddSubstring(&buffer
[first_char_pos
],
127 kMaxExponentLength
- first_char_pos
);
131 void DoubleToStringConverter::CreateDecimalRepresentation(
132 const char* decimal_digits
,
135 int digits_after_point
,
136 StringBuilder
* result_builder
) const {
137 // Create a representation that is padded with zeros if needed.
138 if (decimal_point
<= 0) {
139 // "0.00000decimal_rep" or "0.000decimal_rep00".
140 result_builder
->AddCharacter('0');
141 if (digits_after_point
> 0) {
142 result_builder
->AddCharacter('.');
143 result_builder
->AddPadding('0', -decimal_point
);
144 ASSERT(length
<= digits_after_point
- (-decimal_point
));
145 result_builder
->AddSubstring(decimal_digits
, length
);
146 int remaining_digits
= digits_after_point
- (-decimal_point
) - length
;
147 result_builder
->AddPadding('0', remaining_digits
);
149 } else if (decimal_point
>= length
) {
150 // "decimal_rep0000.00000" or "decimal_rep.0000".
151 result_builder
->AddSubstring(decimal_digits
, length
);
152 result_builder
->AddPadding('0', decimal_point
- length
);
153 if (digits_after_point
> 0) {
154 result_builder
->AddCharacter('.');
155 result_builder
->AddPadding('0', digits_after_point
);
158 // "decima.l_rep000".
159 ASSERT(digits_after_point
> 0);
160 result_builder
->AddSubstring(decimal_digits
, decimal_point
);
161 result_builder
->AddCharacter('.');
162 ASSERT(length
- decimal_point
<= digits_after_point
);
163 result_builder
->AddSubstring(&decimal_digits
[decimal_point
],
164 length
- decimal_point
);
165 int remaining_digits
= digits_after_point
- (length
- decimal_point
);
166 result_builder
->AddPadding('0', remaining_digits
);
168 if (digits_after_point
== 0) {
169 if ((flags_
& EMIT_TRAILING_DECIMAL_POINT
) != 0) {
170 result_builder
->AddCharacter('.');
172 if ((flags_
& EMIT_TRAILING_ZERO_AFTER_POINT
) != 0) {
173 result_builder
->AddCharacter('0');
179 bool DoubleToStringConverter::ToShortestIeeeNumber(
181 StringBuilder
* result_builder
,
182 DoubleToStringConverter::DtoaMode mode
) const {
183 ASSERT(mode
== SHORTEST
|| mode
== SHORTEST_SINGLE
);
184 if (Double(value
).IsSpecial()) {
185 return HandleSpecialValues(value
, result_builder
);
190 const int kDecimalRepCapacity
= kBase10MaximalLength
+ 1;
191 char decimal_rep
[kDecimalRepCapacity
];
192 int decimal_rep_length
;
194 DoubleToAscii(value
, mode
, 0, decimal_rep
, kDecimalRepCapacity
,
195 &sign
, &decimal_rep_length
, &decimal_point
);
197 bool unique_zero
= (flags_
& UNIQUE_ZERO
) != 0;
198 if (sign
&& (value
!= 0.0 || !unique_zero
)) {
199 result_builder
->AddCharacter('-');
202 int exponent
= decimal_point
- 1;
203 if ((decimal_in_shortest_low_
<= exponent
) &&
204 (exponent
< decimal_in_shortest_high_
)) {
205 CreateDecimalRepresentation(decimal_rep
, decimal_rep_length
,
207 Max(0, decimal_rep_length
- decimal_point
),
210 CreateExponentialRepresentation(decimal_rep
, decimal_rep_length
, exponent
,
217 bool DoubleToStringConverter::ToFixed(double value
,
218 int requested_digits
,
219 StringBuilder
* result_builder
) const {
220 ASSERT(kMaxFixedDigitsBeforePoint
== 60);
221 const double kFirstNonFixed
= 1e60
;
223 if (Double(value
).IsSpecial()) {
224 return HandleSpecialValues(value
, result_builder
);
227 if (requested_digits
> kMaxFixedDigitsAfterPoint
) return false;
228 if (value
>= kFirstNonFixed
|| value
<= -kFirstNonFixed
) return false;
230 // Find a sufficiently precise decimal representation of n.
233 // Add space for the '\0' byte.
234 const int kDecimalRepCapacity
=
235 kMaxFixedDigitsBeforePoint
+ kMaxFixedDigitsAfterPoint
+ 1;
236 char decimal_rep
[kDecimalRepCapacity
];
237 int decimal_rep_length
;
238 DoubleToAscii(value
, FIXED
, requested_digits
,
239 decimal_rep
, kDecimalRepCapacity
,
240 &sign
, &decimal_rep_length
, &decimal_point
);
242 bool unique_zero
= ((flags_
& UNIQUE_ZERO
) != 0);
243 if (sign
&& (value
!= 0.0 || !unique_zero
)) {
244 result_builder
->AddCharacter('-');
247 CreateDecimalRepresentation(decimal_rep
, decimal_rep_length
, decimal_point
,
248 requested_digits
, result_builder
);
253 bool DoubleToStringConverter::ToExponential(
255 int requested_digits
,
256 StringBuilder
* result_builder
) const {
257 if (Double(value
).IsSpecial()) {
258 return HandleSpecialValues(value
, result_builder
);
261 if (requested_digits
< -1) return false;
262 if (requested_digits
> kMaxExponentialDigits
) return false;
266 // Add space for digit before the decimal point and the '\0' character.
267 const int kDecimalRepCapacity
= kMaxExponentialDigits
+ 2;
268 ASSERT(kDecimalRepCapacity
> kBase10MaximalLength
);
269 char decimal_rep
[kDecimalRepCapacity
];
270 int decimal_rep_length
;
272 if (requested_digits
== -1) {
273 DoubleToAscii(value
, SHORTEST
, 0,
274 decimal_rep
, kDecimalRepCapacity
,
275 &sign
, &decimal_rep_length
, &decimal_point
);
277 DoubleToAscii(value
, PRECISION
, requested_digits
+ 1,
278 decimal_rep
, kDecimalRepCapacity
,
279 &sign
, &decimal_rep_length
, &decimal_point
);
280 ASSERT(decimal_rep_length
<= requested_digits
+ 1);
282 for (int i
= decimal_rep_length
; i
< requested_digits
+ 1; ++i
) {
283 decimal_rep
[i
] = '0';
285 decimal_rep_length
= requested_digits
+ 1;
288 bool unique_zero
= ((flags_
& UNIQUE_ZERO
) != 0);
289 if (sign
&& (value
!= 0.0 || !unique_zero
)) {
290 result_builder
->AddCharacter('-');
293 int exponent
= decimal_point
- 1;
294 CreateExponentialRepresentation(decimal_rep
,
302 bool DoubleToStringConverter::ToPrecision(double value
,
304 StringBuilder
* result_builder
) const {
305 if (Double(value
).IsSpecial()) {
306 return HandleSpecialValues(value
, result_builder
);
309 if (precision
< kMinPrecisionDigits
|| precision
> kMaxPrecisionDigits
) {
313 // Find a sufficiently precise decimal representation of n.
316 // Add one for the terminating null character.
317 const int kDecimalRepCapacity
= kMaxPrecisionDigits
+ 1;
318 char decimal_rep
[kDecimalRepCapacity
];
319 int decimal_rep_length
;
321 DoubleToAscii(value
, PRECISION
, precision
,
322 decimal_rep
, kDecimalRepCapacity
,
323 &sign
, &decimal_rep_length
, &decimal_point
);
324 ASSERT(decimal_rep_length
<= precision
);
326 bool unique_zero
= ((flags_
& UNIQUE_ZERO
) != 0);
327 if (sign
&& (value
!= 0.0 || !unique_zero
)) {
328 result_builder
->AddCharacter('-');
331 // The exponent if we print the number as x.xxeyyy. That is with the
332 // decimal point after the first digit.
333 int exponent
= decimal_point
- 1;
335 int extra_zero
= ((flags_
& EMIT_TRAILING_ZERO_AFTER_POINT
) != 0) ? 1 : 0;
336 if ((-decimal_point
+ 1 > max_leading_padding_zeroes_in_precision_mode_
) ||
337 (decimal_point
- precision
+ extra_zero
>
338 max_trailing_padding_zeroes_in_precision_mode_
)) {
339 // Fill buffer to contain 'precision' digits.
340 // Usually the buffer is already at the correct length, but 'DoubleToAscii'
341 // is allowed to return less characters.
342 for (int i
= decimal_rep_length
; i
< precision
; ++i
) {
343 decimal_rep
[i
] = '0';
346 CreateExponentialRepresentation(decimal_rep
,
351 CreateDecimalRepresentation(decimal_rep
, decimal_rep_length
, decimal_point
,
352 Max(0, precision
- decimal_point
),
357 #endif // not needed for ICU
360 static BignumDtoaMode
DtoaToBignumDtoaMode(
361 DoubleToStringConverter::DtoaMode dtoa_mode
) {
363 case DoubleToStringConverter::SHORTEST
: return BIGNUM_DTOA_SHORTEST
;
364 case DoubleToStringConverter::SHORTEST_SINGLE
:
365 return BIGNUM_DTOA_SHORTEST_SINGLE
;
366 case DoubleToStringConverter::FIXED
: return BIGNUM_DTOA_FIXED
;
367 case DoubleToStringConverter::PRECISION
: return BIGNUM_DTOA_PRECISION
;
374 void DoubleToStringConverter::DoubleToAscii(double v
,
376 int requested_digits
,
382 Vector
<char> vector(buffer
, buffer_length
);
383 ASSERT(!Double(v
).IsSpecial());
384 ASSERT(mode
== SHORTEST
|| mode
== SHORTEST_SINGLE
|| requested_digits
>= 0);
386 if (Double(v
).Sign() < 0) {
393 if (mode
== PRECISION
&& requested_digits
== 0) {
410 fast_worked
= FastDtoa(v
, FAST_DTOA_SHORTEST
, 0, vector
, length
, point
);
412 #if 0 // not needed for ICU
413 case SHORTEST_SINGLE
:
414 fast_worked
= FastDtoa(v
, FAST_DTOA_SHORTEST_SINGLE
, 0,
415 vector
, length
, point
);
418 fast_worked
= FastFixedDtoa(v
, requested_digits
, vector
, length
, point
);
421 fast_worked
= FastDtoa(v
, FAST_DTOA_PRECISION
, requested_digits
,
422 vector
, length
, point
);
424 #endif // not needed for ICU
429 if (fast_worked
) return;
431 // If the fast dtoa didn't succeed use the slower bignum version.
432 BignumDtoaMode bignum_mode
= DtoaToBignumDtoaMode(mode
);
433 BignumDtoa(v
, bignum_mode
, requested_digits
, vector
, length
, point
);
434 vector
[*length
] = '\0';
440 inline char ToLower(char ch
) {
441 #if 0 // do not include std::locale in ICU
442 static const std::ctype
<char>& cType
=
443 std::use_facet
<std::ctype
<char> >(std::locale::classic());
444 return cType
.tolower(ch
);
451 inline char Pass(char ch
) {
455 template <class Iterator
, class Converter
>
456 static inline bool ConsumeSubStringImpl(Iterator
* current
,
458 const char* substring
,
459 Converter converter
) {
460 ASSERT(converter(**current
) == *substring
);
461 for (substring
++; *substring
!= '\0'; substring
++) {
463 if (*current
== end
|| converter(**current
) != *substring
) {
471 // Consumes the given substring from the iterator.
472 // Returns false, if the substring does not match.
473 template <class Iterator
>
474 static bool ConsumeSubString(Iterator
* current
,
476 const char* substring
,
477 bool allow_case_insensibility
) {
478 if (allow_case_insensibility
) {
479 return ConsumeSubStringImpl(current
, end
, substring
, ToLower
);
481 return ConsumeSubStringImpl(current
, end
, substring
, Pass
);
485 // Consumes first character of the str is equal to ch
486 inline bool ConsumeFirstCharacter(char ch
,
488 bool case_insensibility
) {
489 return case_insensibility
? ToLower(ch
) == str
[0] : ch
== str
[0];
493 // Maximum number of significant digits in decimal representation.
494 // The longest possible double in decimal representation is
495 // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
496 // (768 digits). If we parse a number whose first digits are equal to a
497 // mean of 2 adjacent doubles (that could have up to 769 digits) the result
498 // must be rounded to the bigger one unless the tail consists of zeros, so
499 // we don't need to preserve all the digits.
500 const int kMaxSignificantDigits
= 772;
503 static const char kWhitespaceTable7
[] = { 32, 13, 10, 9, 11, 12 };
504 static const int kWhitespaceTable7Length
= ARRAY_SIZE(kWhitespaceTable7
);
507 static const uc16 kWhitespaceTable16
[] = {
508 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
509 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
511 static const int kWhitespaceTable16Length
= ARRAY_SIZE(kWhitespaceTable16
);
515 static bool isWhitespace(int x
) {
517 for (int i
= 0; i
< kWhitespaceTable7Length
; i
++) {
518 if (kWhitespaceTable7
[i
] == x
) return true;
521 for (int i
= 0; i
< kWhitespaceTable16Length
; i
++) {
522 if (kWhitespaceTable16
[i
] == x
) return true;
529 // Returns true if a nonspace found and false if the end has reached.
530 template <class Iterator
>
531 static inline bool AdvanceToNonspace(Iterator
* current
, Iterator end
) {
532 while (*current
!= end
) {
533 if (!isWhitespace(**current
)) return true;
540 static bool isDigit(int x
, int radix
) {
541 return (x
>= '0' && x
<= '9' && x
< '0' + radix
)
542 || (radix
> 10 && x
>= 'a' && x
< 'a' + radix
- 10)
543 || (radix
> 10 && x
>= 'A' && x
< 'A' + radix
- 10);
547 static double SignedZero(bool sign
) {
548 return sign
? -0.0 : 0.0;
552 // Returns true if 'c' is a decimal digit that is valid for the given radix.
554 // The function is small and could be inlined, but VS2012 emitted a warning
555 // because it constant-propagated the radix and concluded that the last
556 // condition was always true. By moving it into a separate function the
557 // compiler wouldn't warn anymore.
559 #pragma optimize("",off)
560 static bool IsDecimalDigitForRadix(int c
, int radix
) {
561 return '0' <= c
&& c
<= '9' && (c
- '0') < radix
;
563 #pragma optimize("",on)
565 static bool inline IsDecimalDigitForRadix(int c
, int radix
) {
566 return '0' <= c
&& c
<= '9' && (c
- '0') < radix
;
569 // Returns true if 'c' is a character digit that is valid for the given radix.
570 // The 'a_character' should be 'a' or 'A'.
572 // The function is small and could be inlined, but VS2012 emitted a warning
573 // because it constant-propagated the radix and concluded that the first
574 // condition was always false. By moving it into a separate function the
575 // compiler wouldn't warn anymore.
576 static bool IsCharacterDigitForRadix(int c
, int radix
, char a_character
) {
577 return radix
> 10 && c
>= a_character
&& c
< a_character
+ radix
- 10;
580 // Returns true, when the iterator is equal to end.
581 template<class Iterator
>
582 static bool Advance (Iterator
* it
, uc16 separator
, int base
, Iterator
& end
) {
583 if (separator
== StringToDoubleConverter::kNoSeparator
) {
587 if (!isDigit(**it
, base
)) {
592 if (*it
== end
) return true;
593 if (*it
+ 1 == end
) return false;
594 if (**it
== separator
&& isDigit(*(*it
+ 1), base
)) {
600 // Checks whether the string in the range start-end is a hex-float string.
601 // This function assumes that the leading '0x'/'0X' is already consumed.
603 // Hex float strings are of one of the following forms:
604 // - hex_digits+ 'p' ('+'|'-')? exponent_digits+
605 // - hex_digits* '.' hex_digits+ 'p' ('+'|'-')? exponent_digits+
606 // - hex_digits+ '.' 'p' ('+'|'-')? exponent_digits+
607 template<class Iterator
>
608 static bool IsHexFloatString(Iterator start
,
611 bool allow_trailing_junk
) {
612 ASSERT(start
!= end
);
614 Iterator current
= start
;
616 bool saw_digit
= false;
617 while (isDigit(*current
, 16)) {
619 if (Advance(¤t
, separator
, 16, end
)) return false;
621 if (*current
== '.') {
622 if (Advance(¤t
, separator
, 16, end
)) return false;
623 while (isDigit(*current
, 16)) {
625 if (Advance(¤t
, separator
, 16, end
)) return false;
627 if (!saw_digit
) return false; // Only the '.', but no digits.
629 if (*current
!= 'p' && *current
!= 'P') return false;
630 if (Advance(¤t
, separator
, 16, end
)) return false;
631 if (*current
== '+' || *current
== '-') {
632 if (Advance(¤t
, separator
, 16, end
)) return false;
634 if (!isDigit(*current
, 10)) return false;
635 if (Advance(¤t
, separator
, 16, end
)) return true;
636 while (isDigit(*current
, 10)) {
637 if (Advance(¤t
, separator
, 16, end
)) return true;
639 return allow_trailing_junk
|| !AdvanceToNonspace(¤t
, end
);
643 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
645 // If parse_as_hex_float is true, then the string must be a valid
647 template <int radix_log_2
, class Iterator
>
648 static double RadixStringToIeee(Iterator
* current
,
652 bool parse_as_hex_float
,
653 bool allow_trailing_junk
,
654 double junk_string_value
,
656 bool* result_is_junk
) {
657 ASSERT(*current
!= end
);
658 ASSERT(!parse_as_hex_float
||
659 IsHexFloatString(*current
, end
, separator
, allow_trailing_junk
));
661 const int kDoubleSize
= Double::kSignificandSize
;
662 const int kSingleSize
= Single::kSignificandSize
;
663 const int kSignificandSize
= read_as_double
? kDoubleSize
: kSingleSize
;
665 *result_is_junk
= true;
669 const int radix
= (1 << radix_log_2
);
670 // Whether we have encountered a '.' and are parsing the decimal digits.
671 // Only relevant if parse_as_hex_float is true.
672 bool post_decimal
= false;
675 while (**current
== '0') {
676 if (Advance(current
, separator
, radix
, end
)) {
677 *result_is_junk
= false;
678 return SignedZero(sign
);
684 if (IsDecimalDigitForRadix(**current
, radix
)) {
685 digit
= static_cast<char>(**current
) - '0';
686 if (post_decimal
) exponent
-= radix_log_2
;
687 } else if (IsCharacterDigitForRadix(**current
, radix
, 'a')) {
688 digit
= static_cast<char>(**current
) - 'a' + 10;
689 if (post_decimal
) exponent
-= radix_log_2
;
690 } else if (IsCharacterDigitForRadix(**current
, radix
, 'A')) {
691 digit
= static_cast<char>(**current
) - 'A' + 10;
692 if (post_decimal
) exponent
-= radix_log_2
;
693 } else if (parse_as_hex_float
&& **current
== '.') {
695 Advance(current
, separator
, radix
, end
);
696 ASSERT(*current
!= end
);
698 } else if (parse_as_hex_float
&& (**current
== 'p' || **current
== 'P')) {
701 if (allow_trailing_junk
|| !AdvanceToNonspace(current
, end
)) {
704 return junk_string_value
;
708 number
= number
* radix
+ digit
;
709 int overflow
= static_cast<int>(number
>> kSignificandSize
);
711 // Overflow occurred. Need to determine which direction to round the
713 int overflow_bits_count
= 1;
714 while (overflow
> 1) {
715 overflow_bits_count
++;
719 int dropped_bits_mask
= ((1 << overflow_bits_count
) - 1);
720 int dropped_bits
= static_cast<int>(number
) & dropped_bits_mask
;
721 number
>>= overflow_bits_count
;
722 exponent
+= overflow_bits_count
;
724 bool zero_tail
= true;
726 if (Advance(current
, separator
, radix
, end
)) break;
727 if (parse_as_hex_float
&& **current
== '.') {
728 // Just run over the '.'. We are just trying to see whether there is
729 // a non-zero digit somewhere.
730 Advance(current
, separator
, radix
, end
);
731 ASSERT(*current
!= end
);
734 if (!isDigit(**current
, radix
)) break;
735 zero_tail
= zero_tail
&& **current
== '0';
736 if (!post_decimal
) exponent
+= radix_log_2
;
739 if (!parse_as_hex_float
&&
740 !allow_trailing_junk
&&
741 AdvanceToNonspace(current
, end
)) {
742 return junk_string_value
;
745 int middle_value
= (1 << (overflow_bits_count
- 1));
746 if (dropped_bits
> middle_value
) {
747 number
++; // Rounding up.
748 } else if (dropped_bits
== middle_value
) {
749 // Rounding to even to consistency with decimals: half-way case rounds
750 // up if significant part is odd and down otherwise.
751 if ((number
& 1) != 0 || !zero_tail
) {
752 number
++; // Rounding up.
756 // Rounding up may cause overflow.
757 if ((number
& ((int64_t)1 << kSignificandSize
)) != 0) {
763 if (Advance(current
, separator
, radix
, end
)) break;
766 ASSERT(number
< ((int64_t)1 << kSignificandSize
));
767 ASSERT(static_cast<int64_t>(static_cast<double>(number
)) == number
);
769 *result_is_junk
= false;
771 if (parse_as_hex_float
) {
772 ASSERT(**current
== 'p' || **current
== 'P');
773 Advance(current
, separator
, radix
, end
);
774 ASSERT(*current
!= end
);
775 bool is_negative
= false;
776 if (**current
== '+') {
777 Advance(current
, separator
, radix
, end
);
778 ASSERT(*current
!= end
);
779 } else if (**current
== '-') {
781 Advance(current
, separator
, radix
, end
);
782 ASSERT(*current
!= end
);
784 int written_exponent
= 0;
785 while (IsDecimalDigitForRadix(**current
, 10)) {
786 written_exponent
= 10 * written_exponent
+ **current
- '0';
787 if (Advance(current
, separator
, radix
, end
)) break;
789 if (is_negative
) written_exponent
= -written_exponent
;
790 exponent
+= written_exponent
;
793 if (exponent
== 0 || number
== 0) {
795 if (number
== 0) return -0.0;
798 return static_cast<double>(number
);
802 double result
= Double(DiyFp(number
, exponent
)).value();
803 return sign
? -result
: result
;
806 template <class Iterator
>
807 double StringToDoubleConverter::StringToIeee(
811 int* processed_characters_count
) const {
812 Iterator current
= input
;
813 Iterator end
= input
+ length
;
815 *processed_characters_count
= 0;
817 const bool allow_trailing_junk
= (flags_
& ALLOW_TRAILING_JUNK
) != 0;
818 const bool allow_leading_spaces
= (flags_
& ALLOW_LEADING_SPACES
) != 0;
819 const bool allow_trailing_spaces
= (flags_
& ALLOW_TRAILING_SPACES
) != 0;
820 const bool allow_spaces_after_sign
= (flags_
& ALLOW_SPACES_AFTER_SIGN
) != 0;
821 const bool allow_case_insensibility
= (flags_
& ALLOW_CASE_INSENSIBILITY
) != 0;
823 // To make sure that iterator dereferencing is valid the following
824 // convention is used:
825 // 1. Each '++current' statement is followed by check for equality to 'end'.
826 // 2. If AdvanceToNonspace returned false then current == end.
827 // 3. If 'current' becomes equal to 'end' the function returns or goes to
829 // 4. 'current' is not dereferenced after the 'parsing_done' label.
830 // 5. Code before 'parsing_done' may rely on 'current != end'.
831 if (current
== end
) return empty_string_value_
;
833 if (allow_leading_spaces
|| allow_trailing_spaces
) {
834 if (!AdvanceToNonspace(¤t
, end
)) {
835 *processed_characters_count
= static_cast<int>(current
- input
);
836 return empty_string_value_
;
838 if (!allow_leading_spaces
&& (input
!= current
)) {
839 // No leading spaces allowed, but AdvanceToNonspace moved forward.
840 return junk_string_value_
;
844 // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
845 const int kBufferSize
= kMaxSignificantDigits
+ 10;
846 char buffer
[kBufferSize
]; // NOLINT: size is known at compile time.
849 // Exponent will be adjusted if insignificant digits of the integer part
850 // or insignificant leading zeros of the fractional part are dropped.
852 int significant_digits
= 0;
853 int insignificant_digits
= 0;
854 bool nonzero_digit_dropped
= false;
858 if (*current
== '+' || *current
== '-') {
859 sign
= (*current
== '-');
861 Iterator next_non_space
= current
;
862 // Skip following spaces (if allowed).
863 if (!AdvanceToNonspace(&next_non_space
, end
)) return junk_string_value_
;
864 if (!allow_spaces_after_sign
&& (current
!= next_non_space
)) {
865 return junk_string_value_
;
867 current
= next_non_space
;
870 if (infinity_symbol_
!= NULL
) {
871 if (ConsumeFirstCharacter(*current
, infinity_symbol_
, allow_case_insensibility
)) {
872 if (!ConsumeSubString(¤t
, end
, infinity_symbol_
, allow_case_insensibility
)) {
873 return junk_string_value_
;
876 if (!(allow_trailing_spaces
|| allow_trailing_junk
) && (current
!= end
)) {
877 return junk_string_value_
;
879 if (!allow_trailing_junk
&& AdvanceToNonspace(¤t
, end
)) {
880 return junk_string_value_
;
883 ASSERT(buffer_pos
== 0);
884 *processed_characters_count
= static_cast<int>(current
- input
);
885 return sign
? -Double::Infinity() : Double::Infinity();
889 if (nan_symbol_
!= NULL
) {
890 if (ConsumeFirstCharacter(*current
, nan_symbol_
, allow_case_insensibility
)) {
891 if (!ConsumeSubString(¤t
, end
, nan_symbol_
, allow_case_insensibility
)) {
892 return junk_string_value_
;
895 if (!(allow_trailing_spaces
|| allow_trailing_junk
) && (current
!= end
)) {
896 return junk_string_value_
;
898 if (!allow_trailing_junk
&& AdvanceToNonspace(¤t
, end
)) {
899 return junk_string_value_
;
902 ASSERT(buffer_pos
== 0);
903 *processed_characters_count
= static_cast<int>(current
- input
);
904 return sign
? -Double::NaN() : Double::NaN();
908 bool leading_zero
= false;
909 if (*current
== '0') {
910 if (Advance(¤t
, separator_
, 10, end
)) {
911 *processed_characters_count
= static_cast<int>(current
- input
);
912 return SignedZero(sign
);
917 // It could be hexadecimal value.
918 if (((flags_
& ALLOW_HEX
) || (flags_
& ALLOW_HEX_FLOATS
)) &&
919 (*current
== 'x' || *current
== 'X')) {
922 bool parse_as_hex_float
= (flags_
& ALLOW_HEX_FLOATS
) &&
923 IsHexFloatString(current
, end
, separator_
, allow_trailing_junk
);
925 if (current
== end
) return junk_string_value_
; // "0x"
926 if (!parse_as_hex_float
&& !isDigit(*current
, 16)) {
927 return junk_string_value_
;
931 double result
= RadixStringToIeee
<4>(¤t
,
940 if (!result_is_junk
) {
941 if (allow_trailing_spaces
) AdvanceToNonspace(¤t
, end
);
942 *processed_characters_count
= static_cast<int>(current
- input
);
947 // Ignore leading zeros in the integer part.
948 while (*current
== '0') {
949 if (Advance(¤t
, separator_
, 10, end
)) {
950 *processed_characters_count
= static_cast<int>(current
- input
);
951 return SignedZero(sign
);
956 bool octal
= leading_zero
&& (flags_
& ALLOW_OCTALS
) != 0;
958 // Copy significant digits of the integer part (if any) to the buffer.
959 while (*current
>= '0' && *current
<= '9') {
960 if (significant_digits
< kMaxSignificantDigits
) {
961 ASSERT(buffer_pos
< kBufferSize
);
962 buffer
[buffer_pos
++] = static_cast<char>(*current
);
963 significant_digits
++;
964 // Will later check if it's an octal in the buffer.
966 insignificant_digits
++; // Move the digit into the exponential part.
967 nonzero_digit_dropped
= nonzero_digit_dropped
|| *current
!= '0';
969 octal
= octal
&& *current
< '8';
970 if (Advance(¤t
, separator_
, 10, end
)) goto parsing_done
;
973 if (significant_digits
== 0) {
977 if (*current
== '.') {
978 if (octal
&& !allow_trailing_junk
) return junk_string_value_
;
979 if (octal
) goto parsing_done
;
981 if (Advance(¤t
, separator_
, 10, end
)) {
982 if (significant_digits
== 0 && !leading_zero
) {
983 return junk_string_value_
;
989 if (significant_digits
== 0) {
991 // Integer part consists of 0 or is absent. Significant digits start after
992 // leading zeros (if any).
993 while (*current
== '0') {
994 if (Advance(¤t
, separator_
, 10, end
)) {
995 *processed_characters_count
= static_cast<int>(current
- input
);
996 return SignedZero(sign
);
998 exponent
--; // Move this 0 into the exponent.
1002 // There is a fractional part.
1003 // We don't emit a '.', but adjust the exponent instead.
1004 while (*current
>= '0' && *current
<= '9') {
1005 if (significant_digits
< kMaxSignificantDigits
) {
1006 ASSERT(buffer_pos
< kBufferSize
);
1007 buffer
[buffer_pos
++] = static_cast<char>(*current
);
1008 significant_digits
++;
1011 // Ignore insignificant digits in the fractional part.
1012 nonzero_digit_dropped
= nonzero_digit_dropped
|| *current
!= '0';
1014 if (Advance(¤t
, separator_
, 10, end
)) goto parsing_done
;
1018 if (!leading_zero
&& exponent
== 0 && significant_digits
== 0) {
1019 // If leading_zeros is true then the string contains zeros.
1020 // If exponent < 0 then string was [+-]\.0*...
1021 // If significant_digits != 0 the string is not equal to 0.
1022 // Otherwise there are no digits in the string.
1023 return junk_string_value_
;
1026 // Parse exponential part.
1027 if (*current
== 'e' || *current
== 'E') {
1028 if (octal
&& !allow_trailing_junk
) return junk_string_value_
;
1029 if (octal
) goto parsing_done
;
1030 Iterator junk_begin
= current
;
1032 if (current
== end
) {
1033 if (allow_trailing_junk
) {
1034 current
= junk_begin
;
1037 return junk_string_value_
;
1040 char exponen_sign
= '+';
1041 if (*current
== '+' || *current
== '-') {
1042 exponen_sign
= static_cast<char>(*current
);
1044 if (current
== end
) {
1045 if (allow_trailing_junk
) {
1046 current
= junk_begin
;
1049 return junk_string_value_
;
1054 if (current
== end
|| *current
< '0' || *current
> '9') {
1055 if (allow_trailing_junk
) {
1056 current
= junk_begin
;
1059 return junk_string_value_
;
1063 const int max_exponent
= INT_MAX
/ 2;
1064 ASSERT(-max_exponent
/ 2 <= exponent
&& exponent
<= max_exponent
/ 2);
1068 int digit
= *current
- '0';
1069 if (num
>= max_exponent
/ 10
1070 && !(num
== max_exponent
/ 10 && digit
<= max_exponent
% 10)) {
1073 num
= num
* 10 + digit
;
1076 } while (current
!= end
&& *current
>= '0' && *current
<= '9');
1078 exponent
+= (exponen_sign
== '-' ? -num
: num
);
1081 if (!(allow_trailing_spaces
|| allow_trailing_junk
) && (current
!= end
)) {
1082 return junk_string_value_
;
1084 if (!allow_trailing_junk
&& AdvanceToNonspace(¤t
, end
)) {
1085 return junk_string_value_
;
1087 if (allow_trailing_spaces
) {
1088 AdvanceToNonspace(¤t
, end
);
1092 exponent
+= insignificant_digits
;
1096 bool result_is_junk
;
1097 char* start
= buffer
;
1098 result
= RadixStringToIeee
<3>(&start
,
1099 buffer
+ buffer_pos
,
1102 false, // Don't parse as hex_float.
1103 allow_trailing_junk
,
1107 ASSERT(!result_is_junk
);
1108 *processed_characters_count
= static_cast<int>(current
- input
);
1112 if (nonzero_digit_dropped
) {
1113 buffer
[buffer_pos
++] = '1';
1117 ASSERT(buffer_pos
< kBufferSize
);
1118 buffer
[buffer_pos
] = '\0';
1121 if (read_as_double
) {
1122 converted
= Strtod(Vector
<const char>(buffer
, buffer_pos
), exponent
);
1124 converted
= Strtof(Vector
<const char>(buffer
, buffer_pos
), exponent
);
1126 *processed_characters_count
= static_cast<int>(current
- input
);
1127 return sign
? -converted
: converted
;
1131 double StringToDoubleConverter::StringToDouble(
1134 int* processed_characters_count
) const {
1135 return StringToIeee(buffer
, length
, true, processed_characters_count
);
1139 double StringToDoubleConverter::StringToDouble(
1142 int* processed_characters_count
) const {
1143 return StringToIeee(buffer
, length
, true, processed_characters_count
);
1147 float StringToDoubleConverter::StringToFloat(
1150 int* processed_characters_count
) const {
1151 return static_cast<float>(StringToIeee(buffer
, length
, false,
1152 processed_characters_count
));
1156 float StringToDoubleConverter::StringToFloat(
1159 int* processed_characters_count
) const {
1160 return static_cast<float>(StringToIeee(buffer
, length
, false,
1161 processed_characters_count
));
1164 } // namespace double_conversion
1166 // ICU PATCH: Close ICU namespace
1168 #endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING