You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

982 regels
32 KiB

  1. // Copyright 2010 the V8 project authors. All rights reserved.
  2. // Redistribution and use in source and binary forms, with or without
  3. // modification, are permitted provided that the following conditions are
  4. // met:
  5. //
  6. // * Redistributions of source code must retain the above copyright
  7. // notice, this list of conditions and the following disclaimer.
  8. // * Redistributions in binary form must reproduce the above
  9. // copyright notice, this list of conditions and the following
  10. // disclaimer in the documentation and/or other materials provided
  11. // with the distribution.
  12. // * Neither the name of Google Inc. nor the names of its
  13. // contributors may be used to endorse or promote products derived
  14. // from this software without specific prior written permission.
  15. //
  16. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  17. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  18. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  19. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  20. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  21. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  22. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  26. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. #include <limits.h>
  28. #include <math.h>
  29. #include "double-conversion/double-conversion.h"
  30. #include "double-conversion/bignum-dtoa.h"
  31. #include "double-conversion/fast-dtoa.h"
  32. #include "double-conversion/fixed-dtoa.h"
  33. #include "double-conversion/ieee.h"
  34. #include "double-conversion/strtod.h"
  35. #include "double-conversion/utils.h"
  36. namespace double_conversion {
  37. const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
  38. int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
  39. static DoubleToStringConverter converter(flags,
  40. "Infinity",
  41. "NaN",
  42. 'e',
  43. -6, 21,
  44. 6, 0);
  45. return converter;
  46. }
  47. bool DoubleToStringConverter::HandleSpecialValues(
  48. double value,
  49. StringBuilder* result_builder) const {
  50. Double double_inspect(value);
  51. if (double_inspect.IsInfinite()) {
  52. if (infinity_symbol_ == NULL) return false;
  53. if (value < 0) {
  54. result_builder->AddCharacter('-');
  55. }
  56. result_builder->AddString(infinity_symbol_);
  57. return true;
  58. }
  59. if (double_inspect.IsNan()) {
  60. if (nan_symbol_ == NULL) return false;
  61. result_builder->AddString(nan_symbol_);
  62. return true;
  63. }
  64. return false;
  65. }
  66. void DoubleToStringConverter::CreateExponentialRepresentation(
  67. const char* decimal_digits,
  68. int length,
  69. int exponent,
  70. StringBuilder* result_builder) const {
  71. ASSERT(length != 0);
  72. result_builder->AddCharacter(decimal_digits[0]);
  73. if (length != 1) {
  74. result_builder->AddCharacter('.');
  75. result_builder->AddSubstring(&decimal_digits[1], length-1);
  76. }
  77. result_builder->AddCharacter(exponent_character_);
  78. if (exponent < 0) {
  79. result_builder->AddCharacter('-');
  80. exponent = -exponent;
  81. } else {
  82. if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
  83. result_builder->AddCharacter('+');
  84. }
  85. }
  86. if (exponent == 0) {
  87. result_builder->AddCharacter('0');
  88. return;
  89. }
  90. ASSERT(exponent < 1e4);
  91. const int kMaxExponentLength = 5;
  92. char buffer[kMaxExponentLength + 1];
  93. buffer[kMaxExponentLength] = '\0';
  94. int first_char_pos = kMaxExponentLength;
  95. while (exponent > 0) {
  96. buffer[--first_char_pos] = '0' + (exponent % 10);
  97. exponent /= 10;
  98. }
  99. result_builder->AddSubstring(&buffer[first_char_pos],
  100. kMaxExponentLength - first_char_pos);
  101. }
  102. void DoubleToStringConverter::CreateDecimalRepresentation(
  103. const char* decimal_digits,
  104. int length,
  105. int decimal_point,
  106. int digits_after_point,
  107. StringBuilder* result_builder) const {
  108. // Create a representation that is padded with zeros if needed.
  109. if (decimal_point <= 0) {
  110. // "0.00000decimal_rep".
  111. result_builder->AddCharacter('0');
  112. if (digits_after_point > 0) {
  113. result_builder->AddCharacter('.');
  114. result_builder->AddPadding('0', -decimal_point);
  115. ASSERT(length <= digits_after_point - (-decimal_point));
  116. result_builder->AddSubstring(decimal_digits, length);
  117. int remaining_digits = digits_after_point - (-decimal_point) - length;
  118. result_builder->AddPadding('0', remaining_digits);
  119. }
  120. } else if (decimal_point >= length) {
  121. // "decimal_rep0000.00000" or "decimal_rep.0000"
  122. result_builder->AddSubstring(decimal_digits, length);
  123. result_builder->AddPadding('0', decimal_point - length);
  124. if (digits_after_point > 0) {
  125. result_builder->AddCharacter('.');
  126. result_builder->AddPadding('0', digits_after_point);
  127. }
  128. } else {
  129. // "decima.l_rep000"
  130. ASSERT(digits_after_point > 0);
  131. result_builder->AddSubstring(decimal_digits, decimal_point);
  132. result_builder->AddCharacter('.');
  133. ASSERT(length - decimal_point <= digits_after_point);
  134. result_builder->AddSubstring(&decimal_digits[decimal_point],
  135. length - decimal_point);
  136. int remaining_digits = digits_after_point - (length - decimal_point);
  137. result_builder->AddPadding('0', remaining_digits);
  138. }
  139. if (digits_after_point == 0) {
  140. if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
  141. result_builder->AddCharacter('.');
  142. }
  143. if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
  144. result_builder->AddCharacter('0');
  145. }
  146. }
  147. }
  148. bool DoubleToStringConverter::ToShortestIeeeNumber(
  149. double value,
  150. StringBuilder* result_builder,
  151. DoubleToStringConverter::DtoaMode mode) const {
  152. ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE);
  153. if (Double(value).IsSpecial()) {
  154. return HandleSpecialValues(value, result_builder);
  155. }
  156. int decimal_point;
  157. bool sign;
  158. const int kDecimalRepCapacity = kBase10MaximalLength + 1;
  159. char decimal_rep[kDecimalRepCapacity];
  160. int decimal_rep_length;
  161. DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity,
  162. &sign, &decimal_rep_length, &decimal_point);
  163. bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
  164. if (sign && (value != 0.0 || !unique_zero)) {
  165. result_builder->AddCharacter('-');
  166. }
  167. int exponent = decimal_point - 1;
  168. if ((decimal_in_shortest_low_ <= exponent) &&
  169. (exponent < decimal_in_shortest_high_)) {
  170. CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
  171. decimal_point,
  172. Max(0, decimal_rep_length - decimal_point),
  173. result_builder);
  174. } else {
  175. CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
  176. result_builder);
  177. }
  178. return true;
  179. }
  180. bool DoubleToStringConverter::ToFixed(double value,
  181. int requested_digits,
  182. StringBuilder* result_builder) const {
  183. ASSERT(kMaxFixedDigitsBeforePoint == 60);
  184. const double kFirstNonFixed = 1e60;
  185. if (Double(value).IsSpecial()) {
  186. return HandleSpecialValues(value, result_builder);
  187. }
  188. if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
  189. if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
  190. // Find a sufficiently precise decimal representation of n.
  191. int decimal_point;
  192. bool sign;
  193. // Add space for the '\0' byte.
  194. const int kDecimalRepCapacity =
  195. kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
  196. char decimal_rep[kDecimalRepCapacity];
  197. int decimal_rep_length;
  198. DoubleToAscii(value, FIXED, requested_digits,
  199. decimal_rep, kDecimalRepCapacity,
  200. &sign, &decimal_rep_length, &decimal_point);
  201. bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
  202. if (sign && (value != 0.0 || !unique_zero)) {
  203. result_builder->AddCharacter('-');
  204. }
  205. CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
  206. requested_digits, result_builder);
  207. return true;
  208. }
  209. bool DoubleToStringConverter::ToExponential(
  210. double value,
  211. int requested_digits,
  212. StringBuilder* result_builder) const {
  213. if (Double(value).IsSpecial()) {
  214. return HandleSpecialValues(value, result_builder);
  215. }
  216. if (requested_digits < -1) return false;
  217. if (requested_digits > kMaxExponentialDigits) return false;
  218. int decimal_point;
  219. bool sign;
  220. // Add space for digit before the decimal point and the '\0' character.
  221. const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
  222. ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
  223. char decimal_rep[kDecimalRepCapacity];
  224. int decimal_rep_length;
  225. if (requested_digits == -1) {
  226. DoubleToAscii(value, SHORTEST, 0,
  227. decimal_rep, kDecimalRepCapacity,
  228. &sign, &decimal_rep_length, &decimal_point);
  229. } else {
  230. DoubleToAscii(value, PRECISION, requested_digits + 1,
  231. decimal_rep, kDecimalRepCapacity,
  232. &sign, &decimal_rep_length, &decimal_point);
  233. ASSERT(decimal_rep_length <= requested_digits + 1);
  234. for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
  235. decimal_rep[i] = '0';
  236. }
  237. decimal_rep_length = requested_digits + 1;
  238. }
  239. bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
  240. if (sign && (value != 0.0 || !unique_zero)) {
  241. result_builder->AddCharacter('-');
  242. }
  243. int exponent = decimal_point - 1;
  244. CreateExponentialRepresentation(decimal_rep,
  245. decimal_rep_length,
  246. exponent,
  247. result_builder);
  248. return true;
  249. }
  250. bool DoubleToStringConverter::ToPrecision(double value,
  251. int precision,
  252. StringBuilder* result_builder) const {
  253. if (Double(value).IsSpecial()) {
  254. return HandleSpecialValues(value, result_builder);
  255. }
  256. if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
  257. return false;
  258. }
  259. // Find a sufficiently precise decimal representation of n.
  260. int decimal_point;
  261. bool sign;
  262. // Add one for the terminating null character.
  263. const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
  264. char decimal_rep[kDecimalRepCapacity];
  265. int decimal_rep_length;
  266. DoubleToAscii(value, PRECISION, precision,
  267. decimal_rep, kDecimalRepCapacity,
  268. &sign, &decimal_rep_length, &decimal_point);
  269. ASSERT(decimal_rep_length <= precision);
  270. bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
  271. if (sign && (value != 0.0 || !unique_zero)) {
  272. result_builder->AddCharacter('-');
  273. }
  274. // The exponent if we print the number as x.xxeyyy. That is with the
  275. // decimal point after the first digit.
  276. int exponent = decimal_point - 1;
  277. int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
  278. if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
  279. (decimal_point - precision + extra_zero >
  280. max_trailing_padding_zeroes_in_precision_mode_)) {
  281. // Fill buffer to contain 'precision' digits.
  282. // Usually the buffer is already at the correct length, but 'DoubleToAscii'
  283. // is allowed to return less characters.
  284. for (int i = decimal_rep_length; i < precision; ++i) {
  285. decimal_rep[i] = '0';
  286. }
  287. CreateExponentialRepresentation(decimal_rep,
  288. precision,
  289. exponent,
  290. result_builder);
  291. } else {
  292. CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
  293. Max(0, precision - decimal_point),
  294. result_builder);
  295. }
  296. return true;
  297. }
  298. static BignumDtoaMode DtoaToBignumDtoaMode(
  299. DoubleToStringConverter::DtoaMode dtoa_mode) {
  300. switch (dtoa_mode) {
  301. case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST;
  302. case DoubleToStringConverter::SHORTEST_SINGLE:
  303. return BIGNUM_DTOA_SHORTEST_SINGLE;
  304. case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED;
  305. case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
  306. default:
  307. UNREACHABLE();
  308. }
  309. }
  310. void DoubleToStringConverter::DoubleToAscii(double v,
  311. DtoaMode mode,
  312. int requested_digits,
  313. char* buffer,
  314. int buffer_length,
  315. bool* sign,
  316. int* length,
  317. int* point) {
  318. Vector<char> vector(buffer, buffer_length);
  319. ASSERT(!Double(v).IsSpecial());
  320. ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0);
  321. if (Double(v).Sign() < 0) {
  322. *sign = true;
  323. v = -v;
  324. } else {
  325. *sign = false;
  326. }
  327. if (mode == PRECISION && requested_digits == 0) {
  328. vector[0] = '\0';
  329. *length = 0;
  330. return;
  331. }
  332. if (v == 0) {
  333. vector[0] = '0';
  334. vector[1] = '\0';
  335. *length = 1;
  336. *point = 1;
  337. return;
  338. }
  339. bool fast_worked;
  340. switch (mode) {
  341. case SHORTEST:
  342. fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
  343. break;
  344. case SHORTEST_SINGLE:
  345. fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0,
  346. vector, length, point);
  347. break;
  348. case FIXED:
  349. fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
  350. break;
  351. case PRECISION:
  352. fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
  353. vector, length, point);
  354. break;
  355. default:
  356. fast_worked = false;
  357. UNREACHABLE();
  358. }
  359. if (fast_worked) return;
  360. // If the fast dtoa didn't succeed use the slower bignum version.
  361. BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
  362. BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
  363. vector[*length] = '\0';
  364. }
  365. // Consumes the given substring from the iterator.
  366. // Returns false, if the substring does not match.
  367. template <class Iterator>
  368. static bool ConsumeSubString(Iterator* current,
  369. Iterator end,
  370. const char* substring) {
  371. ASSERT(**current == *substring);
  372. for (substring++; *substring != '\0'; substring++) {
  373. ++*current;
  374. if (*current == end || **current != *substring) return false;
  375. }
  376. ++*current;
  377. return true;
  378. }
  379. // Maximum number of significant digits in decimal representation.
  380. // The longest possible double in decimal representation is
  381. // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
  382. // (768 digits). If we parse a number whose first digits are equal to a
  383. // mean of 2 adjacent doubles (that could have up to 769 digits) the result
  384. // must be rounded to the bigger one unless the tail consists of zeros, so
  385. // we don't need to preserve all the digits.
  386. const int kMaxSignificantDigits = 772;
  387. static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 };
  388. static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7);
  389. static const uc16 kWhitespaceTable16[] = {
  390. 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
  391. 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
  392. };
  393. static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16);
  394. static bool isWhitespace(int x) {
  395. if (x < 128) {
  396. for (int i = 0; i < kWhitespaceTable7Length; i++) {
  397. if (kWhitespaceTable7[i] == x) return true;
  398. }
  399. } else {
  400. for (int i = 0; i < kWhitespaceTable16Length; i++) {
  401. if (kWhitespaceTable16[i] == x) return true;
  402. }
  403. }
  404. return false;
  405. }
  406. // Returns true if a nonspace found and false if the end has reached.
  407. template <class Iterator>
  408. static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
  409. while (*current != end) {
  410. if (!isWhitespace(**current)) return true;
  411. ++*current;
  412. }
  413. return false;
  414. }
  415. static bool isDigit(int x, int radix) {
  416. return (x >= '0' && x <= '9' && x < '0' + radix)
  417. || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
  418. || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
  419. }
  420. static double SignedZero(bool sign) {
  421. return sign ? -0.0 : 0.0;
  422. }
  423. // Returns true if 'c' is a decimal digit that is valid for the given radix.
  424. //
  425. // The function is small and could be inlined, but VS2012 emitted a warning
  426. // because it constant-propagated the radix and concluded that the last
  427. // condition was always true. By moving it into a separate function the
  428. // compiler wouldn't warn anymore.
  429. #if _MSC_VER
  430. #pragma optimize("",off)
  431. static bool IsDecimalDigitForRadix(int c, int radix) {
  432. return '0' <= c && c <= '9' && (c - '0') < radix;
  433. }
  434. #pragma optimize("",on)
  435. #else
  436. static bool inline IsDecimalDigitForRadix(int c, int radix) {
  437. return '0' <= c && c <= '9' && (c - '0') < radix;
  438. }
  439. #endif
  440. // Returns true if 'c' is a character digit that is valid for the given radix.
  441. // The 'a_character' should be 'a' or 'A'.
  442. //
  443. // The function is small and could be inlined, but VS2012 emitted a warning
  444. // because it constant-propagated the radix and concluded that the first
  445. // condition was always false. By moving it into a separate function the
  446. // compiler wouldn't warn anymore.
  447. static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
  448. return radix > 10 && c >= a_character && c < a_character + radix - 10;
  449. }
  450. // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
  451. template <int radix_log_2, class Iterator>
  452. static double RadixStringToIeee(Iterator* current,
  453. Iterator end,
  454. bool sign,
  455. bool allow_trailing_junk,
  456. double junk_string_value,
  457. bool read_as_double,
  458. bool* result_is_junk) {
  459. ASSERT(*current != end);
  460. const int kDoubleSize = Double::kSignificandSize;
  461. const int kSingleSize = Single::kSignificandSize;
  462. const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
  463. *result_is_junk = true;
  464. // Skip leading 0s.
  465. while (**current == '0') {
  466. ++(*current);
  467. if (*current == end) {
  468. *result_is_junk = false;
  469. return SignedZero(sign);
  470. }
  471. }
  472. int64_t number = 0;
  473. int exponent = 0;
  474. const int radix = (1 << radix_log_2);
  475. do {
  476. int digit;
  477. if (IsDecimalDigitForRadix(**current, radix)) {
  478. digit = static_cast<char>(**current) - '0';
  479. } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
  480. digit = static_cast<char>(**current) - 'a' + 10;
  481. } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
  482. digit = static_cast<char>(**current) - 'A' + 10;
  483. } else {
  484. if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
  485. break;
  486. } else {
  487. return junk_string_value;
  488. }
  489. }
  490. number = number * radix + digit;
  491. int overflow = static_cast<int>(number >> kSignificandSize);
  492. if (overflow != 0) {
  493. // Overflow occurred. Need to determine which direction to round the
  494. // result.
  495. int overflow_bits_count = 1;
  496. while (overflow > 1) {
  497. overflow_bits_count++;
  498. overflow >>= 1;
  499. }
  500. int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
  501. int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
  502. number >>= overflow_bits_count;
  503. exponent = overflow_bits_count;
  504. bool zero_tail = true;
  505. for (;;) {
  506. ++(*current);
  507. if (*current == end || !isDigit(**current, radix)) break;
  508. zero_tail = zero_tail && **current == '0';
  509. exponent += radix_log_2;
  510. }
  511. if (!allow_trailing_junk && AdvanceToNonspace(current, end)) {
  512. return junk_string_value;
  513. }
  514. int middle_value = (1 << (overflow_bits_count - 1));
  515. if (dropped_bits > middle_value) {
  516. number++; // Rounding up.
  517. } else if (dropped_bits == middle_value) {
  518. // Rounding to even to consistency with decimals: half-way case rounds
  519. // up if significant part is odd and down otherwise.
  520. if ((number & 1) != 0 || !zero_tail) {
  521. number++; // Rounding up.
  522. }
  523. }
  524. // Rounding up may cause overflow.
  525. if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
  526. exponent++;
  527. number >>= 1;
  528. }
  529. break;
  530. }
  531. ++(*current);
  532. } while (*current != end);
  533. ASSERT(number < ((int64_t)1 << kSignificandSize));
  534. ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
  535. *result_is_junk = false;
  536. if (exponent == 0) {
  537. if (sign) {
  538. if (number == 0) return -0.0;
  539. number = -number;
  540. }
  541. return static_cast<double>(number);
  542. }
  543. ASSERT(number != 0);
  544. return Double(DiyFp(number, exponent)).value();
  545. }
  546. template <class Iterator>
  547. double StringToDoubleConverter::StringToIeee(
  548. Iterator input,
  549. int length,
  550. bool read_as_double,
  551. int* processed_characters_count) const {
  552. Iterator current = input;
  553. Iterator end = input + length;
  554. *processed_characters_count = 0;
  555. const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
  556. const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
  557. const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
  558. const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
  559. // To make sure that iterator dereferencing is valid the following
  560. // convention is used:
  561. // 1. Each '++current' statement is followed by check for equality to 'end'.
  562. // 2. If AdvanceToNonspace returned false then current == end.
  563. // 3. If 'current' becomes equal to 'end' the function returns or goes to
  564. // 'parsing_done'.
  565. // 4. 'current' is not dereferenced after the 'parsing_done' label.
  566. // 5. Code before 'parsing_done' may rely on 'current != end'.
  567. if (current == end) return empty_string_value_;
  568. if (allow_leading_spaces || allow_trailing_spaces) {
  569. if (!AdvanceToNonspace(&current, end)) {
  570. *processed_characters_count = static_cast<int>(current - input);
  571. return empty_string_value_;
  572. }
  573. if (!allow_leading_spaces && (input != current)) {
  574. // No leading spaces allowed, but AdvanceToNonspace moved forward.
  575. return junk_string_value_;
  576. }
  577. }
  578. // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
  579. const int kBufferSize = kMaxSignificantDigits + 10;
  580. char buffer[kBufferSize]; // NOLINT: size is known at compile time.
  581. int buffer_pos = 0;
  582. // Exponent will be adjusted if insignificant digits of the integer part
  583. // or insignificant leading zeros of the fractional part are dropped.
  584. int exponent = 0;
  585. int significant_digits = 0;
  586. int insignificant_digits = 0;
  587. bool nonzero_digit_dropped = false;
  588. bool sign = false;
  589. if (*current == '+' || *current == '-') {
  590. sign = (*current == '-');
  591. ++current;
  592. Iterator next_non_space = current;
  593. // Skip following spaces (if allowed).
  594. if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
  595. if (!allow_spaces_after_sign && (current != next_non_space)) {
  596. return junk_string_value_;
  597. }
  598. current = next_non_space;
  599. }
  600. if (infinity_symbol_ != NULL) {
  601. if (*current == infinity_symbol_[0]) {
  602. if (!ConsumeSubString(&current, end, infinity_symbol_)) {
  603. return junk_string_value_;
  604. }
  605. if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
  606. return junk_string_value_;
  607. }
  608. if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
  609. return junk_string_value_;
  610. }
  611. ASSERT(buffer_pos == 0);
  612. *processed_characters_count = static_cast<int>(current - input);
  613. return sign ? -Double::Infinity() : Double::Infinity();
  614. }
  615. }
  616. if (nan_symbol_ != NULL) {
  617. if (*current == nan_symbol_[0]) {
  618. if (!ConsumeSubString(&current, end, nan_symbol_)) {
  619. return junk_string_value_;
  620. }
  621. if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
  622. return junk_string_value_;
  623. }
  624. if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
  625. return junk_string_value_;
  626. }
  627. ASSERT(buffer_pos == 0);
  628. *processed_characters_count = static_cast<int>(current - input);
  629. return sign ? -Double::NaN() : Double::NaN();
  630. }
  631. }
  632. bool leading_zero = false;
  633. if (*current == '0') {
  634. ++current;
  635. if (current == end) {
  636. *processed_characters_count = static_cast<int>(current - input);
  637. return SignedZero(sign);
  638. }
  639. leading_zero = true;
  640. // It could be hexadecimal value.
  641. if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
  642. ++current;
  643. if (current == end || !isDigit(*current, 16)) {
  644. return junk_string_value_; // "0x".
  645. }
  646. bool result_is_junk;
  647. double result = RadixStringToIeee<4>(&current,
  648. end,
  649. sign,
  650. allow_trailing_junk,
  651. junk_string_value_,
  652. read_as_double,
  653. &result_is_junk);
  654. if (!result_is_junk) {
  655. if (allow_trailing_spaces) AdvanceToNonspace(&current, end);
  656. *processed_characters_count = static_cast<int>(current - input);
  657. }
  658. return result;
  659. }
  660. // Ignore leading zeros in the integer part.
  661. while (*current == '0') {
  662. ++current;
  663. if (current == end) {
  664. *processed_characters_count = static_cast<int>(current - input);
  665. return SignedZero(sign);
  666. }
  667. }
  668. }
  669. bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
  670. // Copy significant digits of the integer part (if any) to the buffer.
  671. while (*current >= '0' && *current <= '9') {
  672. if (significant_digits < kMaxSignificantDigits) {
  673. ASSERT(buffer_pos < kBufferSize);
  674. buffer[buffer_pos++] = static_cast<char>(*current);
  675. significant_digits++;
  676. // Will later check if it's an octal in the buffer.
  677. } else {
  678. insignificant_digits++; // Move the digit into the exponential part.
  679. nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
  680. }
  681. octal = octal && *current < '8';
  682. ++current;
  683. if (current == end) goto parsing_done;
  684. }
  685. if (significant_digits == 0) {
  686. octal = false;
  687. }
  688. if (*current == '.') {
  689. if (octal && !allow_trailing_junk) return junk_string_value_;
  690. if (octal) goto parsing_done;
  691. ++current;
  692. if (current == end) {
  693. if (significant_digits == 0 && !leading_zero) {
  694. return junk_string_value_;
  695. } else {
  696. goto parsing_done;
  697. }
  698. }
  699. if (significant_digits == 0) {
  700. // octal = false;
  701. // Integer part consists of 0 or is absent. Significant digits start after
  702. // leading zeros (if any).
  703. while (*current == '0') {
  704. ++current;
  705. if (current == end) {
  706. *processed_characters_count = static_cast<int>(current - input);
  707. return SignedZero(sign);
  708. }
  709. exponent--; // Move this 0 into the exponent.
  710. }
  711. }
  712. // There is a fractional part.
  713. // We don't emit a '.', but adjust the exponent instead.
  714. while (*current >= '0' && *current <= '9') {
  715. if (significant_digits < kMaxSignificantDigits) {
  716. ASSERT(buffer_pos < kBufferSize);
  717. buffer[buffer_pos++] = static_cast<char>(*current);
  718. significant_digits++;
  719. exponent--;
  720. } else {
  721. // Ignore insignificant digits in the fractional part.
  722. nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
  723. }
  724. ++current;
  725. if (current == end) goto parsing_done;
  726. }
  727. }
  728. if (!leading_zero && exponent == 0 && significant_digits == 0) {
  729. // If leading_zeros is true then the string contains zeros.
  730. // If exponent < 0 then string was [+-]\.0*...
  731. // If significant_digits != 0 the string is not equal to 0.
  732. // Otherwise there are no digits in the string.
  733. return junk_string_value_;
  734. }
  735. // Parse exponential part.
  736. if (*current == 'e' || *current == 'E') {
  737. if (octal && !allow_trailing_junk) return junk_string_value_;
  738. if (octal) goto parsing_done;
  739. ++current;
  740. if (current == end) {
  741. if (allow_trailing_junk) {
  742. goto parsing_done;
  743. } else {
  744. return junk_string_value_;
  745. }
  746. }
  747. char exponen_sign = '+';
  748. if (*current == '+' || *current == '-') {
  749. exponen_sign = static_cast<char>(*current);
  750. ++current;
  751. if (current == end) {
  752. if (allow_trailing_junk) {
  753. goto parsing_done;
  754. } else {
  755. return junk_string_value_;
  756. }
  757. }
  758. }
  759. if (current == end || *current < '0' || *current > '9') {
  760. if (allow_trailing_junk) {
  761. goto parsing_done;
  762. } else {
  763. return junk_string_value_;
  764. }
  765. }
  766. const int max_exponent = INT_MAX / 2;
  767. ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
  768. int num = 0;
  769. do {
  770. // Check overflow.
  771. int digit = *current - '0';
  772. if (num >= max_exponent / 10
  773. && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
  774. num = max_exponent;
  775. } else {
  776. num = num * 10 + digit;
  777. }
  778. ++current;
  779. } while (current != end && *current >= '0' && *current <= '9');
  780. exponent += (exponen_sign == '-' ? -num : num);
  781. }
  782. if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
  783. return junk_string_value_;
  784. }
  785. if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
  786. return junk_string_value_;
  787. }
  788. if (allow_trailing_spaces) {
  789. AdvanceToNonspace(&current, end);
  790. }
  791. parsing_done:
  792. exponent += insignificant_digits;
  793. if (octal) {
  794. double result;
  795. bool result_is_junk;
  796. char* start = buffer;
  797. result = RadixStringToIeee<3>(&start,
  798. buffer + buffer_pos,
  799. sign,
  800. allow_trailing_junk,
  801. junk_string_value_,
  802. read_as_double,
  803. &result_is_junk);
  804. ASSERT(!result_is_junk);
  805. *processed_characters_count = static_cast<int>(current - input);
  806. return result;
  807. }
  808. if (nonzero_digit_dropped) {
  809. buffer[buffer_pos++] = '1';
  810. exponent--;
  811. }
  812. ASSERT(buffer_pos < kBufferSize);
  813. buffer[buffer_pos] = '\0';
  814. double converted;
  815. if (read_as_double) {
  816. converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
  817. } else {
  818. converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
  819. }
  820. *processed_characters_count = static_cast<int>(current - input);
  821. return sign? -converted: converted;
  822. }
  823. double StringToDoubleConverter::StringToDouble(
  824. const char* buffer,
  825. int length,
  826. int* processed_characters_count) const {
  827. return StringToIeee(buffer, length, true, processed_characters_count);
  828. }
  829. double StringToDoubleConverter::StringToDouble(
  830. const uc16* buffer,
  831. int length,
  832. int* processed_characters_count) const {
  833. return StringToIeee(buffer, length, true, processed_characters_count);
  834. }
  835. float StringToDoubleConverter::StringToFloat(
  836. const char* buffer,
  837. int length,
  838. int* processed_characters_count) const {
  839. return static_cast<float>(StringToIeee(buffer, length, false,
  840. processed_characters_count));
  841. }
  842. float StringToDoubleConverter::StringToFloat(
  843. const uc16* buffer,
  844. int length,
  845. int* processed_characters_count) const {
  846. return static_cast<float>(StringToIeee(buffer, length, false,
  847. processed_characters_count));
  848. }
  849. } // namespace double_conversion