28 #ifndef V8_CONVERSIONS_INL_H_
29 #define V8_CONVERSIONS_INL_H_
65 const double k2Pow52 = 4503599627370496.0;
75 memcpy(&result, mantissa_ptr,
sizeof(result));
76 return negative ? ~result + 1 : result;
84 if (
isnan(x))
return 0;
85 if (!
isfinite(x) || x == 0)
return x;
86 return (x >= 0) ? floor(x) : ceil(x);
99 if (exponent > 31)
return 0;
105 template <
class Iterator,
class EndMark>
108 const char* substring) {
109 ASSERT(**current == *substring);
110 for (substring++; *substring !=
'\0'; substring++) {
112 if (*current == end || **current != *substring)
return false;
121 template <
class Iterator,
class EndMark>
125 while (*current != end) {
126 if (!unicode_cache->
IsWhiteSpace(**current))
return true;
134 template <
int radix_log_2,
class Iterator,
class EndMark>
139 bool allow_trailing_junk) {
143 while (*current ==
'0') {
145 if (current == end)
return SignedZero(negative);
150 const int radix = (1 << radix_log_2);
154 if (*current >=
'0' && *current <=
'9' && *current <
'0' + radix) {
155 digit =
static_cast<char>(*current) -
'0';
156 }
else if (radix > 10 && *current >=
'a' && *current <
'a' + radix - 10) {
157 digit =
static_cast<char>(*current) -
'a' + 10;
158 }
else if (radix > 10 && *current >=
'A' && *current <
'A' + radix - 10) {
159 digit =
static_cast<char>(*current) -
'A' + 10;
161 if (allow_trailing_junk ||
169 number = number * radix + digit;
170 int overflow =
static_cast<int>(number >> 53);
174 int overflow_bits_count = 1;
175 while (overflow > 1) {
176 overflow_bits_count++;
180 int dropped_bits_mask = ((1 << overflow_bits_count) - 1);
181 int dropped_bits =
static_cast<int>(number) & dropped_bits_mask;
182 number >>= overflow_bits_count;
183 exponent = overflow_bits_count;
185 bool zero_tail =
true;
188 if (current == end || !
isDigit(*current, radix))
break;
189 zero_tail = zero_tail && *current ==
'0';
190 exponent += radix_log_2;
193 if (!allow_trailing_junk &&
198 int middle_value = (1 << (overflow_bits_count - 1));
199 if (dropped_bits > middle_value) {
201 }
else if (dropped_bits == middle_value) {
204 if ((number & 1) != 0 || !zero_tail) {
210 if ((number & ((int64_t)1 << 53)) != 0) {
217 }
while (current != end);
219 ASSERT(number < ((int64_t)1 << 53));
220 ASSERT(static_cast<int64_t>(static_cast<double>(number)) == number);
224 if (number == 0)
return -0.0;
227 return static_cast<double>(number);
231 return ldexp(static_cast<double>(negative ? -number : number), exponent);
235 template <
class Iterator,
class EndMark>
240 const bool allow_trailing_junk =
true;
244 return empty_string_val;
248 bool leading_zero =
false;
250 if (*current ==
'+') {
253 if (current == end) {
256 }
else if (*current ==
'-') {
258 if (current == end) {
266 if (*current ==
'0') {
268 if (current == end)
return SignedZero(negative);
269 if (*current ==
'x' || *current ==
'X') {
280 }
else if (radix == 16) {
281 if (*current ==
'0') {
284 if (current == end)
return SignedZero(negative);
285 if (*current ==
'x' || *current ==
'X') {
297 while (*current ==
'0') {
300 if (current == end)
return SignedZero(negative);
303 if (!leading_zero && !
isDigit(*current, radix)) {
310 return InternalStringToIntDouble<1>(
311 unicode_cache, current, end,
negative, allow_trailing_junk);
313 return InternalStringToIntDouble<2>(
314 unicode_cache, current, end,
negative, allow_trailing_junk);
316 return InternalStringToIntDouble<3>(
317 unicode_cache, current, end,
negative, allow_trailing_junk);
320 return InternalStringToIntDouble<4>(
321 unicode_cache, current, end,
negative, allow_trailing_junk);
324 return InternalStringToIntDouble<5>(
325 unicode_cache, current, end,
negative, allow_trailing_junk);
336 const int kBufferSize = kMaxSignificantDigits + 2;
337 char buffer[kBufferSize];
339 while (*current >=
'0' && *current <=
'9') {
340 if (buffer_pos <= kMaxSignificantDigits) {
343 ASSERT(buffer_pos < kBufferSize);
344 buffer[buffer_pos++] =
static_cast<char>(*current);
347 if (current == end)
break;
350 if (!allow_trailing_junk &&
355 ASSERT(buffer_pos < kBufferSize);
356 buffer[buffer_pos] =
'\0';
358 return negative ? -
Strtod(buffer_vector, 0) :
Strtod(buffer_vector, 0);
366 int lim_0 =
'0' + (radix < 10 ? radix : 10);
367 int lim_a =
'a' + (radix - 10);
368 int lim_A =
'A' + (radix - 10);
380 unsigned int part = 0, multiplier = 1;
383 if (*current >=
'0' && *current < lim_0) {
385 }
else if (*current >=
'a' && *current < lim_a) {
386 d = *current -
'a' + 10;
387 }
else if (*current >=
'A' && *current < lim_A) {
388 d = *current -
'A' + 10;
398 const unsigned int kMaximumMultiplier = 0xffffffff
U / 36;
399 uint32_t m = multiplier * radix;
400 if (m > kMaximumMultiplier)
break;
401 part = part * radix + d;
403 ASSERT(multiplier > part);
406 if (current == end) {
413 v = v * multiplier + part;
416 if (!allow_trailing_junk &&
421 return negative ? -v : v;
430 template <
class Iterator,
class EndMark>
435 double empty_string_val) {
445 return empty_string_val;
452 char buffer[kBufferSize];
458 int significant_digits = 0;
459 int insignificant_digits = 0;
460 bool nonzero_digit_dropped =
false;
464 if (*current ==
'+') {
468 }
else if (*current ==
'-') {
474 static const char kInfinitySymbol[] =
"Infinity";
475 if (*current == kInfinitySymbol[0]) {
480 if (!allow_trailing_junk &&
489 bool leading_zero =
false;
490 if (*current ==
'0') {
492 if (current == end)
return SignedZero(negative);
497 if ((flags &
ALLOW_HEX) && (*current ==
'x' || *current ==
'X')) {
499 if (current == end || !
isDigit(*current, 16)) {
503 return InternalStringToIntDouble<4>(unicode_cache,
507 allow_trailing_junk);
511 while (*current ==
'0') {
513 if (current == end)
return SignedZero(negative);
517 bool octal = leading_zero && (flags &
ALLOW_OCTALS) != 0;
520 while (*current >=
'0' && *current <=
'9') {
522 ASSERT(buffer_pos < kBufferSize);
523 buffer[buffer_pos++] =
static_cast<char>(*current);
524 significant_digits++;
527 insignificant_digits++;
528 nonzero_digit_dropped = nonzero_digit_dropped || *current !=
'0';
530 octal = octal && *current <
'8';
532 if (current == end)
goto parsing_done;
535 if (significant_digits == 0) {
539 if (*current ==
'.') {
541 if (octal)
goto parsing_done;
544 if (current == end) {
545 if (significant_digits == 0 && !leading_zero) {
552 if (significant_digits == 0) {
556 while (*current ==
'0') {
558 if (current == end)
return SignedZero(negative);
565 while (*current >=
'0' && *current <=
'9') {
567 ASSERT(buffer_pos < kBufferSize);
568 buffer[buffer_pos++] =
static_cast<char>(*current);
569 significant_digits++;
573 nonzero_digit_dropped = nonzero_digit_dropped || *current !=
'0';
576 if (current == end)
goto parsing_done;
580 if (!leading_zero && exponent == 0 && significant_digits == 0) {
589 if (*current ==
'e' || *current ==
'E') {
592 if (current == end) {
593 if (allow_trailing_junk) {
600 if (*current ==
'+' || *current ==
'-') {
601 sign =
static_cast<char>(*current);
603 if (current == end) {
604 if (allow_trailing_junk) {
612 if (current == end || *current < '0' || *current >
'9') {
613 if (allow_trailing_junk) {
620 const int max_exponent = INT_MAX / 2;
621 ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
625 int digit = *current -
'0';
626 if (num >= max_exponent / 10
627 && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
630 num = num * 10 + digit;
633 }
while (current != end && *current >=
'0' && *current <=
'9');
635 exponent += (sign ==
'-' ? -num : num);
638 if (!allow_trailing_junk &&
644 exponent += insignificant_digits;
647 return InternalStringToIntDouble<3>(unicode_cache,
651 allow_trailing_junk);
654 if (nonzero_digit_dropped) {
655 buffer[buffer_pos++] =
'1';
659 ASSERT(buffer_pos < kBufferSize);
660 buffer[buffer_pos] =
'\0';
663 return negative ? -converted : converted;
668 #endif // V8_CONVERSIONS_INL_H_
uint64_t Significand() const
double InternalStringToDouble(UnicodeCache *unicode_cache, Iterator current, EndMark end, int flags, double empty_string_val)
double DoubleToInteger(double x)
bool SubStringEquals(Iterator *current, EndMark end, const char *substring)
const uint64_t kQuietNaNMask
bool isDigit(int x, int radix)
bool IsWhiteSpace(unibrow::uchar c)
double InternalStringToInt(UnicodeCache *unicode_cache, Iterator current, EndMark end, int radix)
#define ASSERT(condition)
static const int kSignificandSize
double Strtod(Vector< const char > buffer, int exponent)
double SignedZero(bool negative)
unsigned int FastD2UI(double x)
double InternalStringToIntDouble(UnicodeCache *unicode_cache, Iterator current, EndMark end, bool negative, bool allow_trailing_junk)
bool AdvanceToNonspace(UnicodeCache *unicode_cache, Iterator *current, EndMark end)
const int kMaxSignificantDigits
int32_t DoubleToInt32(double x)