Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

889 строки
29 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.h"
  30. #include "bignum-dtoa.h"
  31. #include "fast-dtoa.h"
  32. #include "fixed-dtoa.h"
  33. #include "ieee.h"
  34. #include "strtod.h"
  35. #include "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. return BIGNUM_DTOA_SHORTEST; // To silence compiler.
  309. }
  310. }
  311. void DoubleToStringConverter::DoubleToAscii(double v,
  312. DtoaMode mode,
  313. int requested_digits,
  314. char* buffer,
  315. int buffer_length,
  316. bool* sign,
  317. int* length,
  318. int* point) {
  319. Vector<char> vector(buffer, buffer_length);
  320. ASSERT(!Double(v).IsSpecial());
  321. ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0);
  322. if (Double(v).Sign() < 0) {
  323. *sign = true;
  324. v = -v;
  325. } else {
  326. *sign = false;
  327. }
  328. if (mode == PRECISION && requested_digits == 0) {
  329. vector[0] = '\0';
  330. *length = 0;
  331. return;
  332. }
  333. if (v == 0) {
  334. vector[0] = '0';
  335. vector[1] = '\0';
  336. *length = 1;
  337. *point = 1;
  338. return;
  339. }
  340. bool fast_worked;
  341. switch (mode) {
  342. case SHORTEST:
  343. fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
  344. break;
  345. case SHORTEST_SINGLE:
  346. fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0,
  347. vector, length, point);
  348. break;
  349. case FIXED:
  350. fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
  351. break;
  352. case PRECISION:
  353. fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
  354. vector, length, point);
  355. break;
  356. default:
  357. UNREACHABLE();
  358. fast_worked = false;
  359. }
  360. if (fast_worked) return;
  361. // If the fast dtoa didn't succeed use the slower bignum version.
  362. BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
  363. BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
  364. vector[*length] = '\0';
  365. }
  366. // Consumes the given substring from the iterator.
  367. // Returns false, if the substring does not match.
  368. static bool ConsumeSubString(const char** current,
  369. const char* 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. // Returns true if a nonspace found and false if the end has reached.
  388. static inline bool AdvanceToNonspace(const char** current, const char* end) {
  389. while (*current != end) {
  390. if (**current != ' ') return true;
  391. ++*current;
  392. }
  393. return false;
  394. }
  395. static bool isDigit(int x, int radix) {
  396. return (x >= '0' && x <= '9' && x < '0' + radix)
  397. || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
  398. || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
  399. }
  400. static double SignedZero(bool sign) {
  401. return sign ? -0.0 : 0.0;
  402. }
  403. // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
  404. template <int radix_log_2>
  405. static double RadixStringToIeee(const char* current,
  406. const char* end,
  407. bool sign,
  408. bool allow_trailing_junk,
  409. double junk_string_value,
  410. bool read_as_double,
  411. const char** trailing_pointer) {
  412. ASSERT(current != end);
  413. const int kDoubleSize = Double::kSignificandSize;
  414. const int kSingleSize = Single::kSignificandSize;
  415. const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
  416. // Skip leading 0s.
  417. while (*current == '0') {
  418. ++current;
  419. if (current == end) {
  420. *trailing_pointer = end;
  421. return SignedZero(sign);
  422. }
  423. }
  424. int64_t number = 0;
  425. int exponent = 0;
  426. const int radix = (1 << radix_log_2);
  427. do {
  428. int digit;
  429. if (*current >= '0' && *current <= '9' && *current < '0' + radix) {
  430. digit = static_cast<char>(*current) - '0';
  431. } else if (radix > 10 && *current >= 'a' && *current < 'a' + radix - 10) {
  432. digit = static_cast<char>(*current) - 'a' + 10;
  433. } else if (radix > 10 && *current >= 'A' && *current < 'A' + radix - 10) {
  434. digit = static_cast<char>(*current) - 'A' + 10;
  435. } else {
  436. if (allow_trailing_junk || !AdvanceToNonspace(&current, end)) {
  437. break;
  438. } else {
  439. return junk_string_value;
  440. }
  441. }
  442. number = number * radix + digit;
  443. int overflow = static_cast<int>(number >> kSignificandSize);
  444. if (overflow != 0) {
  445. // Overflow occurred. Need to determine which direction to round the
  446. // result.
  447. int overflow_bits_count = 1;
  448. while (overflow > 1) {
  449. overflow_bits_count++;
  450. overflow >>= 1;
  451. }
  452. int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
  453. int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
  454. number >>= overflow_bits_count;
  455. exponent = overflow_bits_count;
  456. bool zero_tail = true;
  457. while (true) {
  458. ++current;
  459. if (current == end || !isDigit(*current, radix)) break;
  460. zero_tail = zero_tail && *current == '0';
  461. exponent += radix_log_2;
  462. }
  463. if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
  464. return junk_string_value;
  465. }
  466. int middle_value = (1 << (overflow_bits_count - 1));
  467. if (dropped_bits > middle_value) {
  468. number++; // Rounding up.
  469. } else if (dropped_bits == middle_value) {
  470. // Rounding to even to consistency with decimals: half-way case rounds
  471. // up if significant part is odd and down otherwise.
  472. if ((number & 1) != 0 || !zero_tail) {
  473. number++; // Rounding up.
  474. }
  475. }
  476. // Rounding up may cause overflow.
  477. if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
  478. exponent++;
  479. number >>= 1;
  480. }
  481. break;
  482. }
  483. ++current;
  484. } while (current != end);
  485. ASSERT(number < ((int64_t)1 << kSignificandSize));
  486. ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
  487. *trailing_pointer = current;
  488. if (exponent == 0) {
  489. if (sign) {
  490. if (number == 0) return -0.0;
  491. number = -number;
  492. }
  493. return static_cast<double>(number);
  494. }
  495. ASSERT(number != 0);
  496. return Double(DiyFp(number, exponent)).value();
  497. }
  498. double StringToDoubleConverter::StringToIeee(
  499. const char* input,
  500. int length,
  501. int* processed_characters_count,
  502. bool read_as_double) {
  503. const char* current = input;
  504. const char* end = input + length;
  505. *processed_characters_count = 0;
  506. const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
  507. const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
  508. const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
  509. const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
  510. // To make sure that iterator dereferencing is valid the following
  511. // convention is used:
  512. // 1. Each '++current' statement is followed by check for equality to 'end'.
  513. // 2. If AdvanceToNonspace returned false then current == end.
  514. // 3. If 'current' becomes equal to 'end' the function returns or goes to
  515. // 'parsing_done'.
  516. // 4. 'current' is not dereferenced after the 'parsing_done' label.
  517. // 5. Code before 'parsing_done' may rely on 'current != end'.
  518. if (current == end) return empty_string_value_;
  519. if (allow_leading_spaces || allow_trailing_spaces) {
  520. if (!AdvanceToNonspace(&current, end)) {
  521. *processed_characters_count = current - input;
  522. return empty_string_value_;
  523. }
  524. if (!allow_leading_spaces && (input != current)) {
  525. // No leading spaces allowed, but AdvanceToNonspace moved forward.
  526. return junk_string_value_;
  527. }
  528. }
  529. // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
  530. const int kBufferSize = kMaxSignificantDigits + 10;
  531. char buffer[kBufferSize]; // NOLINT: size is known at compile time.
  532. int buffer_pos = 0;
  533. // Exponent will be adjusted if insignificant digits of the integer part
  534. // or insignificant leading zeros of the fractional part are dropped.
  535. int exponent = 0;
  536. int significant_digits = 0;
  537. int insignificant_digits = 0;
  538. bool nonzero_digit_dropped = false;
  539. bool sign = false;
  540. if (*current == '+' || *current == '-') {
  541. sign = (*current == '-');
  542. ++current;
  543. const char* next_non_space = current;
  544. // Skip following spaces (if allowed).
  545. if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
  546. if (!allow_spaces_after_sign && (current != next_non_space)) {
  547. return junk_string_value_;
  548. }
  549. current = next_non_space;
  550. }
  551. if (infinity_symbol_ != NULL) {
  552. if (*current == infinity_symbol_[0]) {
  553. if (!ConsumeSubString(&current, end, infinity_symbol_)) {
  554. return junk_string_value_;
  555. }
  556. if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
  557. return junk_string_value_;
  558. }
  559. if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
  560. return junk_string_value_;
  561. }
  562. ASSERT(buffer_pos == 0);
  563. *processed_characters_count = current - input;
  564. return sign ? -Double::Infinity() : Double::Infinity();
  565. }
  566. }
  567. if (nan_symbol_ != NULL) {
  568. if (*current == nan_symbol_[0]) {
  569. if (!ConsumeSubString(&current, end, nan_symbol_)) {
  570. return junk_string_value_;
  571. }
  572. if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
  573. return junk_string_value_;
  574. }
  575. if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
  576. return junk_string_value_;
  577. }
  578. ASSERT(buffer_pos == 0);
  579. *processed_characters_count = current - input;
  580. return sign ? -Double::NaN() : Double::NaN();
  581. }
  582. }
  583. bool leading_zero = false;
  584. if (*current == '0') {
  585. ++current;
  586. if (current == end) {
  587. *processed_characters_count = current - input;
  588. return SignedZero(sign);
  589. }
  590. leading_zero = true;
  591. // It could be hexadecimal value.
  592. if ((flags_ & ALLOW_HEX) && (*current == 'x' || *current == 'X')) {
  593. ++current;
  594. if (current == end || !isDigit(*current, 16)) {
  595. return junk_string_value_; // "0x".
  596. }
  597. const char* tail_pointer = NULL;
  598. double result = RadixStringToIeee<4>(current,
  599. end,
  600. sign,
  601. allow_trailing_junk,
  602. junk_string_value_,
  603. read_as_double,
  604. &tail_pointer);
  605. if (tail_pointer != NULL) {
  606. if (allow_trailing_spaces) AdvanceToNonspace(&tail_pointer, end);
  607. *processed_characters_count = tail_pointer - input;
  608. }
  609. return result;
  610. }
  611. // Ignore leading zeros in the integer part.
  612. while (*current == '0') {
  613. ++current;
  614. if (current == end) {
  615. *processed_characters_count = current - input;
  616. return SignedZero(sign);
  617. }
  618. }
  619. }
  620. bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
  621. // Copy significant digits of the integer part (if any) to the buffer.
  622. while (*current >= '0' && *current <= '9') {
  623. if (significant_digits < kMaxSignificantDigits) {
  624. ASSERT(buffer_pos < kBufferSize);
  625. buffer[buffer_pos++] = static_cast<char>(*current);
  626. significant_digits++;
  627. // Will later check if it's an octal in the buffer.
  628. } else {
  629. insignificant_digits++; // Move the digit into the exponential part.
  630. nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
  631. }
  632. octal = octal && *current < '8';
  633. ++current;
  634. if (current == end) goto parsing_done;
  635. }
  636. if (significant_digits == 0) {
  637. octal = false;
  638. }
  639. if (*current == '.') {
  640. if (octal && !allow_trailing_junk) return junk_string_value_;
  641. if (octal) goto parsing_done;
  642. ++current;
  643. if (current == end) {
  644. if (significant_digits == 0 && !leading_zero) {
  645. return junk_string_value_;
  646. } else {
  647. goto parsing_done;
  648. }
  649. }
  650. if (significant_digits == 0) {
  651. // octal = false;
  652. // Integer part consists of 0 or is absent. Significant digits start after
  653. // leading zeros (if any).
  654. while (*current == '0') {
  655. ++current;
  656. if (current == end) {
  657. *processed_characters_count = current - input;
  658. return SignedZero(sign);
  659. }
  660. exponent--; // Move this 0 into the exponent.
  661. }
  662. }
  663. // There is a fractional part.
  664. // We don't emit a '.', but adjust the exponent instead.
  665. while (*current >= '0' && *current <= '9') {
  666. if (significant_digits < kMaxSignificantDigits) {
  667. ASSERT(buffer_pos < kBufferSize);
  668. buffer[buffer_pos++] = static_cast<char>(*current);
  669. significant_digits++;
  670. exponent--;
  671. } else {
  672. // Ignore insignificant digits in the fractional part.
  673. nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
  674. }
  675. ++current;
  676. if (current == end) goto parsing_done;
  677. }
  678. }
  679. if (!leading_zero && exponent == 0 && significant_digits == 0) {
  680. // If leading_zeros is true then the string contains zeros.
  681. // If exponent < 0 then string was [+-]\.0*...
  682. // If significant_digits != 0 the string is not equal to 0.
  683. // Otherwise there are no digits in the string.
  684. return junk_string_value_;
  685. }
  686. // Parse exponential part.
  687. if (*current == 'e' || *current == 'E') {
  688. if (octal && !allow_trailing_junk) return junk_string_value_;
  689. if (octal) goto parsing_done;
  690. ++current;
  691. if (current == end) {
  692. if (allow_trailing_junk) {
  693. goto parsing_done;
  694. } else {
  695. return junk_string_value_;
  696. }
  697. }
  698. char sign = '+';
  699. if (*current == '+' || *current == '-') {
  700. sign = static_cast<char>(*current);
  701. ++current;
  702. if (current == end) {
  703. if (allow_trailing_junk) {
  704. goto parsing_done;
  705. } else {
  706. return junk_string_value_;
  707. }
  708. }
  709. }
  710. if (current == end || *current < '0' || *current > '9') {
  711. if (allow_trailing_junk) {
  712. goto parsing_done;
  713. } else {
  714. return junk_string_value_;
  715. }
  716. }
  717. const int max_exponent = INT_MAX / 2;
  718. ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
  719. int num = 0;
  720. do {
  721. // Check overflow.
  722. int digit = *current - '0';
  723. if (num >= max_exponent / 10
  724. && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
  725. num = max_exponent;
  726. } else {
  727. num = num * 10 + digit;
  728. }
  729. ++current;
  730. } while (current != end && *current >= '0' && *current <= '9');
  731. exponent += (sign == '-' ? -num : num);
  732. }
  733. if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
  734. return junk_string_value_;
  735. }
  736. if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
  737. return junk_string_value_;
  738. }
  739. if (allow_trailing_spaces) {
  740. AdvanceToNonspace(&current, end);
  741. }
  742. parsing_done:
  743. exponent += insignificant_digits;
  744. if (octal) {
  745. double result;
  746. const char* tail_pointer = NULL;
  747. result = RadixStringToIeee<3>(buffer,
  748. buffer + buffer_pos,
  749. sign,
  750. allow_trailing_junk,
  751. junk_string_value_,
  752. read_as_double,
  753. &tail_pointer);
  754. ASSERT(tail_pointer != NULL);
  755. *processed_characters_count = current - input;
  756. return result;
  757. }
  758. if (nonzero_digit_dropped) {
  759. buffer[buffer_pos++] = '1';
  760. exponent--;
  761. }
  762. ASSERT(buffer_pos < kBufferSize);
  763. buffer[buffer_pos] = '\0';
  764. double converted;
  765. if (read_as_double) {
  766. converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
  767. } else {
  768. converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
  769. }
  770. *processed_characters_count = current - input;
  771. return sign? -converted: converted;
  772. }
  773. } // namespace double_conversion