Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: Source/wtf/dtoa/double-conversion.cc

Issue 20652002: Fix trailing whitespace in scripts and misc. files (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Don't change literal diff. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/wtf/dtoa/diy-fp.cc ('k') | Source/wtf/dtoa/fast-dtoa.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 24 matching lines...) Expand all
35 #include "bignum-dtoa.h" 35 #include "bignum-dtoa.h"
36 #include "double.h" 36 #include "double.h"
37 #include "fast-dtoa.h" 37 #include "fast-dtoa.h"
38 #include "fixed-dtoa.h" 38 #include "fixed-dtoa.h"
39 #include "strtod.h" 39 #include "strtod.h"
40 #include "utils.h" 40 #include "utils.h"
41 41
42 namespace WTF { 42 namespace WTF {
43 43
44 namespace double_conversion { 44 namespace double_conversion {
45 45
46 const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter( ) { 46 const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter( ) {
47 int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN; 47 int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
48 static DoubleToStringConverter converter(flags, 48 static DoubleToStringConverter converter(flags,
49 "Infinity", 49 "Infinity",
50 "NaN", 50 "NaN",
51 'e', 51 'e',
52 -6, 21, 52 -6, 21,
53 6, 0); 53 6, 0);
54 return converter; 54 return converter;
55 } 55 }
56 56
57 57
58 bool DoubleToStringConverter::HandleSpecialValues( 58 bool DoubleToStringConverter::HandleSpecialValues(
59 double value, 59 double value,
60 StringBuilder* result_buil der) const { 60 StringBuilder* result_buil der) const {
61 Double double_inspect(value); 61 Double double_inspect(value);
62 if (double_inspect.IsInfinite()) { 62 if (double_inspect.IsInfinite()) {
63 if (infinity_symbol_ == NULL) return false; 63 if (infinity_symbol_ == NULL) return false;
64 if (value < 0) { 64 if (value < 0) {
65 result_builder->AddCharacter('-'); 65 result_builder->AddCharacter('-');
66 } 66 }
67 result_builder->AddString(infinity_symbol_); 67 result_builder->AddString(infinity_symbol_);
68 return true; 68 return true;
69 } 69 }
70 if (double_inspect.IsNan()) { 70 if (double_inspect.IsNan()) {
71 if (nan_symbol_ == NULL) return false; 71 if (nan_symbol_ == NULL) return false;
72 result_builder->AddString(nan_symbol_); 72 result_builder->AddString(nan_symbol_);
73 return true; 73 return true;
74 } 74 }
75 return false; 75 return false;
76 } 76 }
77 77
78 78
79 void DoubleToStringConverter::CreateExponentialRepresentation( 79 void DoubleToStringConverter::CreateExponentialRepresentation(
80 const char* de cimal_digits, 80 const char* de cimal_digits,
81 int length, 81 int length,
82 int exponent, 82 int exponent,
83 StringBuilder* result_builder) const { 83 StringBuilder* result_builder) const {
84 ASSERT(length != 0); 84 ASSERT(length != 0);
85 result_builder->AddCharacter(decimal_digits[0]); 85 result_builder->AddCharacter(decimal_digits[0]);
86 if (length != 1) { 86 if (length != 1) {
87 result_builder->AddCharacter('.'); 87 result_builder->AddCharacter('.');
88 result_builder->AddSubstring(&decimal_digits[1], length-1); 88 result_builder->AddSubstring(&decimal_digits[1], length-1);
(...skipping 16 matching lines...) Expand all
105 char buffer[kMaxExponentLength + 1]; 105 char buffer[kMaxExponentLength + 1];
106 int first_char_pos = kMaxExponentLength; 106 int first_char_pos = kMaxExponentLength;
107 buffer[first_char_pos] = '\0'; 107 buffer[first_char_pos] = '\0';
108 while (exponent > 0) { 108 while (exponent > 0) {
109 buffer[--first_char_pos] = '0' + (exponent % 10); 109 buffer[--first_char_pos] = '0' + (exponent % 10);
110 exponent /= 10; 110 exponent /= 10;
111 } 111 }
112 result_builder->AddSubstring(&buffer[first_char_pos], 112 result_builder->AddSubstring(&buffer[first_char_pos],
113 kMaxExponentLength - first_char_pos); 113 kMaxExponentLength - first_char_pos);
114 } 114 }
115 115
116 116
117 void DoubleToStringConverter::CreateDecimalRepresentation( 117 void DoubleToStringConverter::CreateDecimalRepresentation(
118 const char* decima l_digits, 118 const char* decima l_digits,
119 int length, 119 int length,
120 int decimal_point, 120 int decimal_point,
121 int digits_after_p oint, 121 int digits_after_p oint,
122 StringBuilder* res ult_builder) const { 122 StringBuilder* res ult_builder) const {
123 // Create a representation that is padded with zeros if needed. 123 // Create a representation that is padded with zeros if needed.
124 if (decimal_point <= 0) { 124 if (decimal_point <= 0) {
125 // "0.00000decimal_rep". 125 // "0.00000decimal_rep".
126 result_builder->AddCharacter('0'); 126 result_builder->AddCharacter('0');
(...skipping 26 matching lines...) Expand all
153 } 153 }
154 if (digits_after_point == 0) { 154 if (digits_after_point == 0) {
155 if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) { 155 if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
156 result_builder->AddCharacter('.'); 156 result_builder->AddCharacter('.');
157 } 157 }
158 if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) { 158 if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
159 result_builder->AddCharacter('0'); 159 result_builder->AddCharacter('0');
160 } 160 }
161 } 161 }
162 } 162 }
163 163
164 164
165 bool DoubleToStringConverter::ToShortest(double value, 165 bool DoubleToStringConverter::ToShortest(double value,
166 StringBuilder* result_builder) cons t { 166 StringBuilder* result_builder) cons t {
167 if (Double(value).IsSpecial()) { 167 if (Double(value).IsSpecial()) {
168 return HandleSpecialValues(value, result_builder); 168 return HandleSpecialValues(value, result_builder);
169 } 169 }
170 170
171 int decimal_point; 171 int decimal_point;
172 bool sign; 172 bool sign;
173 const int kDecimalRepCapacity = kBase10MaximalLength + 1; 173 const int kDecimalRepCapacity = kBase10MaximalLength + 1;
174 char decimal_rep[kDecimalRepCapacity]; 174 char decimal_rep[kDecimalRepCapacity];
175 int decimal_rep_length; 175 int decimal_rep_length;
176 176
177 DoubleToAscii(value, SHORTEST, 0, decimal_rep, kDecimalRepCapacity, 177 DoubleToAscii(value, SHORTEST, 0, decimal_rep, kDecimalRepCapacity,
178 &sign, &decimal_rep_length, &decimal_point); 178 &sign, &decimal_rep_length, &decimal_point);
179 179
180 bool unique_zero = (flags_ & UNIQUE_ZERO) != 0; 180 bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
181 if (sign && (value != 0.0 || !unique_zero)) { 181 if (sign && (value != 0.0 || !unique_zero)) {
182 result_builder->AddCharacter('-'); 182 result_builder->AddCharacter('-');
183 } 183 }
184 184
185 int exponent = decimal_point - 1; 185 int exponent = decimal_point - 1;
186 if ((decimal_in_shortest_low_ <= exponent) && 186 if ((decimal_in_shortest_low_ <= exponent) &&
187 (exponent < decimal_in_shortest_high_)) { 187 (exponent < decimal_in_shortest_high_)) {
188 CreateDecimalRepresentation(decimal_rep, decimal_rep_length, 188 CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
189 decimal_point, 189 decimal_point,
190 Max(0, decimal_rep_length - decimal_poin t), 190 Max(0, decimal_rep_length - decimal_poin t),
191 result_builder); 191 result_builder);
192 } else { 192 } else {
193 CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exp onent, 193 CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exp onent,
194 result_builder); 194 result_builder);
195 } 195 }
196 return true; 196 return true;
197 } 197 }
198 198
199 199
200 bool DoubleToStringConverter::ToFixed(double value, 200 bool DoubleToStringConverter::ToFixed(double value,
201 int requested_digits, 201 int requested_digits,
202 StringBuilder* result_builder) const { 202 StringBuilder* result_builder) const {
203 ASSERT(kMaxFixedDigitsBeforePoint == 60); 203 ASSERT(kMaxFixedDigitsBeforePoint == 60);
204 const double kFirstNonFixed = 1e60; 204 const double kFirstNonFixed = 1e60;
205 205
206 if (Double(value).IsSpecial()) { 206 if (Double(value).IsSpecial()) {
207 return HandleSpecialValues(value, result_builder); 207 return HandleSpecialValues(value, result_builder);
208 } 208 }
209 209
210 if (requested_digits > kMaxFixedDigitsAfterPoint) return false; 210 if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
211 if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false; 211 if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;
212 212
213 // Find a sufficiently precise decimal representation of n. 213 // Find a sufficiently precise decimal representation of n.
214 int decimal_point; 214 int decimal_point;
215 bool sign; 215 bool sign;
216 // Add space for the '\0' byte. 216 // Add space for the '\0' byte.
217 const int kDecimalRepCapacity = 217 const int kDecimalRepCapacity =
218 kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1; 218 kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
219 char decimal_rep[kDecimalRepCapacity]; 219 char decimal_rep[kDecimalRepCapacity];
220 int decimal_rep_length; 220 int decimal_rep_length;
221 DoubleToAscii(value, FIXED, requested_digits, 221 DoubleToAscii(value, FIXED, requested_digits,
222 decimal_rep, kDecimalRepCapacity, 222 decimal_rep, kDecimalRepCapacity,
223 &sign, &decimal_rep_length, &decimal_point); 223 &sign, &decimal_rep_length, &decimal_point);
224 224
225 bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); 225 bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
226 if (sign && (value != 0.0 || !unique_zero)) { 226 if (sign && (value != 0.0 || !unique_zero)) {
227 result_builder->AddCharacter('-'); 227 result_builder->AddCharacter('-');
228 } 228 }
229 229
230 CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_poi nt, 230 CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_poi nt,
231 requested_digits, result_builder); 231 requested_digits, result_builder);
232 return true; 232 return true;
233 } 233 }
234 234
235 235
236 bool DoubleToStringConverter::ToExponential( 236 bool DoubleToStringConverter::ToExponential(
237 double value, 237 double value,
238 int requested_digits, 238 int requested_digits,
239 StringBuilder* result_builder) c onst { 239 StringBuilder* result_builder) c onst {
240 if (Double(value).IsSpecial()) { 240 if (Double(value).IsSpecial()) {
241 return HandleSpecialValues(value, result_builder); 241 return HandleSpecialValues(value, result_builder);
242 } 242 }
243 243
244 if (requested_digits < -1) return false; 244 if (requested_digits < -1) return false;
245 if (requested_digits > kMaxExponentialDigits) return false; 245 if (requested_digits > kMaxExponentialDigits) return false;
246 246
247 int decimal_point; 247 int decimal_point;
248 bool sign; 248 bool sign;
249 // Add space for digit before the decimal point and the '\0' character. 249 // Add space for digit before the decimal point and the '\0' character.
250 const int kDecimalRepCapacity = kMaxExponentialDigits + 2; 250 const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
251 ASSERT(kDecimalRepCapacity > kBase10MaximalLength); 251 ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
252 char decimal_rep[kDecimalRepCapacity]; 252 char decimal_rep[kDecimalRepCapacity];
253 int decimal_rep_length; 253 int decimal_rep_length;
254 254
255 if (requested_digits == -1) { 255 if (requested_digits == -1) {
256 DoubleToAscii(value, SHORTEST, 0, 256 DoubleToAscii(value, SHORTEST, 0,
257 decimal_rep, kDecimalRepCapacity, 257 decimal_rep, kDecimalRepCapacity,
258 &sign, &decimal_rep_length, &decimal_point); 258 &sign, &decimal_rep_length, &decimal_point);
259 } else { 259 } else {
260 DoubleToAscii(value, PRECISION, requested_digits + 1, 260 DoubleToAscii(value, PRECISION, requested_digits + 1,
261 decimal_rep, kDecimalRepCapacity, 261 decimal_rep, kDecimalRepCapacity,
262 &sign, &decimal_rep_length, &decimal_point); 262 &sign, &decimal_rep_length, &decimal_point);
263 ASSERT(decimal_rep_length <= requested_digits + 1); 263 ASSERT(decimal_rep_length <= requested_digits + 1);
264 264
265 for (int i = decimal_rep_length; i < requested_digits + 1; ++i) { 265 for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
266 decimal_rep[i] = '0'; 266 decimal_rep[i] = '0';
267 } 267 }
268 decimal_rep_length = requested_digits + 1; 268 decimal_rep_length = requested_digits + 1;
269 } 269 }
270 270
271 bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); 271 bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
272 if (sign && (value != 0.0 || !unique_zero)) { 272 if (sign && (value != 0.0 || !unique_zero)) {
273 result_builder->AddCharacter('-'); 273 result_builder->AddCharacter('-');
274 } 274 }
275 275
276 int exponent = decimal_point - 1; 276 int exponent = decimal_point - 1;
277 CreateExponentialRepresentation(decimal_rep, 277 CreateExponentialRepresentation(decimal_rep,
278 decimal_rep_length, 278 decimal_rep_length,
279 exponent, 279 exponent,
280 result_builder); 280 result_builder);
281 return true; 281 return true;
282 } 282 }
283 283
284 284
285 bool DoubleToStringConverter::ToPrecision(double value, 285 bool DoubleToStringConverter::ToPrecision(double value,
286 int precision, 286 int precision,
287 StringBuilder* result_builder) con st { 287 StringBuilder* result_builder) con st {
288 if (Double(value).IsSpecial()) { 288 if (Double(value).IsSpecial()) {
289 return HandleSpecialValues(value, result_builder); 289 return HandleSpecialValues(value, result_builder);
290 } 290 }
291 291
292 if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) { 292 if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
293 return false; 293 return false;
294 } 294 }
295 295
296 // Find a sufficiently precise decimal representation of n. 296 // Find a sufficiently precise decimal representation of n.
297 int decimal_point; 297 int decimal_point;
298 bool sign; 298 bool sign;
299 // Add one for the terminating null character. 299 // Add one for the terminating null character.
300 const int kDecimalRepCapacity = kMaxPrecisionDigits + 1; 300 const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
301 char decimal_rep[kDecimalRepCapacity]; 301 char decimal_rep[kDecimalRepCapacity];
302 int decimal_rep_length; 302 int decimal_rep_length;
303 303
304 DoubleToAscii(value, PRECISION, precision, 304 DoubleToAscii(value, PRECISION, precision,
305 decimal_rep, kDecimalRepCapacity, 305 decimal_rep, kDecimalRepCapacity,
306 &sign, &decimal_rep_length, &decimal_point); 306 &sign, &decimal_rep_length, &decimal_point);
307 ASSERT(decimal_rep_length <= precision); 307 ASSERT(decimal_rep_length <= precision);
308 308
309 bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0); 309 bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
310 if (sign && (value != 0.0 || !unique_zero)) { 310 if (sign && (value != 0.0 || !unique_zero)) {
311 result_builder->AddCharacter('-'); 311 result_builder->AddCharacter('-');
312 } 312 }
313 313
314 // The exponent if we print the number as x.xxeyyy. That is with the 314 // The exponent if we print the number as x.xxeyyy. That is with the
315 // decimal point after the first digit. 315 // decimal point after the first digit.
316 int exponent = decimal_point - 1; 316 int exponent = decimal_point - 1;
317 317
318 int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0; 318 int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
319 if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) || 319 if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
320 (decimal_point - precision + extra_zero > 320 (decimal_point - precision + extra_zero >
321 max_trailing_padding_zeroes_in_precision_mode_)) { 321 max_trailing_padding_zeroes_in_precision_mode_)) {
322 // Fill buffer to contain 'precision' digits. 322 // Fill buffer to contain 'precision' digits.
323 // Usually the buffer is already at the correct length, but 'Dou bleToAscii' 323 // Usually the buffer is already at the correct length, but 'Dou bleToAscii'
324 // is allowed to return less characters. 324 // is allowed to return less characters.
325 for (int i = decimal_rep_length; i < precision; ++i) { 325 for (int i = decimal_rep_length; i < precision; ++i) {
326 decimal_rep[i] = '0'; 326 decimal_rep[i] = '0';
327 } 327 }
328 328
329 CreateExponentialRepresentation(decimal_rep, 329 CreateExponentialRepresentation(decimal_rep,
330 precision, 330 precision,
331 exponent, 331 exponent,
332 result_builder); 332 result_builder);
333 } else { 333 } else {
334 CreateDecimalRepresentation(decimal_rep, decimal_rep_length, dec imal_point, 334 CreateDecimalRepresentation(decimal_rep, decimal_rep_length, dec imal_point,
335 Max(0, precision - decimal_point), 335 Max(0, precision - decimal_point),
336 result_builder); 336 result_builder);
337 } 337 }
338 return true; 338 return true;
339 } 339 }
340 340
341 341
342 static BignumDtoaMode DtoaToBignumDtoaMode( 342 static BignumDtoaMode DtoaToBignumDtoaMode(
343 DoubleToStringConverter::DtoaMode dtoa_mode) { 343 DoubleToStringConverter::DtoaMode dtoa_mode) {
344 switch (dtoa_mode) { 344 switch (dtoa_mode) {
345 case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST ; 345 case DoubleToStringConverter::SHORTEST: return BIGNUM_DTOA_SHORTEST ;
346 case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED; 346 case DoubleToStringConverter::FIXED: return BIGNUM_DTOA_FIXED;
347 case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISIO N; 347 case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISIO N;
348 default: 348 default:
349 UNREACHABLE(); 349 UNREACHABLE();
350 return BIGNUM_DTOA_SHORTEST; // To silence compiler. 350 return BIGNUM_DTOA_SHORTEST; // To silence compiler.
351 } 351 }
352 } 352 }
353 353
354 354
355 void DoubleToStringConverter::DoubleToAscii(double v, 355 void DoubleToStringConverter::DoubleToAscii(double v,
356 DtoaMode mode, 356 DtoaMode mode,
357 int requested_digits, 357 int requested_digits,
358 char* buffer, 358 char* buffer,
359 int buffer_length, 359 int buffer_length,
360 bool* sign, 360 bool* sign,
361 int* length, 361 int* length,
362 int* point) { 362 int* point) {
363 Vector<char> vector(buffer, buffer_length); 363 Vector<char> vector(buffer, buffer_length);
364 ASSERT(!Double(v).IsSpecial()); 364 ASSERT(!Double(v).IsSpecial());
365 ASSERT(mode == SHORTEST || requested_digits >= 0); 365 ASSERT(mode == SHORTEST || requested_digits >= 0);
366 366
367 if (Double(v).Sign() < 0) { 367 if (Double(v).Sign() < 0) {
368 *sign = true; 368 *sign = true;
369 v = -v; 369 v = -v;
370 } else { 370 } else {
371 *sign = false; 371 *sign = false;
372 } 372 }
373 373
374 if (mode == PRECISION && requested_digits == 0) { 374 if (mode == PRECISION && requested_digits == 0) {
375 vector[0] = '\0'; 375 vector[0] = '\0';
376 *length = 0; 376 *length = 0;
377 return; 377 return;
378 } 378 }
379 379
380 if (v == 0) { 380 if (v == 0) {
381 vector[0] = '0'; 381 vector[0] = '0';
382 vector[1] = '\0'; 382 vector[1] = '\0';
383 *length = 1; 383 *length = 1;
384 *point = 1; 384 *point = 1;
385 return; 385 return;
386 } 386 }
387 387
388 bool fast_worked; 388 bool fast_worked;
389 switch (mode) { 389 switch (mode) {
390 case SHORTEST: 390 case SHORTEST:
391 fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point); 391 fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
392 break; 392 break;
393 case FIXED: 393 case FIXED:
394 fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point); 394 fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
395 break; 395 break;
396 case PRECISION: 396 case PRECISION:
397 fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits, 397 fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
398 vector, length, point); 398 vector, length, point);
399 break; 399 break;
400 default: 400 default:
401 UNREACHABLE(); 401 UNREACHABLE();
402 fast_worked = false; 402 fast_worked = false;
403 } 403 }
404 if (fast_worked) return; 404 if (fast_worked) return;
405 405
406 // If the fast dtoa didn't succeed use the slower bignum version. 406 // If the fast dtoa didn't succeed use the slower bignum version.
407 BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode); 407 BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
408 BignumDtoa(v, bignum_mode, requested_digits, vector, length, point); 408 BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
409 vector[*length] = '\0'; 409 vector[*length] = '\0';
410 } 410 }
411 411
412 412
413 // Maximum number of significant digits in decimal representation. 413 // Maximum number of significant digits in decimal representation.
414 // The longest possible double in decimal representation is 414 // The longest possible double in decimal representation is
415 // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074 415 // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
416 // (768 digits). If we parse a number whose first digits are equal to a 416 // (768 digits). If we parse a number whose first digits are equal to a
417 // mean of 2 adjacent doubles (that could have up to 769 digits) the result 417 // mean of 2 adjacent doubles (that could have up to 769 digits) the result
418 // must be rounded to the bigger one unless the tail consists of zeros, so 418 // must be rounded to the bigger one unless the tail consists of zeros, so
419 // we don't need to preserve all the digits. 419 // we don't need to preserve all the digits.
420 const int kMaxSignificantDigits = 772; 420 const int kMaxSignificantDigits = 772;
421 421
422 422
423 static double SignedZero(bool sign) { 423 static double SignedZero(bool sign) {
424 return sign ? -0.0 : 0.0; 424 return sign ? -0.0 : 0.0;
425 } 425 }
426 426
427 427
428 double StringToDoubleConverter::StringToDouble( 428 double StringToDoubleConverter::StringToDouble(
429 const char* input, 429 const char* input,
430 size_t length, 430 size_t length,
431 size_t* processed_characters_ count) { 431 size_t* processed_characters_ count) {
432 const char* current = input; 432 const char* current = input;
433 const char* end = input + length; 433 const char* end = input + length;
434 434
435 *processed_characters_count = 0; 435 *processed_characters_count = 0;
436 436
437 // To make sure that iterator dereferencing is valid the following 437 // To make sure that iterator dereferencing is valid the following
438 // convention is used: 438 // convention is used:
439 // 1. Each '++current' statement is followed by check for equality to 'e nd'. 439 // 1. Each '++current' statement is followed by check for equality to 'e nd'.
440 // 3. If 'current' becomes equal to 'end' the function returns or goes t o 440 // 3. If 'current' becomes equal to 'end' the function returns or goes t o
441 // 'parsing_done'. 441 // 'parsing_done'.
442 // 4. 'current' is not dereferenced after the 'parsing_done' label. 442 // 4. 'current' is not dereferenced after the 'parsing_done' label.
443 // 5. Code before 'parsing_done' may rely on 'current != end'. 443 // 5. Code before 'parsing_done' may rely on 'current != end'.
444 if (current == end) return 0.0; 444 if (current == end) return 0.0;
445 445
446 // The longest form of simplified number is: "-<significant digits>.1eXX X\0". 446 // The longest form of simplified number is: "-<significant digits>.1eXX X\0".
447 const int kBufferSize = kMaxSignificantDigits + 10; 447 const int kBufferSize = kMaxSignificantDigits + 10;
448 char buffer[kBufferSize]; // NOLINT: size is known at compile time. 448 char buffer[kBufferSize]; // NOLINT: size is known at compile time.
449 int buffer_pos = 0; 449 int buffer_pos = 0;
450 450
451 // Exponent will be adjusted if insignificant digits of the integer part 451 // Exponent will be adjusted if insignificant digits of the integer part
452 // or insignificant leading zeros of the fractional part are dropped. 452 // or insignificant leading zeros of the fractional part are dropped.
453 int exponent = 0; 453 int exponent = 0;
454 int significant_digits = 0; 454 int significant_digits = 0;
455 int insignificant_digits = 0; 455 int insignificant_digits = 0;
456 bool nonzero_digit_dropped = false; 456 bool nonzero_digit_dropped = false;
457 bool sign = false; 457 bool sign = false;
458 458
459 if (*current == '+' || *current == '-') { 459 if (*current == '+' || *current == '-') {
460 sign = (*current == '-'); 460 sign = (*current == '-');
461 ++current; 461 ++current;
462 if (current == end) return 0.0; 462 if (current == end) return 0.0;
463 } 463 }
464 464
465 bool leading_zero = false; 465 bool leading_zero = false;
466 if (*current == '0') { 466 if (*current == '0') {
467 ++current; 467 ++current;
468 if (current == end) { 468 if (current == end) {
469 *processed_characters_count = current - input; 469 *processed_characters_count = current - input;
470 return SignedZero(sign); 470 return SignedZero(sign);
471 } 471 }
472 472
473 leading_zero = true; 473 leading_zero = true;
474 474
475 // Ignore leading zeros in the integer part. 475 // Ignore leading zeros in the integer part.
476 while (*current == '0') { 476 while (*current == '0') {
477 ++current; 477 ++current;
478 if (current == end) { 478 if (current == end) {
479 *processed_characters_count = current - input; 479 *processed_characters_count = current - input;
480 return SignedZero(sign); 480 return SignedZero(sign);
481 } 481 }
482 } 482 }
483 } 483 }
484 484
485 // Copy significant digits of the integer part (if any) to the buffer. 485 // Copy significant digits of the integer part (if any) to the buffer.
486 while (*current >= '0' && *current <= '9') { 486 while (*current >= '0' && *current <= '9') {
487 if (significant_digits < kMaxSignificantDigits) { 487 if (significant_digits < kMaxSignificantDigits) {
488 ASSERT(buffer_pos < kBufferSize); 488 ASSERT(buffer_pos < kBufferSize);
489 buffer[buffer_pos++] = static_cast<char>(*current); 489 buffer[buffer_pos++] = static_cast<char>(*current);
490 significant_digits++; 490 significant_digits++;
491 } else { 491 } else {
492 insignificant_digits++; // Move the digit into the exponential part. 492 insignificant_digits++; // Move the digit into the exponential part.
493 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0' ; 493 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0' ;
494 } 494 }
495 ++current; 495 ++current;
496 if (current == end) goto parsing_done; 496 if (current == end) goto parsing_done;
497 } 497 }
498 498
499 if (*current == '.') { 499 if (*current == '.') {
500 ++current; 500 ++current;
501 if (current == end) { 501 if (current == end) {
502 if (significant_digits == 0 && !leading_zero) { 502 if (significant_digits == 0 && !leading_zero) {
503 return 0.0; 503 return 0.0;
504 } else { 504 } else {
505 goto parsing_done; 505 goto parsing_done;
506 } 506 }
507 } 507 }
508 508
509 if (significant_digits == 0) { 509 if (significant_digits == 0) {
510 // Integer part consists of 0 or is absent. Significant digits s tart after 510 // Integer part consists of 0 or is absent. Significant digits s tart after
511 // leading zeros (if any). 511 // leading zeros (if any).
512 while (*current == '0') { 512 while (*current == '0') {
513 ++current; 513 ++current;
514 if (current == end) { 514 if (current == end) {
515 *processed_characters_count = current - input; 515 *processed_characters_count = current - input;
516 return SignedZero(sign); 516 return SignedZero(sign);
517 } 517 }
518 exponent--; // Move this 0 into the exponent. 518 exponent--; // Move this 0 into the exponent.
519 } 519 }
520 } 520 }
521 521
522 // There is a fractional part. 522 // There is a fractional part.
523 while (*current >= '0' && *current <= '9') { 523 while (*current >= '0' && *current <= '9') {
524 if (significant_digits < kMaxSignificantDigits) { 524 if (significant_digits < kMaxSignificantDigits) {
525 ASSERT(buffer_pos < kBufferSize); 525 ASSERT(buffer_pos < kBufferSize);
526 buffer[buffer_pos++] = static_cast<char>(*current); 526 buffer[buffer_pos++] = static_cast<char>(*current);
527 significant_digits++; 527 significant_digits++;
528 exponent--; 528 exponent--;
529 } else { 529 } else {
530 // Ignore insignificant digits in the fractional part. 530 // Ignore insignificant digits in the fractional part.
531 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0'; 531 nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
532 } 532 }
533 ++current; 533 ++current;
534 if (current == end) goto parsing_done; 534 if (current == end) goto parsing_done;
535 } 535 }
536 } 536 }
537 537
538 if (!leading_zero && exponent == 0 && significant_digits == 0) { 538 if (!leading_zero && exponent == 0 && significant_digits == 0) {
539 // If leading_zeros is true then the string contains zeros. 539 // If leading_zeros is true then the string contains zeros.
540 // If exponent < 0 then string was [+-]\.0*... 540 // If exponent < 0 then string was [+-]\.0*...
541 // If significant_digits != 0 the string is not equal to 0. 541 // If significant_digits != 0 the string is not equal to 0.
542 // Otherwise there are no digits in the string. 542 // Otherwise there are no digits in the string.
543 return 0.0; 543 return 0.0;
544 } 544 }
545 545
546 // Parse exponential part. 546 // Parse exponential part.
547 if (*current == 'e' || *current == 'E') { 547 if (*current == 'e' || *current == 'E') {
548 ++current; 548 ++current;
549 if (current == end) { 549 if (current == end) {
550 --current; 550 --current;
551 goto parsing_done; 551 goto parsing_done;
552 } 552 }
553 char sign = 0; 553 char sign = 0;
554 if (*current == '+' || *current == '-') { 554 if (*current == '+' || *current == '-') {
555 sign = static_cast<char>(*current); 555 sign = static_cast<char>(*current);
556 ++current; 556 ++current;
557 if (current == end) { 557 if (current == end) {
558 current -= 2; 558 current -= 2;
559 goto parsing_done; 559 goto parsing_done;
560 } 560 }
561 } 561 }
562 562
563 if (*current < '0' || *current > '9') { 563 if (*current < '0' || *current > '9') {
564 if (sign) 564 if (sign)
565 --current; 565 --current;
566 --current; 566 --current;
567 goto parsing_done; 567 goto parsing_done;
568 } 568 }
569 569
570 const int max_exponent = INT_MAX / 2; 570 const int max_exponent = INT_MAX / 2;
571 ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2 ); 571 ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2 );
572 int num = 0; 572 int num = 0;
573 do { 573 do {
574 // Check overflow. 574 // Check overflow.
575 int digit = *current - '0'; 575 int digit = *current - '0';
576 if (num >= max_exponent / 10 576 if (num >= max_exponent / 10
577 && !(num == max_exponent / 10 && digit <= max_exponent % 10) ) { 577 && !(num == max_exponent / 10 && digit <= max_exponent % 10) ) {
578 num = max_exponent; 578 num = max_exponent;
579 } else { 579 } else {
580 num = num * 10 + digit; 580 num = num * 10 + digit;
581 } 581 }
582 ++current; 582 ++current;
583 } while (current != end && *current >= '0' && *current <= '9'); 583 } while (current != end && *current >= '0' && *current <= '9');
584 584
585 exponent += (sign == '-' ? -num : num); 585 exponent += (sign == '-' ? -num : num);
586 } 586 }
587 587
588 parsing_done: 588 parsing_done:
589 exponent += insignificant_digits; 589 exponent += insignificant_digits;
590 590
591 if (nonzero_digit_dropped) { 591 if (nonzero_digit_dropped) {
592 buffer[buffer_pos++] = '1'; 592 buffer[buffer_pos++] = '1';
593 exponent--; 593 exponent--;
594 } 594 }
595 595
596 ASSERT(buffer_pos < kBufferSize); 596 ASSERT(buffer_pos < kBufferSize);
597 buffer[buffer_pos] = '\0'; 597 buffer[buffer_pos] = '\0';
598 598
599 double converted = Strtod(Vector<const char>(buffer, buffer_pos), expone nt); 599 double converted = Strtod(Vector<const char>(buffer, buffer_pos), expone nt);
600 *processed_characters_count = current - input; 600 *processed_characters_count = current - input;
601 return sign? -converted: converted; 601 return sign? -converted: converted;
602 } 602 }
603 603
604 } // namespace double_conversion 604 } // namespace double_conversion
605 605
606 } // namespace WTF 606 } // namespace WTF
OLDNEW
« no previous file with comments | « Source/wtf/dtoa/diy-fp.cc ('k') | Source/wtf/dtoa/fast-dtoa.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698