double-conversion.cc 29 KB

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