您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

1144 行
38 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 <climits>
  28. #include <locale>
  29. #include <cmath>
  30. #include "double-conversion.h"
  31. #include "bignum-dtoa.h"
  32. #include "fast-dtoa.h"
  33. #include "fixed-dtoa.h"
  34. #include "ieee.h"
  35. #include "strtod.h"
  36. #include "utils.h"
  37. namespace double_conversion {
  38. const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
  39. int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
  40. static DoubleToStringConverter converter(flags,
  41. "Infinity",
  42. "NaN",
  43. 'e',
  44. -6, 21,
  45. 6, 0);
  46. return converter;
  47. }
  48. bool DoubleToStringConverter::HandleSpecialValues(
  49. double value,
  50. StringBuilder* result_builder) const {
  51. Double double_inspect(value);
  52. if (double_inspect.IsInfinite()) {
  53. if (infinity_symbol_ == NULL) return false;
  54. if (value < 0) {
  55. result_builder->AddCharacter('-');
  56. }
  57. result_builder->AddString(infinity_symbol_);
  58. return true;
  59. }
  60. if (double_inspect.IsNan()) {
  61. if (nan_symbol_ == NULL) return false;
  62. result_builder->AddString(nan_symbol_);
  63. return true;
  64. }
  65. return false;
  66. }
  67. void DoubleToStringConverter::CreateExponentialRepresentation(
  68. const char* decimal_digits,
  69. int length,
  70. int exponent,
  71. StringBuilder* result_builder) const {
  72. ASSERT(length != 0);
  73. result_builder->AddCharacter(decimal_digits[0]);
  74. if (length != 1) {
  75. result_builder->AddCharacter('.');
  76. result_builder->AddSubstring(&decimal_digits[1], length-1);
  77. }
  78. result_builder->AddCharacter(exponent_character_);
  79. if (exponent < 0) {
  80. result_builder->AddCharacter('-');
  81. exponent = -exponent;
  82. } else {
  83. if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
  84. result_builder->AddCharacter('+');
  85. }
  86. }
  87. if (exponent == 0) {
  88. result_builder->AddCharacter('0');
  89. return;
  90. }
  91. ASSERT(exponent < 1e4);
  92. const int kMaxExponentLength = 5;
  93. char buffer[kMaxExponentLength + 1];
  94. buffer[kMaxExponentLength] = '\0';
  95. int first_char_pos = kMaxExponentLength;
  96. while (exponent > 0) {
  97. buffer[--first_char_pos] = '0' + (exponent % 10);
  98. exponent /= 10;
  99. }
  100. result_builder->AddSubstring(&buffer[first_char_pos],
  101. kMaxExponentLength - first_char_pos);
  102. }
  103. void DoubleToStringConverter::CreateDecimalRepresentation(
  104. const char* decimal_digits,
  105. int length,
  106. int decimal_point,
  107. int digits_after_point,
  108. StringBuilder* result_builder) const {
  109. // Create a representation that is padded with zeros if needed.
  110. if (decimal_point <= 0) {
  111. // "0.00000decimal_rep" or "0.000decimal_rep00".
  112. result_builder->AddCharacter('0');
  113. if (digits_after_point > 0) {
  114. result_builder->AddCharacter('.');
  115. result_builder->AddPadding('0', -decimal_point);
  116. ASSERT(length <= digits_after_point - (-decimal_point));
  117. result_builder->AddSubstring(decimal_digits, length);
  118. int remaining_digits = digits_after_point - (-decimal_point) - length;
  119. result_builder->AddPadding('0', remaining_digits);
  120. }
  121. } else if (decimal_point >= length) {
  122. // "decimal_rep0000.00000" or "decimal_rep.0000".
  123. result_builder->AddSubstring(decimal_digits, length);
  124. result_builder->AddPadding('0', decimal_point - length);
  125. if (digits_after_point > 0) {
  126. result_builder->AddCharacter('.');
  127. result_builder->AddPadding('0', digits_after_point);
  128. }
  129. } else {
  130. // "decima.l_rep000".
  131. ASSERT(digits_after_point > 0);
  132. result_builder->AddSubstring(decimal_digits, decimal_point);
  133. result_builder->AddCharacter('.');
  134. ASSERT(length - decimal_point <= digits_after_point);
  135. result_builder->AddSubstring(&decimal_digits[decimal_point],
  136. length - decimal_point);
  137. int remaining_digits = digits_after_point - (length - decimal_point);
  138. result_builder->AddPadding('0', remaining_digits);
  139. }
  140. if (digits_after_point == 0) {
  141. if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
  142. result_builder->AddCharacter('.');
  143. }
  144. if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
  145. result_builder->AddCharacter('0');
  146. }
  147. }
  148. }
  149. bool DoubleToStringConverter::ToShortestIeeeNumber(
  150. double value,
  151. StringBuilder* result_builder,
  152. DoubleToStringConverter::DtoaMode mode) const {
  153. ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE);
  154. if (Double(value).IsSpecial()) {
  155. return HandleSpecialValues(value, result_builder);
  156. }
  157. int decimal_point;
  158. bool sign;
  159. const int kDecimalRepCapacity = kBase10MaximalLength + 1;
  160. char decimal_rep[kDecimalRepCapacity];
  161. int decimal_rep_length;
  162. DoubleToAscii(value, mode, 0, decimal_rep, kDecimalRepCapacity,
  163. &sign, &decimal_rep_length, &decimal_point);
  164. bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
  165. if (sign && (value != 0.0 || !unique_zero)) {
  166. result_builder->AddCharacter('-');
  167. }
  168. int exponent = decimal_point - 1;
  169. if ((decimal_in_shortest_low_ <= exponent) &&
  170. (exponent < decimal_in_shortest_high_)) {
  171. CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
  172. decimal_point,
  173. Max(0, decimal_rep_length - decimal_point),
  174. result_builder);
  175. } else {
  176. CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
  177. result_builder);
  178. }
  179. return true;
  180. }
  181. bool DoubleToStringConverter::ToFixed(double value,
  182. int requested_digits,
  183. StringBuilder* result_builder) const {
  184. ASSERT(kMaxFixedDigitsBeforePoint == 60);
  185. const double kFirstNonFixed = 1e60;
  186. if (Double(value).IsSpecial()) {
  187. return HandleSpecialValues(value, result_builder);
  188. }
  189. if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
  190. if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
  191. // Find a sufficiently precise decimal representation of n.
  192. int decimal_point;
  193. bool sign;
  194. // Add space for the '\0' byte.
  195. const int kDecimalRepCapacity =
  196. kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
  197. char decimal_rep[kDecimalRepCapacity];
  198. int decimal_rep_length;
  199. DoubleToAscii(value, FIXED, requested_digits,
  200. decimal_rep, kDecimalRepCapacity,
  201. &sign, &decimal_rep_length, &decimal_point);
  202. bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
  203. if (sign && (value != 0.0 || !unique_zero)) {
  204. result_builder->AddCharacter('-');
  205. }
  206. CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
  207. requested_digits, result_builder);
  208. return true;
  209. }
  210. bool DoubleToStringConverter::ToExponential(
  211. double value,
  212. int requested_digits,
  213. StringBuilder* result_builder) const {
  214. if (Double(value).IsSpecial()) {
  215. return HandleSpecialValues(value, result_builder);
  216. }
  217. if (requested_digits < -1) return false;
  218. if (requested_digits > kMaxExponentialDigits) return false;
  219. int decimal_point;
  220. bool sign;
  221. // Add space for digit before the decimal point and the '\0' character.
  222. const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
  223. ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
  224. char decimal_rep[kDecimalRepCapacity];
  225. #ifndef NDEBUG
  226. // Problem: there is an assert in StringBuilder::AddSubstring() that
  227. // will pass this buffer to strlen(), and this buffer is not generally
  228. // null-terminated.
  229. memset(decimal_rep, 0, sizeof(decimal_rep));
  230. #endif
  231. int decimal_rep_length;
  232. if (requested_digits == -1) {
  233. DoubleToAscii(value, SHORTEST, 0,
  234. decimal_rep, kDecimalRepCapacity,
  235. &sign, &decimal_rep_length, &decimal_point);
  236. } else {
  237. DoubleToAscii(value, PRECISION, requested_digits + 1,
  238. decimal_rep, kDecimalRepCapacity,
  239. &sign, &decimal_rep_length, &decimal_point);
  240. ASSERT(decimal_rep_length <= requested_digits + 1);
  241. for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
  242. decimal_rep[i] = '0';
  243. }
  244. decimal_rep_length = requested_digits + 1;
  245. }
  246. bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
  247. if (sign && (value != 0.0 || !unique_zero)) {
  248. result_builder->AddCharacter('-');
  249. }
  250. int exponent = decimal_point - 1;
  251. CreateExponentialRepresentation(decimal_rep,
  252. decimal_rep_length,
  253. exponent,
  254. result_builder);
  255. return true;
  256. }
  257. bool DoubleToStringConverter::ToPrecision(double value,
  258. int precision,
  259. StringBuilder* result_builder) const {
  260. if (Double(value).IsSpecial()) {
  261. return HandleSpecialValues(value, result_builder);
  262. }
  263. if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
  264. return false;
  265. }
  266. // Find a sufficiently precise decimal representation of n.
  267. int decimal_point;
  268. bool sign;
  269. // Add one for the terminating null character.
  270. const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
  271. char decimal_rep[kDecimalRepCapacity];
  272. int decimal_rep_length;
  273. DoubleToAscii(value, PRECISION, precision,
  274. decimal_rep, kDecimalRepCapacity,
  275. &sign, &decimal_rep_length, &decimal_point);
  276. ASSERT(decimal_rep_length <= precision);
  277. bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
  278. if (sign && (value != 0.0 || !unique_zero)) {
  279. result_builder->AddCharacter('-');
  280. }
  281. // The exponent if we print the number as x.xxeyyy. That is with the
  282. // decimal point after the first digit.
  283. int exponent = decimal_point - 1;
  284. int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
  285. if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
  286. (decimal_point - precision + extra_zero >
  287. max_trailing_padding_zeroes_in_precision_mode_)) {
  288. // Fill buffer to contain 'precision' digits.
  289. // Usually the buffer is already at the correct length, but 'DoubleToAscii'
  290. // is allowed to return less characters.
  291. for (int i = decimal_rep_length; i < precision; ++i) {
  292. decimal_rep[i] = '0';
  293. }
  294. CreateExponentialRepresentation(decimal_rep,
  295. precision,
  296. exponent,
  297. result_builder);
  298. } else {
  299. CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
  300. Max(0, precision - decimal_point),
  301. result_builder);
  302. }
  303. return true;
  304. }
  305. static BignumDtoaMode DtoaToBignumDtoaMode(
  306. DoubleToStringConverter::DtoaMode dtoa_mode) {
  307. switch (dtoa_mode) {
  308. case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST;
  309. case DoubleToStringConverter::SHORTEST_SINGLE:
  310. return BIGNUM_DTOA_SHORTEST_SINGLE;
  311. case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED;
  312. case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
  313. default:
  314. UNREACHABLE();
  315. }
  316. }
  317. void DoubleToStringConverter::DoubleToAscii(double v,
  318. DtoaMode mode,
  319. int requested_digits,
  320. char* buffer,
  321. int buffer_length,
  322. bool* sign,
  323. int* length,
  324. int* point) {
  325. Vector<char> vector(buffer, buffer_length);
  326. ASSERT(!Double(v).IsSpecial());
  327. ASSERT(mode == SHORTEST || mode == SHORTEST_SINGLE || requested_digits >= 0);
  328. if (Double(v).Sign() < 0) {
  329. *sign = true;
  330. v = -v;
  331. } else {
  332. *sign = false;
  333. }
  334. if (mode == PRECISION && requested_digits == 0) {
  335. vector[0] = '\0';
  336. *length = 0;
  337. return;
  338. }
  339. if (v == 0) {
  340. vector[0] = '0';
  341. vector[1] = '\0';
  342. *length = 1;
  343. *point = 1;
  344. return;
  345. }
  346. bool fast_worked;
  347. switch (mode) {
  348. case SHORTEST:
  349. fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
  350. break;
  351. case SHORTEST_SINGLE:
  352. fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST_SINGLE, 0,
  353. vector, length, point);
  354. break;
  355. case FIXED:
  356. fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
  357. break;
  358. case PRECISION:
  359. fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
  360. vector, length, point);
  361. break;
  362. default:
  363. fast_worked = false;
  364. UNREACHABLE();
  365. }
  366. if (fast_worked) return;
  367. // If the fast dtoa didn't succeed use the slower bignum version.
  368. BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
  369. BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
  370. vector[*length] = '\0';
  371. }
  372. namespace {
  373. inline char ToLower(char ch) {
  374. static const std::ctype<char>& cType =
  375. std::use_facet<std::ctype<char> >(std::locale::classic());
  376. return cType.tolower(ch);
  377. }
  378. inline char Pass(char ch) {
  379. return ch;
  380. }
  381. template <class Iterator, class Converter>
  382. static inline bool ConsumeSubStringImpl(Iterator* current,
  383. Iterator end,
  384. const char* substring,
  385. Converter converter) {
  386. ASSERT(converter(**current) == *substring);
  387. for (substring++; *substring != '\0'; substring++) {
  388. ++*current;
  389. if (*current == end || converter(**current) != *substring) {
  390. return false;
  391. }
  392. }
  393. ++*current;
  394. return true;
  395. }
  396. // Consumes the given substring from the iterator.
  397. // Returns false, if the substring does not match.
  398. template <class Iterator>
  399. static bool ConsumeSubString(Iterator* current,
  400. Iterator end,
  401. const char* substring,
  402. bool allow_case_insensibility) {
  403. if (allow_case_insensibility) {
  404. return ConsumeSubStringImpl(current, end, substring, ToLower);
  405. } else {
  406. return ConsumeSubStringImpl(current, end, substring, Pass);
  407. }
  408. }
  409. // Consumes first character of the str is equal to ch
  410. inline bool ConsumeFirstCharacter(char ch,
  411. const char* str,
  412. bool case_insensibility) {
  413. return case_insensibility ? ToLower(ch) == str[0] : ch == str[0];
  414. }
  415. } // namespace
  416. // Maximum number of significant digits in decimal representation.
  417. // The longest possible double in decimal representation is
  418. // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
  419. // (768 digits). If we parse a number whose first digits are equal to a
  420. // mean of 2 adjacent doubles (that could have up to 769 digits) the result
  421. // must be rounded to the bigger one unless the tail consists of zeros, so
  422. // we don't need to preserve all the digits.
  423. const int kMaxSignificantDigits = 772;
  424. static const char kWhitespaceTable7[] = { 32, 13, 10, 9, 11, 12 };
  425. static const int kWhitespaceTable7Length = ARRAY_SIZE(kWhitespaceTable7);
  426. static const uc16 kWhitespaceTable16[] = {
  427. 160, 8232, 8233, 5760, 6158, 8192, 8193, 8194, 8195,
  428. 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 8287, 12288, 65279
  429. };
  430. static const int kWhitespaceTable16Length = ARRAY_SIZE(kWhitespaceTable16);
  431. static bool isWhitespace(int x) {
  432. if (x < 128) {
  433. for (int i = 0; i < kWhitespaceTable7Length; i++) {
  434. if (kWhitespaceTable7[i] == x) return true;
  435. }
  436. } else {
  437. for (int i = 0; i < kWhitespaceTable16Length; i++) {
  438. if (kWhitespaceTable16[i] == x) return true;
  439. }
  440. }
  441. return false;
  442. }
  443. // Returns true if a nonspace found and false if the end has reached.
  444. template <class Iterator>
  445. static inline bool AdvanceToNonspace(Iterator* current, Iterator end) {
  446. while (*current != end) {
  447. if (!isWhitespace(**current)) return true;
  448. ++*current;
  449. }
  450. return false;
  451. }
  452. static bool isDigit(int x, int radix) {
  453. return (x >= '0' && x <= '9' && x < '0' + radix)
  454. || (radix > 10 && x >= 'a' && x < 'a' + radix - 10)
  455. || (radix > 10 && x >= 'A' && x < 'A' + radix - 10);
  456. }
  457. static double SignedZero(bool sign) {
  458. return sign ? -0.0 : 0.0;
  459. }
  460. // Returns true if 'c' is a decimal digit that is valid for the given radix.
  461. //
  462. // The function is small and could be inlined, but VS2012 emitted a warning
  463. // because it constant-propagated the radix and concluded that the last
  464. // condition was always true. By moving it into a separate function the
  465. // compiler wouldn't warn anymore.
  466. #ifdef _MSC_VER
  467. #pragma optimize("",off)
  468. static bool IsDecimalDigitForRadix(int c, int radix) {
  469. return '0' <= c && c <= '9' && (c - '0') < radix;
  470. }
  471. #pragma optimize("",on)
  472. #else
  473. static bool inline IsDecimalDigitForRadix(int c, int radix) {
  474. return '0' <= c && c <= '9' && (c - '0') < radix;
  475. }
  476. #endif
  477. // Returns true if 'c' is a character digit that is valid for the given radix.
  478. // The 'a_character' should be 'a' or 'A'.
  479. //
  480. // The function is small and could be inlined, but VS2012 emitted a warning
  481. // because it constant-propagated the radix and concluded that the first
  482. // condition was always false. By moving it into a separate function the
  483. // compiler wouldn't warn anymore.
  484. static bool IsCharacterDigitForRadix(int c, int radix, char a_character) {
  485. return radix > 10 && c >= a_character && c < a_character + radix - 10;
  486. }
  487. // Returns true, when the iterator is equal to end.
  488. template<class Iterator>
  489. static bool Advance (Iterator* it, uc16 separator, int base, Iterator& end) {
  490. if (separator == StringToDoubleConverter::kNoSeparator) {
  491. ++(*it);
  492. return *it == end;
  493. }
  494. if (!isDigit(**it, base)) {
  495. ++(*it);
  496. return *it == end;
  497. }
  498. ++(*it);
  499. if (*it == end) return true;
  500. if (*it + 1 == end) return false;
  501. if (**it == separator && isDigit(*(*it + 1), base)) {
  502. ++(*it);
  503. }
  504. return *it == end;
  505. }
  506. // Checks whether the string in the range start-end is a hex-float string.
  507. // This function assumes that the leading '0x'/'0X' is already consumed.
  508. //
  509. // Hex float strings are of one of the following forms:
  510. // - hex_digits+ 'p' ('+'|'-')? exponent_digits+
  511. // - hex_digits* '.' hex_digits+ 'p' ('+'|'-')? exponent_digits+
  512. // - hex_digits+ '.' 'p' ('+'|'-')? exponent_digits+
  513. template<class Iterator>
  514. static bool IsHexFloatString(Iterator start,
  515. Iterator end,
  516. uc16 separator,
  517. bool allow_trailing_junk) {
  518. ASSERT(start != end);
  519. Iterator current = start;
  520. bool saw_digit = false;
  521. while (isDigit(*current, 16)) {
  522. saw_digit = true;
  523. if (Advance(&current, separator, 16, end)) return false;
  524. }
  525. if (*current == '.') {
  526. if (Advance(&current, separator, 16, end)) return false;
  527. while (isDigit(*current, 16)) {
  528. saw_digit = true;
  529. if (Advance(&current, separator, 16, end)) return false;
  530. }
  531. if (!saw_digit) return false; // Only the '.', but no digits.
  532. }
  533. if (*current != 'p' && *current != 'P') return false;
  534. if (Advance(&current, separator, 16, end)) return false;
  535. if (*current == '+' || *current == '-') {
  536. if (Advance(&current, separator, 16, end)) return false;
  537. }
  538. if (!isDigit(*current, 10)) return false;
  539. if (Advance(&current, separator, 16, end)) return true;
  540. while (isDigit(*current, 10)) {
  541. if (Advance(&current, separator, 16, end)) return true;
  542. }
  543. return allow_trailing_junk || !AdvanceToNonspace(&current, end);
  544. }
  545. // Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
  546. //
  547. // If parse_as_hex_float is true, then the string must be a valid
  548. // hex-float.
  549. template <int radix_log_2, class Iterator>
  550. static double RadixStringToIeee(Iterator* current,
  551. Iterator end,
  552. bool sign,
  553. uc16 separator,
  554. bool parse_as_hex_float,
  555. bool allow_trailing_junk,
  556. double junk_string_value,
  557. bool read_as_double,
  558. bool* result_is_junk) {
  559. ASSERT(*current != end);
  560. ASSERT(!parse_as_hex_float ||
  561. IsHexFloatString(*current, end, separator, allow_trailing_junk));
  562. const int kDoubleSize = Double::kSignificandSize;
  563. const int kSingleSize = Single::kSignificandSize;
  564. const int kSignificandSize = read_as_double? kDoubleSize: kSingleSize;
  565. *result_is_junk = true;
  566. int64_t number = 0;
  567. int exponent = 0;
  568. const int radix = (1 << radix_log_2);
  569. // Whether we have encountered a '.' and are parsing the decimal digits.
  570. // Only relevant if parse_as_hex_float is true.
  571. bool post_decimal = false;
  572. // Skip leading 0s.
  573. while (**current == '0') {
  574. if (Advance(current, separator, radix, end)) {
  575. *result_is_junk = false;
  576. return SignedZero(sign);
  577. }
  578. }
  579. while (true) {
  580. int digit;
  581. if (IsDecimalDigitForRadix(**current, radix)) {
  582. digit = static_cast<char>(**current) - '0';
  583. if (post_decimal) exponent -= radix_log_2;
  584. } else if (IsCharacterDigitForRadix(**current, radix, 'a')) {
  585. digit = static_cast<char>(**current) - 'a' + 10;
  586. if (post_decimal) exponent -= radix_log_2;
  587. } else if (IsCharacterDigitForRadix(**current, radix, 'A')) {
  588. digit = static_cast<char>(**current) - 'A' + 10;
  589. if (post_decimal) exponent -= radix_log_2;
  590. } else if (parse_as_hex_float && **current == '.') {
  591. post_decimal = true;
  592. Advance(current, separator, radix, end);
  593. ASSERT(*current != end);
  594. continue;
  595. } else if (parse_as_hex_float && (**current == 'p' || **current == 'P')) {
  596. break;
  597. } else {
  598. if (allow_trailing_junk || !AdvanceToNonspace(current, end)) {
  599. break;
  600. } else {
  601. return junk_string_value;
  602. }
  603. }
  604. number = number * radix + digit;
  605. int overflow = static_cast<int>(number >> kSignificandSize);
  606. if (overflow != 0) {
  607. // Overflow occurred. Need to determine which direction to round the
  608. // result.
  609. int overflow_bits_count = 1;
  610. while (overflow > 1) {
  611. overflow_bits_count++;
  612. overflow >>= 1;
  613. }
  614. int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
  615. int dropped_bits = static_cast<int>(number) & dropped_bits_mask;
  616. number >>= overflow_bits_count;
  617. exponent += overflow_bits_count;
  618. bool zero_tail = true;
  619. for (;;) {
  620. if (Advance(current, separator, radix, end)) break;
  621. if (parse_as_hex_float && **current == '.') {
  622. // Just run over the '.'. We are just trying to see whether there is
  623. // a non-zero digit somewhere.
  624. Advance(current, separator, radix, end);
  625. ASSERT(*current != end);
  626. post_decimal = true;
  627. }
  628. if (!isDigit(**current, radix)) break;
  629. zero_tail = zero_tail && **current == '0';
  630. if (!post_decimal) exponent += radix_log_2;
  631. }
  632. if (!parse_as_hex_float &&
  633. !allow_trailing_junk &&
  634. AdvanceToNonspace(current, end)) {
  635. return junk_string_value;
  636. }
  637. int middle_value = (1 << (overflow_bits_count - 1));
  638. if (dropped_bits > middle_value) {
  639. number++; // Rounding up.
  640. } else if (dropped_bits == middle_value) {
  641. // Rounding to even to consistency with decimals: half-way case rounds
  642. // up if significant part is odd and down otherwise.
  643. if ((number & 1) != 0 || !zero_tail) {
  644. number++; // Rounding up.
  645. }
  646. }
  647. // Rounding up may cause overflow.
  648. if ((number & ((int64_t)1 << kSignificandSize)) != 0) {
  649. exponent++;
  650. number >>= 1;
  651. }
  652. break;
  653. }
  654. if (Advance(current, separator, radix, end)) break;
  655. }
  656. ASSERT(number < ((int64_t)1 << kSignificandSize));
  657. ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
  658. *result_is_junk = false;
  659. if (parse_as_hex_float) {
  660. ASSERT(**current == 'p' || **current == 'P');
  661. Advance(current, separator, radix, end);
  662. ASSERT(*current != end);
  663. bool is_negative = false;
  664. if (**current == '+') {
  665. Advance(current, separator, radix, end);
  666. ASSERT(*current != end);
  667. } else if (**current == '-') {
  668. is_negative = true;
  669. Advance(current, separator, radix, end);
  670. ASSERT(*current != end);
  671. }
  672. int written_exponent = 0;
  673. while (IsDecimalDigitForRadix(**current, 10)) {
  674. written_exponent = 10 * written_exponent + **current - '0';
  675. if (Advance(current, separator, radix, end)) break;
  676. }
  677. if (is_negative) written_exponent = -written_exponent;
  678. exponent += written_exponent;
  679. }
  680. if (exponent == 0 || number == 0) {
  681. if (sign) {
  682. if (number == 0) return -0.0;
  683. number = -number;
  684. }
  685. return static_cast<double>(number);
  686. }
  687. ASSERT(number != 0);
  688. double result = Double(DiyFp(number, exponent)).value();
  689. return sign ? -result : result;
  690. }
  691. template <class Iterator>
  692. double StringToDoubleConverter::StringToIeee(
  693. Iterator input,
  694. int length,
  695. bool read_as_double,
  696. int* processed_characters_count) const {
  697. Iterator current = input;
  698. Iterator end = input + length;
  699. *processed_characters_count = 0;
  700. const bool allow_trailing_junk = (flags_ & ALLOW_TRAILING_JUNK) != 0;
  701. const bool allow_leading_spaces = (flags_ & ALLOW_LEADING_SPACES) != 0;
  702. const bool allow_trailing_spaces = (flags_ & ALLOW_TRAILING_SPACES) != 0;
  703. const bool allow_spaces_after_sign = (flags_ & ALLOW_SPACES_AFTER_SIGN) != 0;
  704. const bool allow_case_insensibility = (flags_ & ALLOW_CASE_INSENSIBILITY) != 0;
  705. // To make sure that iterator dereferencing is valid the following
  706. // convention is used:
  707. // 1. Each '++current' statement is followed by check for equality to 'end'.
  708. // 2. If AdvanceToNonspace returned false then current == end.
  709. // 3. If 'current' becomes equal to 'end' the function returns or goes to
  710. // 'parsing_done'.
  711. // 4. 'current' is not dereferenced after the 'parsing_done' label.
  712. // 5. Code before 'parsing_done' may rely on 'current != end'.
  713. if (current == end) return empty_string_value_;
  714. if (allow_leading_spaces || allow_trailing_spaces) {
  715. if (!AdvanceToNonspace(&current, end)) {
  716. *processed_characters_count = static_cast<int>(current - input);
  717. return empty_string_value_;
  718. }
  719. if (!allow_leading_spaces && (input != current)) {
  720. // No leading spaces allowed, but AdvanceToNonspace moved forward.
  721. return junk_string_value_;
  722. }
  723. }
  724. // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
  725. const int kBufferSize = kMaxSignificantDigits + 10;
  726. char buffer[kBufferSize]; // NOLINT: size is known at compile time.
  727. int buffer_pos = 0;
  728. // Exponent will be adjusted if insignificant digits of the integer part
  729. // or insignificant leading zeros of the fractional part are dropped.
  730. int exponent = 0;
  731. int significant_digits = 0;
  732. int insignificant_digits = 0;
  733. bool nonzero_digit_dropped = false;
  734. bool sign = false;
  735. if (*current == '+' || *current == '-') {
  736. sign = (*current == '-');
  737. ++current;
  738. Iterator next_non_space = current;
  739. // Skip following spaces (if allowed).
  740. if (!AdvanceToNonspace(&next_non_space, end)) return junk_string_value_;
  741. if (!allow_spaces_after_sign && (current != next_non_space)) {
  742. return junk_string_value_;
  743. }
  744. current = next_non_space;
  745. }
  746. if (infinity_symbol_ != NULL) {
  747. if (ConsumeFirstCharacter(*current, infinity_symbol_, allow_case_insensibility)) {
  748. if (!ConsumeSubString(&current, end, infinity_symbol_, allow_case_insensibility)) {
  749. return junk_string_value_;
  750. }
  751. if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
  752. return junk_string_value_;
  753. }
  754. if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
  755. return junk_string_value_;
  756. }
  757. ASSERT(buffer_pos == 0);
  758. *processed_characters_count = static_cast<int>(current - input);
  759. return sign ? -Double::Infinity() : Double::Infinity();
  760. }
  761. }
  762. if (nan_symbol_ != NULL) {
  763. if (ConsumeFirstCharacter(*current, nan_symbol_, allow_case_insensibility)) {
  764. if (!ConsumeSubString(&current, end, nan_symbol_, allow_case_insensibility)) {
  765. return junk_string_value_;
  766. }
  767. if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
  768. return junk_string_value_;
  769. }
  770. if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
  771. return junk_string_value_;
  772. }
  773. ASSERT(buffer_pos == 0);
  774. *processed_characters_count = static_cast<int>(current - input);
  775. return sign ? -Double::NaN() : Double::NaN();
  776. }
  777. }
  778. bool leading_zero = false;
  779. if (*current == '0') {
  780. if (Advance(&current, separator_, 10, end)) {
  781. *processed_characters_count = static_cast<int>(current - input);
  782. return SignedZero(sign);
  783. }
  784. leading_zero = true;
  785. // It could be hexadecimal value.
  786. if (((flags_ & ALLOW_HEX) || (flags_ & ALLOW_HEX_FLOATS)) &&
  787. (*current == 'x' || *current == 'X')) {
  788. ++current;
  789. bool parse_as_hex_float = (flags_ & ALLOW_HEX_FLOATS) &&
  790. IsHexFloatString(current, end, separator_, allow_trailing_junk);
  791. if (current == end) return junk_string_value_; // "0x"
  792. if (!parse_as_hex_float && !isDigit(*current, 16)) {
  793. return junk_string_value_;
  794. }
  795. bool result_is_junk;
  796. double result = RadixStringToIeee<4>(&current,
  797. end,
  798. sign,
  799. separator_,
  800. parse_as_hex_float,
  801. allow_trailing_junk,
  802. junk_string_value_,
  803. read_as_double,
  804. &result_is_junk);
  805. if (!result_is_junk) {
  806. if (allow_trailing_spaces) AdvanceToNonspace(&current, end);
  807. *processed_characters_count = static_cast<int>(current - input);
  808. }
  809. return result;
  810. }
  811. // Ignore leading zeros in the integer part.
  812. while (*current == '0') {
  813. if (Advance(&current, separator_, 10, end)) {
  814. *processed_characters_count = static_cast<int>(current - input);
  815. return SignedZero(sign);
  816. }
  817. }
  818. }
  819. bool octal = leading_zero && (flags_ & ALLOW_OCTALS) != 0;
  820. // Copy significant digits of the integer part (if any) to the buffer.
  821. while (*current >= '0' && *current <= '9') {
  822. if (significant_digits < kMaxSignificantDigits) {
  823. ASSERT(buffer_pos < kBufferSize);
  824. buffer[buffer_pos++] = static_cast<char>(*current);
  825. significant_digits++;
  826. // Will later check if it's an octal in the buffer.
  827. } else {
  828. insignificant_digits++; // Move the digit into the exponential part.
  829. nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
  830. }
  831. octal = octal && *current < '8';
  832. if (Advance(&current, separator_, 10, end)) goto parsing_done;
  833. }
  834. if (significant_digits == 0) {
  835. octal = false;
  836. }
  837. if (*current == '.') {
  838. if (octal && !allow_trailing_junk) return junk_string_value_;
  839. if (octal) goto parsing_done;
  840. if (Advance(&current, separator_, 10, end)) {
  841. if (significant_digits == 0 && !leading_zero) {
  842. return junk_string_value_;
  843. } else {
  844. goto parsing_done;
  845. }
  846. }
  847. if (significant_digits == 0) {
  848. // octal = false;
  849. // Integer part consists of 0 or is absent. Significant digits start after
  850. // leading zeros (if any).
  851. while (*current == '0') {
  852. if (Advance(&current, separator_, 10, end)) {
  853. *processed_characters_count = static_cast<int>(current - input);
  854. return SignedZero(sign);
  855. }
  856. exponent--; // Move this 0 into the exponent.
  857. }
  858. }
  859. // There is a fractional part.
  860. // We don't emit a '.', but adjust the exponent instead.
  861. while (*current >= '0' && *current <= '9') {
  862. if (significant_digits < kMaxSignificantDigits) {
  863. ASSERT(buffer_pos < kBufferSize);
  864. buffer[buffer_pos++] = static_cast<char>(*current);
  865. significant_digits++;
  866. exponent--;
  867. } else {
  868. // Ignore insignificant digits in the fractional part.
  869. nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
  870. }
  871. if (Advance(&current, separator_, 10, end)) goto parsing_done;
  872. }
  873. }
  874. if (!leading_zero && exponent == 0 && significant_digits == 0) {
  875. // If leading_zeros is true then the string contains zeros.
  876. // If exponent < 0 then string was [+-]\.0*...
  877. // If significant_digits != 0 the string is not equal to 0.
  878. // Otherwise there are no digits in the string.
  879. return junk_string_value_;
  880. }
  881. // Parse exponential part.
  882. if (*current == 'e' || *current == 'E') {
  883. if (octal && !allow_trailing_junk) return junk_string_value_;
  884. if (octal) goto parsing_done;
  885. Iterator junk_begin = current;
  886. ++current;
  887. if (current == end) {
  888. if (allow_trailing_junk) {
  889. current = junk_begin;
  890. goto parsing_done;
  891. } else {
  892. return junk_string_value_;
  893. }
  894. }
  895. char exponen_sign = '+';
  896. if (*current == '+' || *current == '-') {
  897. exponen_sign = static_cast<char>(*current);
  898. ++current;
  899. if (current == end) {
  900. if (allow_trailing_junk) {
  901. current = junk_begin;
  902. goto parsing_done;
  903. } else {
  904. return junk_string_value_;
  905. }
  906. }
  907. }
  908. if (current == end || *current < '0' || *current > '9') {
  909. if (allow_trailing_junk) {
  910. current = junk_begin;
  911. goto parsing_done;
  912. } else {
  913. return junk_string_value_;
  914. }
  915. }
  916. const int max_exponent = INT_MAX / 2;
  917. ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
  918. int num = 0;
  919. do {
  920. // Check overflow.
  921. int digit = *current - '0';
  922. if (num >= max_exponent / 10
  923. && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
  924. num = max_exponent;
  925. } else {
  926. num = num * 10 + digit;
  927. }
  928. ++current;
  929. } while (current != end && *current >= '0' && *current <= '9');
  930. exponent += (exponen_sign == '-' ? -num : num);
  931. }
  932. if (!(allow_trailing_spaces || allow_trailing_junk) && (current != end)) {
  933. return junk_string_value_;
  934. }
  935. if (!allow_trailing_junk && AdvanceToNonspace(&current, end)) {
  936. return junk_string_value_;
  937. }
  938. if (allow_trailing_spaces) {
  939. AdvanceToNonspace(&current, end);
  940. }
  941. parsing_done:
  942. exponent += insignificant_digits;
  943. if (octal) {
  944. double result;
  945. bool result_is_junk;
  946. char* start = buffer;
  947. result = RadixStringToIeee<3>(&start,
  948. buffer + buffer_pos,
  949. sign,
  950. separator_,
  951. false, // Don't parse as hex_float.
  952. allow_trailing_junk,
  953. junk_string_value_,
  954. read_as_double,
  955. &result_is_junk);
  956. ASSERT(!result_is_junk);
  957. *processed_characters_count = static_cast<int>(current - input);
  958. return result;
  959. }
  960. if (nonzero_digit_dropped) {
  961. buffer[buffer_pos++] = '1';
  962. exponent--;
  963. }
  964. ASSERT(buffer_pos < kBufferSize);
  965. buffer[buffer_pos] = '\0';
  966. double converted;
  967. if (read_as_double) {
  968. converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
  969. } else {
  970. converted = Strtof(Vector<const char>(buffer, buffer_pos), exponent);
  971. }
  972. *processed_characters_count = static_cast<int>(current - input);
  973. return sign? -converted: converted;
  974. }
  975. double StringToDoubleConverter::StringToDouble(
  976. const char* buffer,
  977. int length,
  978. int* processed_characters_count) const {
  979. return StringToIeee(buffer, length, true, processed_characters_count);
  980. }
  981. double StringToDoubleConverter::StringToDouble(
  982. const uc16* buffer,
  983. int length,
  984. int* processed_characters_count) const {
  985. return StringToIeee(buffer, length, true, processed_characters_count);
  986. }
  987. float StringToDoubleConverter::StringToFloat(
  988. const char* buffer,
  989. int length,
  990. int* processed_characters_count) const {
  991. return static_cast<float>(StringToIeee(buffer, length, false,
  992. processed_characters_count));
  993. }
  994. float StringToDoubleConverter::StringToFloat(
  995. const uc16* buffer,
  996. int length,
  997. int* processed_characters_count) const {
  998. return static_cast<float>(StringToIeee(buffer, length, false,
  999. processed_characters_count));
  1000. }
  1001. } // namespace double_conversion