OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits.h> | 5 #include <limits.h> |
6 #include <stdarg.h> | 6 #include <stdarg.h> |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 } while (n); | 190 } while (n); |
191 if (negative) buffer[--i] = '-'; | 191 if (negative) buffer[--i] = '-'; |
192 return buffer.start() + i; | 192 return buffer.start() + i; |
193 } | 193 } |
194 | 194 |
195 | 195 |
196 char* DoubleToFixedCString(double value, int f) { | 196 char* DoubleToFixedCString(double value, int f) { |
197 const int kMaxDigitsBeforePoint = 21; | 197 const int kMaxDigitsBeforePoint = 21; |
198 const double kFirstNonFixed = 1e21; | 198 const double kFirstNonFixed = 1e21; |
199 const int kMaxDigitsAfterPoint = 20; | 199 const int kMaxDigitsAfterPoint = 20; |
200 ASSERT(f >= 0); | 200 DCHECK(f >= 0); |
201 ASSERT(f <= kMaxDigitsAfterPoint); | 201 DCHECK(f <= kMaxDigitsAfterPoint); |
202 | 202 |
203 bool negative = false; | 203 bool negative = false; |
204 double abs_value = value; | 204 double abs_value = value; |
205 if (value < 0) { | 205 if (value < 0) { |
206 abs_value = -value; | 206 abs_value = -value; |
207 negative = true; | 207 negative = true; |
208 } | 208 } |
209 | 209 |
210 // If abs_value has more than kMaxDigitsBeforePoint digits before the point | 210 // If abs_value has more than kMaxDigitsBeforePoint digits before the point |
211 // use the non-fixed conversion routine. | 211 // use the non-fixed conversion routine. |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 builder.AddCharacter('e'); | 292 builder.AddCharacter('e'); |
293 builder.AddCharacter(negative_exponent ? '-' : '+'); | 293 builder.AddCharacter(negative_exponent ? '-' : '+'); |
294 builder.AddDecimalInteger(exponent); | 294 builder.AddDecimalInteger(exponent); |
295 return builder.Finalize(); | 295 return builder.Finalize(); |
296 } | 296 } |
297 | 297 |
298 | 298 |
299 char* DoubleToExponentialCString(double value, int f) { | 299 char* DoubleToExponentialCString(double value, int f) { |
300 const int kMaxDigitsAfterPoint = 20; | 300 const int kMaxDigitsAfterPoint = 20; |
301 // f might be -1 to signal that f was undefined in JavaScript. | 301 // f might be -1 to signal that f was undefined in JavaScript. |
302 ASSERT(f >= -1 && f <= kMaxDigitsAfterPoint); | 302 DCHECK(f >= -1 && f <= kMaxDigitsAfterPoint); |
303 | 303 |
304 bool negative = false; | 304 bool negative = false; |
305 if (value < 0) { | 305 if (value < 0) { |
306 value = -value; | 306 value = -value; |
307 negative = true; | 307 negative = true; |
308 } | 308 } |
309 | 309 |
310 // Find a sufficiently precise decimal representation of n. | 310 // Find a sufficiently precise decimal representation of n. |
311 int decimal_point; | 311 int decimal_point; |
312 int sign; | 312 int sign; |
313 // f corresponds to the digits after the point. There is always one digit | 313 // f corresponds to the digits after the point. There is always one digit |
314 // before the point. The number of requested_digits equals hence f + 1. | 314 // before the point. The number of requested_digits equals hence f + 1. |
315 // And we have to add one character for the null-terminator. | 315 // And we have to add one character for the null-terminator. |
316 const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1; | 316 const int kV8DtoaBufferCapacity = kMaxDigitsAfterPoint + 1 + 1; |
317 // Make sure that the buffer is big enough, even if we fall back to the | 317 // Make sure that the buffer is big enough, even if we fall back to the |
318 // shortest representation (which happens when f equals -1). | 318 // shortest representation (which happens when f equals -1). |
319 ASSERT(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1); | 319 DCHECK(kBase10MaximalLength <= kMaxDigitsAfterPoint + 1); |
320 char decimal_rep[kV8DtoaBufferCapacity]; | 320 char decimal_rep[kV8DtoaBufferCapacity]; |
321 int decimal_rep_length; | 321 int decimal_rep_length; |
322 | 322 |
323 if (f == -1) { | 323 if (f == -1) { |
324 DoubleToAscii(value, DTOA_SHORTEST, 0, | 324 DoubleToAscii(value, DTOA_SHORTEST, 0, |
325 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), | 325 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
326 &sign, &decimal_rep_length, &decimal_point); | 326 &sign, &decimal_rep_length, &decimal_point); |
327 f = decimal_rep_length - 1; | 327 f = decimal_rep_length - 1; |
328 } else { | 328 } else { |
329 DoubleToAscii(value, DTOA_PRECISION, f + 1, | 329 DoubleToAscii(value, DTOA_PRECISION, f + 1, |
330 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), | 330 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
331 &sign, &decimal_rep_length, &decimal_point); | 331 &sign, &decimal_rep_length, &decimal_point); |
332 } | 332 } |
333 ASSERT(decimal_rep_length > 0); | 333 DCHECK(decimal_rep_length > 0); |
334 ASSERT(decimal_rep_length <= f + 1); | 334 DCHECK(decimal_rep_length <= f + 1); |
335 | 335 |
336 int exponent = decimal_point - 1; | 336 int exponent = decimal_point - 1; |
337 char* result = | 337 char* result = |
338 CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1); | 338 CreateExponentialRepresentation(decimal_rep, exponent, negative, f+1); |
339 | 339 |
340 return result; | 340 return result; |
341 } | 341 } |
342 | 342 |
343 | 343 |
344 char* DoubleToPrecisionCString(double value, int p) { | 344 char* DoubleToPrecisionCString(double value, int p) { |
345 const int kMinimalDigits = 1; | 345 const int kMinimalDigits = 1; |
346 const int kMaximalDigits = 21; | 346 const int kMaximalDigits = 21; |
347 ASSERT(p >= kMinimalDigits && p <= kMaximalDigits); | 347 DCHECK(p >= kMinimalDigits && p <= kMaximalDigits); |
348 USE(kMinimalDigits); | 348 USE(kMinimalDigits); |
349 | 349 |
350 bool negative = false; | 350 bool negative = false; |
351 if (value < 0) { | 351 if (value < 0) { |
352 value = -value; | 352 value = -value; |
353 negative = true; | 353 negative = true; |
354 } | 354 } |
355 | 355 |
356 // Find a sufficiently precise decimal representation of n. | 356 // Find a sufficiently precise decimal representation of n. |
357 int decimal_point; | 357 int decimal_point; |
358 int sign; | 358 int sign; |
359 // Add one for the terminating null character. | 359 // Add one for the terminating null character. |
360 const int kV8DtoaBufferCapacity = kMaximalDigits + 1; | 360 const int kV8DtoaBufferCapacity = kMaximalDigits + 1; |
361 char decimal_rep[kV8DtoaBufferCapacity]; | 361 char decimal_rep[kV8DtoaBufferCapacity]; |
362 int decimal_rep_length; | 362 int decimal_rep_length; |
363 | 363 |
364 DoubleToAscii(value, DTOA_PRECISION, p, | 364 DoubleToAscii(value, DTOA_PRECISION, p, |
365 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), | 365 Vector<char>(decimal_rep, kV8DtoaBufferCapacity), |
366 &sign, &decimal_rep_length, &decimal_point); | 366 &sign, &decimal_rep_length, &decimal_point); |
367 ASSERT(decimal_rep_length <= p); | 367 DCHECK(decimal_rep_length <= p); |
368 | 368 |
369 int exponent = decimal_point - 1; | 369 int exponent = decimal_point - 1; |
370 | 370 |
371 char* result = NULL; | 371 char* result = NULL; |
372 | 372 |
373 if (exponent < -6 || exponent >= p) { | 373 if (exponent < -6 || exponent >= p) { |
374 result = | 374 result = |
375 CreateExponentialRepresentation(decimal_rep, exponent, negative, p); | 375 CreateExponentialRepresentation(decimal_rep, exponent, negative, p); |
376 } else { | 376 } else { |
377 // Use fixed notation. | 377 // Use fixed notation. |
(...skipping 27 matching lines...) Expand all Loading... |
405 } | 405 } |
406 } | 406 } |
407 result = builder.Finalize(); | 407 result = builder.Finalize(); |
408 } | 408 } |
409 | 409 |
410 return result; | 410 return result; |
411 } | 411 } |
412 | 412 |
413 | 413 |
414 char* DoubleToRadixCString(double value, int radix) { | 414 char* DoubleToRadixCString(double value, int radix) { |
415 ASSERT(radix >= 2 && radix <= 36); | 415 DCHECK(radix >= 2 && radix <= 36); |
416 | 416 |
417 // Character array used for conversion. | 417 // Character array used for conversion. |
418 static const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; | 418 static const char chars[] = "0123456789abcdefghijklmnopqrstuvwxyz"; |
419 | 419 |
420 // Buffer for the integer part of the result. 1024 chars is enough | 420 // Buffer for the integer part of the result. 1024 chars is enough |
421 // for max integer value in radix 2. We need room for a sign too. | 421 // for max integer value in radix 2. We need room for a sign too. |
422 static const int kBufferSize = 1100; | 422 static const int kBufferSize = 1100; |
423 char integer_buffer[kBufferSize]; | 423 char integer_buffer[kBufferSize]; |
424 integer_buffer[kBufferSize - 1] = '\0'; | 424 integer_buffer[kBufferSize - 1] = '\0'; |
425 | 425 |
(...skipping 13 matching lines...) Expand all Loading... |
439 // Convert the integer part starting from the back. Always generate | 439 // Convert the integer part starting from the back. Always generate |
440 // at least one digit. | 440 // at least one digit. |
441 int integer_pos = kBufferSize - 2; | 441 int integer_pos = kBufferSize - 2; |
442 do { | 442 do { |
443 double remainder = std::fmod(integer_part, radix); | 443 double remainder = std::fmod(integer_part, radix); |
444 integer_buffer[integer_pos--] = chars[static_cast<int>(remainder)]; | 444 integer_buffer[integer_pos--] = chars[static_cast<int>(remainder)]; |
445 integer_part -= remainder; | 445 integer_part -= remainder; |
446 integer_part /= radix; | 446 integer_part /= radix; |
447 } while (integer_part >= 1.0); | 447 } while (integer_part >= 1.0); |
448 // Sanity check. | 448 // Sanity check. |
449 ASSERT(integer_pos > 0); | 449 DCHECK(integer_pos > 0); |
450 // Add sign if needed. | 450 // Add sign if needed. |
451 if (is_negative) integer_buffer[integer_pos--] = '-'; | 451 if (is_negative) integer_buffer[integer_pos--] = '-'; |
452 | 452 |
453 // Convert the decimal part. Repeatedly multiply by the radix to | 453 // Convert the decimal part. Repeatedly multiply by the radix to |
454 // generate the next char. Never generate more than kBufferSize - 1 | 454 // generate the next char. Never generate more than kBufferSize - 1 |
455 // chars. | 455 // chars. |
456 // | 456 // |
457 // TODO(1093998): We will often generate a full decimal_buffer of | 457 // TODO(1093998): We will often generate a full decimal_buffer of |
458 // chars because hitting zero will often not happen. The right | 458 // chars because hitting zero will often not happen. The right |
459 // solution would be to continue until the string representation can | 459 // solution would be to continue until the string representation can |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 return StringToDouble( | 494 return StringToDouble( |
495 unicode_cache, flat.ToOneByteVector(), flags, empty_string_val); | 495 unicode_cache, flat.ToOneByteVector(), flags, empty_string_val); |
496 } else { | 496 } else { |
497 return StringToDouble( | 497 return StringToDouble( |
498 unicode_cache, flat.ToUC16Vector(), flags, empty_string_val); | 498 unicode_cache, flat.ToUC16Vector(), flags, empty_string_val); |
499 } | 499 } |
500 } | 500 } |
501 | 501 |
502 | 502 |
503 } } // namespace v8::internal | 503 } } // namespace v8::internal |
OLD | NEW |