]> git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/double-conversion.cpp
ICU-64243.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / double-conversion.cpp
1 // © 2018 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 //
4 // From the double-conversion library. Original license:
5 //
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
9 // met:
10 //
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.
20 //
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.
32
33 // ICU PATCH: ifdef around UCONFIG_NO_FORMATTING
34 #include "unicode/utypes.h"
35 #if !UCONFIG_NO_FORMATTING
36
37 // ICU PATCH: Do not include std::locale.
38
39 #include <climits>
40 //#include <locale>
41 #include <cmath>
42
43 // ICU PATCH: Customize header file paths for ICU.
44 // The file fixed-dtoa.h is not needed.
45
46 #include "double-conversion.h"
47
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"
53
54 // ICU PATCH: Wrap in ICU namespace
55 U_NAMESPACE_BEGIN
56
57 namespace double_conversion {
58
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,
63 "Infinity",
64 "NaN",
65 'e',
66 -6, 21,
67 6, 0);
68 return converter;
69 }
70
71
72 bool DoubleToStringConverter::HandleSpecialValues(
73 double value,
74 StringBuilder* result_builder) const {
75 Double double_inspect(value);
76 if (double_inspect.IsInfinite()) {
77 if (infinity_symbol_ == NULL) return false;
78 if (value < 0) {
79 result_builder->AddCharacter('-');
80 }
81 result_builder->AddString(infinity_symbol_);
82 return true;
83 }
84 if (double_inspect.IsNan()) {
85 if (nan_symbol_ == NULL) return false;
86 result_builder->AddString(nan_symbol_);
87 return true;
88 }
89 return false;
90 }
91
92
93 void DoubleToStringConverter::CreateExponentialRepresentation(
94 const char* decimal_digits,
95 int length,
96 int exponent,
97 StringBuilder* result_builder) const {
98 ASSERT(length != 0);
99 result_builder->AddCharacter(decimal_digits[0]);
100 if (length != 1) {
101 result_builder->AddCharacter('.');
102 result_builder->AddSubstring(&decimal_digits[1], length-1);
103 }
104 result_builder->AddCharacter(exponent_character_);
105 if (exponent < 0) {
106 result_builder->AddCharacter('-');
107 exponent = -exponent;
108 } else {
109 if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
110 result_builder->AddCharacter('+');
111 }
112 }
113 if (exponent == 0) {
114 result_builder->AddCharacter('0');
115 return;
116 }
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);
124 exponent /= 10;
125 }
126 result_builder->AddSubstring(&buffer[first_char_pos],
127 kMaxExponentLength - first_char_pos);
128 }
129
130
131 void DoubleToStringConverter::CreateDecimalRepresentation(
132 const char* decimal_digits,
133 int length,
134 int decimal_point,
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);
148 }
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);
156 }
157 } else {
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);
167 }
168 if (digits_after_point == 0) {
169 if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
170 result_builder->AddCharacter('.');
171 }
172 if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
173 result_builder->AddCharacter('0');
174 }
175 }
176 }
177
178
179 bool DoubleToStringConverter::ToShortestIeeeNumber(
180 double value,
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);
186 }
187
188 int decimal_point;
189 bool sign;
190 const int kDecimalRepCapacity = kBase10MaximalLength + 1;
191 char decimal_rep[kDecimalRepCapacity];
192 int decimal_rep_length;
193
194 DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity,
195 &sign, &decimal_rep_length, &decimal_point);
196
197 bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
198 if (sign && (value != 0.0 || !unique_zero)) {
199 result_builder->AddCharacter('-');
200 }
201
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,
206 decimal_point,
207 Max(0, decimal_rep_length - decimal_point),
208 result_builder);
209 } else {
210 CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
211 result_builder);
212 }
213 return true;
214 }
215
216
217 bool DoubleToStringConverter::ToFixed(double value,
218 int requested_digits,
219 StringBuilder* result_builder) const {
220 ASSERT(kMaxFixedDigitsBeforePoint == 60);
221 const double kFirstNonFixed = 1e60;
222
223 if (Double(value).IsSpecial()) {
224 return HandleSpecialValues(value, result_builder);
225 }
226
227 if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
228 if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
229
230 // Find a sufficiently precise decimal representation of n.
231 int decimal_point;
232 bool sign;
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);
241
242 bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
243 if (sign && (value != 0.0 || !unique_zero)) {
244 result_builder->AddCharacter('-');
245 }
246
247 CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
248 requested_digits, result_builder);
249 return true;
250 }
251
252
253 bool DoubleToStringConverter::ToExponential(
254 double value,
255 int requested_digits,
256 StringBuilder* result_builder) const {
257 if (Double(value).IsSpecial()) {
258 return HandleSpecialValues(value, result_builder);
259 }
260
261 if (requested_digits < -1) return false;
262 if (requested_digits > kMaxExponentialDigits) return false;
263
264 int decimal_point;
265 bool sign;
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;
271
272 if (requested_digits == -1) {
273 DoubleToAscii(value, SHORTEST, 0,
274 decimal_rep, kDecimalRepCapacity,
275 &sign, &decimal_rep_length, &decimal_point);
276 } else {
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);
281
282 for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
283 decimal_rep[i] = '0';
284 }
285 decimal_rep_length = requested_digits + 1;
286 }
287
288 bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
289 if (sign && (value != 0.0 || !unique_zero)) {
290 result_builder->AddCharacter('-');
291 }
292
293 int exponent = decimal_point - 1;
294 CreateExponentialRepresentation(decimal_rep,
295 decimal_rep_length,
296 exponent,
297 result_builder);
298 return true;
299 }
300
301
302 bool DoubleToStringConverter::ToPrecision(double value,
303 int precision,
304 StringBuilder* result_builder) const {
305 if (Double(value).IsSpecial()) {
306 return HandleSpecialValues(value, result_builder);
307 }
308
309 if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
310 return false;
311 }
312
313 // Find a sufficiently precise decimal representation of n.
314 int decimal_point;
315 bool sign;
316 // Add one for the terminating null character.
317 const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
318 char decimal_rep[kDecimalRepCapacity];
319 int decimal_rep_length;
320
321 DoubleToAscii(value, PRECISION, precision,
322 decimal_rep, kDecimalRepCapacity,
323 &sign, &decimal_rep_length, &decimal_point);
324 ASSERT(decimal_rep_length <= precision);
325
326 bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
327 if (sign && (value != 0.0 || !unique_zero)) {
328 result_builder->AddCharacter('-');
329 }
330
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;
334
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';
344 }
345
346 CreateExponentialRepresentation(decimal_rep,
347 precision,
348 exponent,
349 result_builder);
350 } else {
351 CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
352 Max(0, precision - decimal_point),
353 result_builder);
354 }
355 return true;
356 }
357 #endif // not needed for ICU
358
359
360 static BignumDtoaMode DtoaToBignumDtoaMode(
361 DoubleToStringConverter::DtoaMode dtoa_mode) {
362 switch (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;
368 default:
369 UNREACHABLE();
370 }
371 }
372
373
374 void DoubleToStringConverter::DoubleToAscii(double v,
375 DtoaMode mode,
376 int requested_digits,
377 char* buffer,
378 int buffer_length,
379 bool* sign,
380 int* length,
381 int* point) {
382 Vector<char> vector(buffer, buffer_length);
383 ASSERT(!Double(v).IsSpecial());
384 ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0);
385
386 if (Double(v).Sign() < 0) {
387 *sign = true;
388 v = -v;
389 } else {
390 *sign = false;
391 }
392
393 if (mode == PRECISION && requested_digits == 0) {
394 vector[0] = '\0';
395 *length = 0;
396 return;
397 }
398
399 if (v == 0) {
400 vector[0] = '0';
401 vector[1] = '\0';
402 *length = 1;
403 *point = 1;
404 return;
405 }
406
407 bool fast_worked;
408 switch (mode) {
409 case SHORTEST:
410 fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
411 break;
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);
416 break;
417 case FIXED:
418 fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
419 break;
420 case PRECISION:
421 fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
422 vector, length, point);
423 break;
424 #endif // not needed for ICU
425 default:
426 fast_worked = false;
427 UNREACHABLE();
428 }
429 if (fast_worked) return;
430
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';
435 }
436
437
438 namespace {
439
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);
445 #else
446 (void)ch;
447 UNREACHABLE();
448 #endif
449 }
450
451 inline char Pass(char ch) {
452 return ch;
453 }
454
455 template <class Iterator, class Converter>
456 static inline bool ConsumeSubStringImpl(Iterator* current,
457 Iterator end,
458 const char* substring,
459 Converter converter) {
460 ASSERT(converter(**current) == *substring);
461 for (substring++; *substring != '\0'; substring++) {
462 ++*current;
463 if (*current == end || converter(**current) != *substring) {
464 return false;
465 }
466 }
467 ++*current;
468 return true;
469 }
470
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,
475 Iterator end,
476 const char* substring,
477 bool allow_case_insensibility) {
478 if (allow_case_insensibility) {
479 return ConsumeSubStringImpl(current, end, substring, ToLower);
480 } else {
481 return ConsumeSubStringImpl(current, end, substring, Pass);
482 }
483 }
484
485 // Consumes first character of the str is equal to ch
486 inline bool ConsumeFirstCharacter(char ch,
487 const char* str,
488 bool case_insensibility) {
489 return case_insensibility ? ToLower(ch) == str[0] : ch == str[0];
490 }
491 } // namespace
492
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;
501
502
503 static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 };
504 static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7);
505
506
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
510 };
511 static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16);
512
513
514
515 static bool isWhitespace(int x) {
516 if (x < 128) {
517 for (int i = 0; i < kWhitespaceTable7Length; i++) {
518 if (kWhitespaceTable7[i] == x) return true;
519 }
520 } else {
521 for (int i = 0; i < kWhitespaceTable16Length; i++) {
522 if (kWhitespaceTable16[i] == x) return true;
523 }
524 }
525 return false;
526 }
527
528
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;
534 ++*current;
535 }
536 return false;
537 }
538
539
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);
544 }
545
546
547 static double SignedZero(bool sign) {
548 return sign ? -0.0 : 0.0;
549 }
550
551
552 // Returns true if 'c' is a decimal digit that is valid for the given radix.
553 //
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.
558 #ifdef _MSC_VER
559 #pragma optimize("",off)
560 static bool IsDecimalDigitForRadix(int c, int radix) {
561 return '0' <= c && c <= '9' && (c - '0') < radix;
562 }
563 #pragma optimize("",on)
564 #else
565 static bool inline IsDecimalDigitForRadix(int c, int radix) {
566 return '0' <= c && c <= '9' && (c - '0') < radix;
567 }
568 #endif
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'.
571 //
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;
578 }
579
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) {
584 ++(*it);
585 return *it == end;
586 }
587 if (!isDigit(**it, base)) {
588 ++(*it);
589 return *it == end;
590 }
591 ++(*it);
592 if (*it == end) return true;
593 if (*it + 1 == end) return false;
594 if (**it == separator && isDigit(*(*it + 1), base)) {
595 ++(*it);
596 }
597 return *it == end;
598 }
599
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.
602 //
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,
609 Iterator end,
610 uc16 separator,
611 bool allow_trailing_junk) {
612 ASSERT(start != end);
613
614 Iterator current = start;
615
616 bool saw_digit = false;
617 while (isDigit(*current, 16)) {
618 saw_digit = true;
619 if (Advance(&current, separator, 16, end)) return false;
620 }
621 if (*current == '.') {
622 if (Advance(&current, separator, 16, end)) return false;
623 while (isDigit(*current, 16)) {
624 saw_digit = true;
625 if (Advance(&current, separator, 16, end)) return false;
626 }
627 if (!saw_digit) return false; // Only the '.', but no digits.
628 }
629 if (*current != 'p' && *current != 'P') return false;
630 if (Advance(&current, separator, 16, end)) return false;
631 if (*current == '+' || *current == '-') {
632 if (Advance(&current, separator, 16, end)) return false;
633 }
634 if (!isDigit(*current, 10)) return false;
635 if (Advance(&current, separator, 16, end)) return true;
636 while (isDigit(*current, 10)) {
637 if (Advance(&current, separator, 16, end)) return true;
638 }
639 return allow_trailing_junk || !AdvanceToNonspace(&current, end);
640 }
641
642
643 // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
644 //
645 // If parse_as_hex_float is true, then the string must be a valid
646 // hex-float.
647 template <int radix_log_2, class Iterator>
648 static double RadixStringToIeee(Iterator* current,
649 Iterator end,
650 bool sign,
651 uc16 separator,
652 bool parse_as_hex_float,
653 bool allow_trailing_junk,
654 double junk_string_value,
655 bool read_as_double,
656 bool* result_is_junk) {
657 ASSERT(*current != end);
658 ASSERT(!parse_as_hex_float ||
659 IsHexFloatString(*current, end, separator, allow_trailing_junk));
660
661 const int kDoubleSize = Double::kSignificandSize;
662 const int kSingleSize = Single::kSignificandSize;
663 const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
664
665 *result_is_junk = true;
666
667 int64_t number = 0;
668 int exponent = 0;
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;
673
674 // Skip leading 0s.
675 while (**current == '0') {
676 if (Advance(current, separator, radix, end)) {
677 *result_is_junk = false;
678 return SignedZero(sign);
679 }
680 }
681
682 while (true) {
683 int digit;
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 == '.') {
694 post_decimal = true;
695 Advance(current, separator, radix, end);
696 ASSERT(*current != end);
697 continue;
698 } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) {
699 break;
700 } else {
701 if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
702 break;
703 } else {
704 return junk_string_value;
705 }
706 }
707
708 number = number * radix + digit;
709 int overflow = static_cast<int>(number >> kSignificandSize);
710 if (overflow != 0) {
711 // Overflow occurred. Need to determine which direction to round the
712 // result.
713 int overflow_bits_count = 1;
714 while (overflow > 1) {
715 overflow_bits_count++;
716 overflow >>= 1;
717 }
718
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;
723
724 bool zero_tail = true;
725 for (;;) {
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);
732 post_decimal = true;
733 }
734 if (!isDigit(**current, radix)) break;
735 zero_tail = zero_tail && **current == '0';
736 if (!post_decimal) exponent += radix_log_2;
737 }
738
739 if (!parse_as_hex_float &&
740 !allow_trailing_junk &&
741 AdvanceToNonspace(current, end)) {
742 return junk_string_value;
743 }
744
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.
753 }
754 }
755
756 // Rounding up may cause overflow.
757 if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
758 exponent++;
759 number >>= 1;
760 }
761 break;
762 }
763 if (Advance(current, separator, radix, end)) break;
764 }
765
766 ASSERT(number < ((int64_t)1 << kSignificandSize));
767 ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
768
769 *result_is_junk = false;
770
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 == '-') {
780 is_negative = true;
781 Advance(current, separator, radix, end);
782 ASSERT(*current != end);
783 }
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;
788 }
789 if (is_negative) written_exponent = -written_exponent;
790 exponent += written_exponent;
791 }
792
793 if (exponent == 0 || number == 0) {
794 if (sign) {
795 if (number == 0) return -0.0;
796 number = -number;
797 }
798 return static_cast<double>(number);
799 }
800
801 ASSERT(number != 0);
802 double result = Double(DiyFp(number, exponent)).value();
803 return sign ? -result : result;
804 }
805
806 template <class Iterator>
807 double StringToDoubleConverter::StringToIeee(
808 Iterator input,
809 int length,
810 bool read_as_double,
811 int* processed_characters_count) const {
812 Iterator current = input;
813 Iterator end = input + length;
814
815 *processed_characters_count = 0;
816
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;
822
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
828 // 'parsing_done'.
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_;
832
833 if (allow_leading_spaces || allow_trailing_spaces) {
834 if (!AdvanceToNonspace(&current, end)) {
835 *processed_characters_count = static_cast<int>(current - input);
836 return empty_string_value_;
837 }
838 if (!allow_leading_spaces && (input != current)) {
839 // No leading spaces allowed, but AdvanceToNonspace moved forward.
840 return junk_string_value_;
841 }
842 }
843
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.
847 int buffer_pos = 0;
848
849 // Exponent will be adjusted if insignificant digits of the integer part
850 // or insignificant leading zeros of the fractional part are dropped.
851 int exponent = 0;
852 int significant_digits = 0;
853 int insignificant_digits = 0;
854 bool nonzero_digit_dropped = false;
855
856 bool sign = false;
857
858 if (*current == '+' || *current == '-') {
859 sign = (*current == '-');
860 ++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_;
866 }
867 current = next_non_space;
868 }
869
870 if (infinity_symbol_ != NULL) {
871 if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensibility)) {
872 if (!ConsumeSubString(&current, end, infinity_symbol_, allow_case_insensibility)) {
873 return junk_string_value_;
874 }
875
876 if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
877 return junk_string_value_;
878 }
879 if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
880 return junk_string_value_;
881 }
882
883 ASSERT(buffer_pos == 0);
884 *processed_characters_count = static_cast<int>(current - input);
885 return sign ? -Double::Infinity() : Double::Infinity();
886 }
887 }
888
889 if (nan_symbol_ != NULL) {
890 if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensibility)) {
891 if (!ConsumeSubString(&current, end, nan_symbol_, allow_case_insensibility)) {
892 return junk_string_value_;
893 }
894
895 if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
896 return junk_string_value_;
897 }
898 if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
899 return junk_string_value_;
900 }
901
902 ASSERT(buffer_pos == 0);
903 *processed_characters_count = static_cast<int>(current - input);
904 return sign ? -Double::NaN() : Double::NaN();
905 }
906 }
907
908 bool leading_zero = false;
909 if (*current == '0') {
910 if (Advance(&current, separator_, 10, end)) {
911 *processed_characters_count = static_cast<int>(current - input);
912 return SignedZero(sign);
913 }
914
915 leading_zero = true;
916
917 // It could be hexadecimal value.
918 if (((flags_ & ALLOW_HEX) || (flags_ & ALLOW_HEX_FLOATS)) &&
919 (*current == 'x' || *current == 'X')) {
920 ++current;
921
922 bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
923 IsHexFloatString(current, end, separator_, allow_trailing_junk);
924
925 if (current == end) return junk_string_value_; // "0x"
926 if (!parse_as_hex_float && !isDigit(*current, 16)) {
927 return junk_string_value_;
928 }
929
930 bool result_is_junk;
931 double result = RadixStringToIeee<4>(&current,
932 end,
933 sign,
934 separator_,
935 parse_as_hex_float,
936 allow_trailing_junk,
937 junk_string_value_,
938 read_as_double,
939 &result_is_junk);
940 if (!result_is_junk) {
941 if (allow_trailing_spaces) AdvanceToNonspace(&current, end);
942 *processed_characters_count = static_cast<int>(current - input);
943 }
944 return result;
945 }
946
947 // Ignore leading zeros in the integer part.
948 while (*current == '0') {
949 if (Advance(&current, separator_, 10, end)) {
950 *processed_characters_count = static_cast<int>(current - input);
951 return SignedZero(sign);
952 }
953 }
954 }
955
956 bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
957
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.
965 } else {
966 insignificant_digits++; // Move the digit into the exponential part.
967 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
968 }
969 octal = octal && *current < '8';
970 if (Advance(&current, separator_, 10, end)) goto parsing_done;
971 }
972
973 if (significant_digits == 0) {
974 octal = false;
975 }
976
977 if (*current == '.') {
978 if (octal && !allow_trailing_junk) return junk_string_value_;
979 if (octal) goto parsing_done;
980
981 if (Advance(&current, separator_, 10, end)) {
982 if (significant_digits == 0 && !leading_zero) {
983 return junk_string_value_;
984 } else {
985 goto parsing_done;
986 }
987 }
988
989 if (significant_digits == 0) {
990 // octal = false;
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(&current, separator_, 10, end)) {
995 *processed_characters_count = static_cast<int>(current - input);
996 return SignedZero(sign);
997 }
998 exponent--; // Move this 0 into the exponent.
999 }
1000 }
1001
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++;
1009 exponent--;
1010 } else {
1011 // Ignore insignificant digits in the fractional part.
1012 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
1013 }
1014 if (Advance(&current, separator_, 10, end)) goto parsing_done;
1015 }
1016 }
1017
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_;
1024 }
1025
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;
1031 ++current;
1032 if (current == end) {
1033 if (allow_trailing_junk) {
1034 current = junk_begin;
1035 goto parsing_done;
1036 } else {
1037 return junk_string_value_;
1038 }
1039 }
1040 char exponen_sign = '+';
1041 if (*current == '+' || *current == '-') {
1042 exponen_sign = static_cast<char>(*current);
1043 ++current;
1044 if (current == end) {
1045 if (allow_trailing_junk) {
1046 current = junk_begin;
1047 goto parsing_done;
1048 } else {
1049 return junk_string_value_;
1050 }
1051 }
1052 }
1053
1054 if (current == end || *current < '0' || *current > '9') {
1055 if (allow_trailing_junk) {
1056 current = junk_begin;
1057 goto parsing_done;
1058 } else {
1059 return junk_string_value_;
1060 }
1061 }
1062
1063 const int max_exponent = INT_MAX / 2;
1064 ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
1065 int num = 0;
1066 do {
1067 // Check overflow.
1068 int digit = *current - '0';
1069 if (num >= max_exponent / 10
1070 && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
1071 num = max_exponent;
1072 } else {
1073 num = num * 10 + digit;
1074 }
1075 ++current;
1076 } while (current != end && *current >= '0' && *current <= '9');
1077
1078 exponent += (exponen_sign == '-' ? -num : num);
1079 }
1080
1081 if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
1082 return junk_string_value_;
1083 }
1084 if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
1085 return junk_string_value_;
1086 }
1087 if (allow_trailing_spaces) {
1088 AdvanceToNonspace(&current, end);
1089 }
1090
1091 parsing_done:
1092 exponent += insignificant_digits;
1093
1094 if (octal) {
1095 double result;
1096 bool result_is_junk;
1097 char* start = buffer;
1098 result = RadixStringToIeee<3>(&start,
1099 buffer + buffer_pos,
1100 sign,
1101 separator_,
1102 false, // Don't parse as hex_float.
1103 allow_trailing_junk,
1104 junk_string_value_,
1105 read_as_double,
1106 &result_is_junk);
1107 ASSERT(!result_is_junk);
1108 *processed_characters_count = static_cast<int>(current - input);
1109 return result;
1110 }
1111
1112 if (nonzero_digit_dropped) {
1113 buffer[buffer_pos++] = '1';
1114 exponent--;
1115 }
1116
1117 ASSERT(buffer_pos < kBufferSize);
1118 buffer[buffer_pos] = '\0';
1119
1120 double converted;
1121 if (read_as_double) {
1122 converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
1123 } else {
1124 converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
1125 }
1126 *processed_characters_count = static_cast<int>(current - input);
1127 return sign? -converted: converted;
1128 }
1129
1130
1131 double StringToDoubleConverter::StringToDouble(
1132 const char* buffer,
1133 int length,
1134 int* processed_characters_count) const {
1135 return StringToIeee(buffer, length, true, processed_characters_count);
1136 }
1137
1138
1139 double StringToDoubleConverter::StringToDouble(
1140 const uc16* buffer,
1141 int length,
1142 int* processed_characters_count) const {
1143 return StringToIeee(buffer, length, true, processed_characters_count);
1144 }
1145
1146
1147 float StringToDoubleConverter::StringToFloat(
1148 const char* buffer,
1149 int length,
1150 int* processed_characters_count) const {
1151 return static_cast<float>(StringToIeee(buffer, length, false,
1152 processed_characters_count));
1153 }
1154
1155
1156 float StringToDoubleConverter::StringToFloat(
1157 const uc16* buffer,
1158 int length,
1159 int* processed_characters_count) const {
1160 return static_cast<float>(StringToIeee(buffer, length, false,
1161 processed_characters_count));
1162 }
1163
1164 } // namespace double_conversion
1165
1166 // ICU PATCH: Close ICU namespace
1167 U_NAMESPACE_END
1168 #endif // ICU PATCH: close #if !UCONFIG_NO_FORMATTING