Changeset 29020 in webkit
- Timestamp:
- Dec 28, 2007, 8:01:13 PM (17 years ago)
- Location:
- trunk
- Files:
-
- 5 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r29018 r29020 1 2007-12-28 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Oliver. 4 5 Fix (-0).toFixed() and re-factor a little 6 Fix (-0).toExponential() and printing of trailing 0s in toExponential 7 Fix toPrecision(nan) handling 8 9 * kjs/number_object.cpp: 10 (KJS::numberToFixed): 11 (KJS::fractionalPartToString): 12 (KJS::numberToExponential): 13 (KJS::numberToPrecision): 14 1 15 2007-12-28 Eric Seidel <eric@webkit.org> 2 16 -
trunk/JavaScriptCore/kjs/number_object.cpp
r29018 r29020 209 209 s.append('-'); 210 210 x = -x; 211 } 211 } else if (x == -0.0) 212 x = 0; 212 213 213 214 if (x >= pow(10.0, 21.0)) … … 234 235 return jsString(s + m.substr(0, kMinusf) + "." + m.substr(kMinusf)); 235 236 return jsString(s + m.substr(0, kMinusf)); 237 } 238 239 void fractionalPartToString(char* buf, int& i, const char* result, int resultLength, int fractionalDigits) 240 { 241 if (fractionalDigits <= 0) 242 return; 243 244 int fDigitsInResult = static_cast<int>(resultLength) - 1; 245 buf[i++] = '.'; 246 if (fDigitsInResult > 0) { 247 if (fractionalDigits < fDigitsInResult) { 248 strncpy(buf + i, result + 1, fractionalDigits); 249 i += fractionalDigits; 250 } else { 251 strcpy(buf + i, result + 1); 252 i += static_cast<int>(resultLength) - 1; 253 } 254 } 255 256 for (int j = 0; j < fractionalDigits - fDigitsInResult; j++) 257 buf[i++] = '0'; 236 258 } 237 259 … … 259 281 return jsString(UString::from(x)); 260 282 261 JSValue* fraction Digits= args[0];262 double df = fraction Digits->toInteger(exec);283 JSValue* fractionalDigitsValue = args[0]; 284 double df = fractionalDigitsValue->toInteger(exec); 263 285 if (!(df >= 0 && df <= 20)) 264 286 return throwError(exec, RangeError, "toExponential() argument must between 0 and 20"); 265 int f = (int)df;266 bool includeAllDigits = fraction Digits->isUndefined();287 int fractionalDigits = (int)df; 288 bool includeAllDigits = fractionalDigitsValue->isUndefined(); 267 289 268 290 int decimalAdjust = 0; 269 if ( !includeAllDigits) {291 if (x && !includeAllDigits) { 270 292 double logx = floor(log10(fabs(x))); 271 293 x /= pow(10.0, logx); 272 const double tenToTheF = pow(10.0, f );294 const double tenToTheF = pow(10.0, fractionalDigits); 273 295 double fx = floor(x * tenToTheF) / tenToTheF; 274 296 double cx = ceil(x * tenToTheF) / tenToTheF; … … 285 307 return jsString("NaN"); 286 308 309 if (x == -0.0) // (-0.0).toExponential() should print as 0 instead of -0 310 x = 0; 311 287 312 int decimalPoint; 288 313 int sign; 289 314 char* result = kjs_dtoa(x, 0, 0, &decimalPoint, &sign, NULL); 290 size_t length = strlen(result);315 size_t resultLength = strlen(result); 291 316 decimalPoint += decimalAdjust; 292 317 293 318 int i = 0; 294 char buf[80]; 319 char buf[80]; // digit + '.' + fractionDigits (max 20) + 'e' + sign + exponent (max?) 295 320 if (sign) 296 321 buf[i++] = '-'; … … 302 327 303 328 if (includeAllDigits) 304 f = static_cast<int>(length) - 1; 305 306 if (length > 1 && f > 0) { 307 buf[i++] = '.'; 308 int haveFDigits = static_cast<int>(length) - 1; 309 if (f < haveFDigits) { 310 strncpy(buf + i, result + 1, f); 311 i += f; 312 } else { 313 strcpy(buf + i, result + 1); 314 i += static_cast<int>(length) - 1; 315 for (int j = 0; j < f - haveFDigits; j++) 316 buf[i++] = '0'; 317 } 318 } 329 fractionalDigits = static_cast<int>(resultLength) - 1; 330 331 fractionalPartToString(buf, i, result, resultLength, fractionalDigits); 319 332 exponentialPartToString(buf, i, decimalPoint); 320 333 buf[i++] = '\0'; 321 334 } 322 323 335 ASSERT(i <= 80); 324 336 … … 332 344 double doublePrecision = args[0]->toIntegerPreserveNaN(exec); 333 345 double x = v->toNumber(exec); 334 if ( isnan(doublePrecision) || isnan(x) || isinf(x))346 if (args[0]->isUndefined() || isnan(x) || isinf(x)) 335 347 return jsString(v->toString(exec)); 336 348 … … 347 359 int e = 0; 348 360 UString m; 349 if (x != 0) {361 if (x) { 350 362 e = static_cast<int>(log10(x)); 351 363 double tens = intPow10(e - precision + 1); -
trunk/LayoutTests/ChangeLog
r29012 r29020 1 2007-12-28 Eric Seidel <eric@webkit.org> 2 3 Reviewed by Oliver. 4 5 Add more tests for toFixed, toPrecision and toExponential 6 Add tests for toString to match Firefox's behavior 7 8 All tests pass in Firefox, but some fail in WebKit 9 I've chosen to land failing tests as I expect we'll move closer 10 towards Firefox's behavior in the future, and it's better to have 11 the tests now thus to notice any behavior changes in the future. 12 13 * fast/js/number-toExponential-expected.txt: Added. 14 * fast/js/number-toString-expected.txt: Added. 15 * fast/js/number-toString.html: Added. 16 * fast/js/number-tofixed-expected.txt: 17 * fast/js/number-toprecision-expected.txt: 18 * fast/js/resources/number-toExponential.js: Added. 19 * fast/js/resources/number-toString.js: Added. 20 * fast/js/resources/number-tofixed.js: 21 * fast/js/resources/number-toprecision.js: 22 1 23 2007-12-29 Nikolas Zimmermann <zimmermann@kde.org> 2 24 -
trunk/LayoutTests/fast/js/number-tofixed-expected.txt
r12000 r29020 26 26 PASS (-0.55).toFixed(1) is '-0.6' 27 27 PASS (-0.551).toFixed(1) is '-0.6' 28 PASS (0.0).toFixed(4) is "0.0000" 29 PASS (-0.0).toFixed(4) is "0.0000" 30 PASS (0.0).toFixed() is "0" 31 PASS (-0.0).toFixed() is "0" 32 PASS (1234.567).toFixed() is "1235" 33 PASS (1234.567).toFixed(0) is "1235" 34 PASS (1234.567).toFixed(1) is "1234.6" 35 PASS (1234.567).toFixed(2) is "1234.57" 36 PASS (1234.567).toFixed(5) is "1234.56700" 37 FAIL (1234.567).toFixed(20) should be 1234.56700000000000727596. Was 1234.56700000000000000000. 38 FAIL (1234.567).toFixed(21) should be 1234.567000000000007275958. Threw exception RangeError: toFixed() digits argument must be between 0 and 20 39 FAIL (1234.567).toFixed(100) should be 1234.5670000000000072759576141834259033203125000000000000000000000000000000000000000000000000000000000000. Threw exception RangeError: toFixed() digits argument must be between 0 and 20 40 PASS (1234.567).toFixed(101) threw exception RangeError: toFixed() digits argument must be between 0 and 20. 41 FAIL (1234.567).toFixed(-1) should be 1230. Threw exception RangeError: toFixed() digits argument must be between 0 and 20 42 FAIL (1234.567).toFixed(-4) should be 0. Threw exception RangeError: toFixed() digits argument must be between 0 and 20 43 FAIL (1234.567).toFixed(-5) should be 0. Threw exception RangeError: toFixed() digits argument must be between 0 and 20 44 FAIL (1234.567).toFixed(-20) should be 0. Threw exception RangeError: toFixed() digits argument must be between 0 and 20 45 PASS (1234.567).toFixed(-21) threw exception RangeError: toFixed() digits argument must be between 0 and 20. 46 PASS (1234.567).toFixed(posInf) threw exception RangeError: toFixed() digits argument must be between 0 and 20. 47 PASS (1234.567).toFixed(negInf) threw exception RangeError: toFixed() digits argument must be between 0 and 20. 48 PASS (1234.567).toFixed(nan) is "1235" 49 PASS posInf.toFixed() is "Infinity" 50 PASS negInf.toFixed() is "-Infinity" 51 PASS nan.toFixed() is "NaN" 28 52 PASS successfullyParsed is true 29 53 -
trunk/LayoutTests/fast/js/number-toprecision-expected.txt
r26581 r29020 4 4 5 5 6 PASS (0.999).toPrecision(1) is '1' 7 PASS (0.999).toPrecision(2) is '1.0' 8 PASS (0.999).toPrecision(3) is '0.999' 6 PASS (0.999).toPrecision(1) is "1" 7 PASS (0.999).toPrecision(2) is "1.0" 8 PASS (0.999).toPrecision(3) is "0.999" 9 PASS (0.0).toPrecision(4) is "0.000" 10 PASS (-0.0).toPrecision(4) is "0.000" 11 FAIL (0.0).toPrecision() should be 0. Threw exception RangeError: toPrecision() argument must be between 1 and 21 12 FAIL (-0.0).toPrecision() should be 0. Threw exception RangeError: toPrecision() argument must be between 1 and 21 13 FAIL (1234.567).toPrecision() should be 1234.567. Threw exception RangeError: toPrecision() argument must be between 1 and 21 14 PASS (1234.567).toPrecision(0) threw exception RangeError: toPrecision() argument must be between 1 and 21. 15 PASS (1234.567).toPrecision(-1) threw exception RangeError: toPrecision() argument must be between 1 and 21. 16 PASS (1234.567).toPrecision(1) is "1e+3" 17 PASS (1234.567).toPrecision(2) is "1.2e+3" 18 PASS (1234.567).toPrecision(5) is "1234.6" 19 FAIL (1234.567).toPrecision(21) should be 1234.56700000000000728. Was 1234.56700000000000000. 20 FAIL (1234.567).toPrecision(22) should be 1234.567000000000007276. Threw exception RangeError: toPrecision() argument must be between 1 and 21 21 FAIL (1234.567).toPrecision(100) should be 1234.567000000000007275957614183425903320312500000000000000000000000000000000000000000000000000000000. Threw exception RangeError: toPrecision() argument must be between 1 and 21 22 PASS (1234.567).toPrecision(101) threw exception RangeError: toPrecision() argument must be between 1 and 21. 23 PASS (1234.567).toPrecision(posInf) threw exception RangeError: toPrecision() argument must be between 1 and 21. 24 PASS (1234.567).toPrecision(negInf) threw exception RangeError: toPrecision() argument must be between 1 and 21. 25 PASS (1234.567).toPrecision(nan) threw exception RangeError: toPrecision() argument must be between 1 and 21. 26 PASS posInf.toPrecision() is "Infinity" 27 PASS negInf.toPrecision() is "-Infinity" 28 PASS nan.toPrecision() is "NaN" 9 29 PASS successfullyParsed is true 10 30 -
trunk/LayoutTests/fast/js/resources/number-tofixed.js
r12000 r29020 34 34 shouldBe("(-0.551).toFixed(1)", "'-0.6'"); 35 35 36 var posInf = 1/0; 37 var negInf = -1/0; 38 var nan = 0/0; 39 40 // From Acid3, http://bugs.webkit.org/show_bug.cgi?id=16640 41 shouldBeEqualToString("(0.0).toFixed(4)", "0.0000"); 42 shouldBeEqualToString("(-0.0).toFixed(4)", "0.0000"); 43 shouldBeEqualToString("(0.0).toFixed()", "0"); 44 shouldBeEqualToString("(-0.0).toFixed()", "0"); 45 46 // From http://bugs.webkit.org/show_bug.cgi?id=5258 47 shouldBeEqualToString("(1234.567).toFixed()", "1235"); 48 shouldBeEqualToString("(1234.567).toFixed(0)", "1235"); 49 // 0 equivilents 50 shouldBeEqualToString("(1234.567).toFixed(null)", "1235"); 51 shouldBeEqualToString("(1234.567).toFixed(false)", "1235"); 52 shouldBeEqualToString("(1234.567).toFixed('foo')", "1235"); 53 shouldBeEqualToString("(1234.567).toFixed(nan)", "1235"); // nan is treated like 0 54 55 shouldBeEqualToString("(1234.567).toFixed(1)", "1234.6"); 56 shouldBeEqualToString("(1234.567).toFixed(true)", "1234.6"); // just like 1 57 shouldBeEqualToString("(1234.567).toFixed('1')", "1234.6"); // just like 1 58 59 shouldBeEqualToString("(1234.567).toFixed(2)", "1234.57"); 60 shouldBeEqualToString("(1234.567).toFixed(5)", "1234.56700"); 61 shouldBeEqualToString("(1234.567).toFixed(20)", "1234.56700000000000727596"); 62 63 // SpiderMonkey allows precision values -20 to 100, we only allow 0 to 20 currently 64 shouldBeEqualToString("(1234.567).toFixed(21)", "1234.567000000000007275958"); 65 shouldBeEqualToString("(1234.567).toFixed(100)", "1234.5670000000000072759576141834259033203125000000000000000000000000000000000000000000000000000000000000"); 66 shouldThrow("(1234.567).toFixed(101)"); 67 shouldBeEqualToString("(1234.567).toFixed(-1)", "1230"); 68 shouldBeEqualToString("(1234.567).toFixed(-4)", "0"); 69 shouldBeEqualToString("(1234.567).toFixed(-5)", "0"); 70 shouldBeEqualToString("(1234.567).toFixed(-20)", "0"); 71 shouldThrow("(1234.567).toFixed(-21)"); 72 73 shouldThrow("(1234.567).toFixed(posInf)"); 74 shouldThrow("(1234.567).toFixed(negInf)"); 75 76 shouldBeEqualToString("posInf.toFixed()", "Infinity"); 77 shouldBeEqualToString("negInf.toFixed()", "-Infinity"); 78 shouldBeEqualToString("nan.toFixed()", "NaN"); 79 36 80 var successfullyParsed = true; -
trunk/LayoutTests/fast/js/resources/number-toprecision.js
r26581 r29020 4 4 '.'); 5 5 6 shouldBe ("(0.999).toPrecision(1)", "'1'");7 shouldBe ("(0.999).toPrecision(2)", "'1.0'");8 shouldBe ("(0.999).toPrecision(3)", "'0.999'");6 shouldBeEqualToString("(0.999).toPrecision(1)", "1"); 7 shouldBeEqualToString("(0.999).toPrecision(2)", "1.0"); 8 shouldBeEqualToString("(0.999).toPrecision(3)", "0.999"); 9 9 10 var posInf = 1/0; 11 var negInf = -1/0; 12 var nan = 0/0; 13 14 shouldBeEqualToString("(0.0).toPrecision(4)", "0.000"); 15 shouldBeEqualToString("(-0.0).toPrecision(4)", "0.000"); 16 shouldBeEqualToString("(0.0).toPrecision()", "0"); 17 shouldBeEqualToString("(-0.0).toPrecision()", "0"); 18 shouldBeEqualToString("(1234.567).toPrecision()", "1234.567"); 19 shouldThrow("(1234.567).toPrecision(0)"); 20 shouldThrow("(1234.567).toPrecision(null)"); // just like 0 21 shouldThrow("(1234.567).toPrecision(false)"); // just like 0 22 shouldThrow("(1234.567).toPrecision('foo')"); // just like 0 23 shouldThrow("(1234.567).toPrecision(-1)"); 24 shouldBeEqualToString("(1234.567).toPrecision(1)", "1e+3"); 25 shouldBeEqualToString("(1234.567).toPrecision(true)", "1e+3"); // just like 1 26 shouldBeEqualToString("(1234.567).toPrecision('1')", "1e+3"); // just like 1 27 shouldBeEqualToString("(1234.567).toPrecision(2)", "1.2e+3"); 28 shouldBeEqualToString("(1234.567).toPrecision(5)", "1234.6"); 29 shouldBeEqualToString("(1234.567).toPrecision(21)", "1234.56700000000000728"); 30 // SpiderMonkey allows precision values 1 to 100, we only allow 1 to 21 currently 31 shouldBeEqualToString("(1234.567).toPrecision(22)", "1234.567000000000007276"); 32 shouldBeEqualToString("(1234.567).toPrecision(100)", "1234.567000000000007275957614183425903320312500000000000000000000000000000000000000000000000000000000"); 33 shouldThrow("(1234.567).toPrecision(101)"); 34 35 shouldThrow("(1234.567).toPrecision(posInf)"); 36 shouldThrow("(1234.567).toPrecision(negInf)"); 37 shouldThrow("(1234.567).toPrecision(nan)"); // nan is treated like 0 38 39 shouldBeEqualToString("posInf.toPrecision()", "Infinity"); 40 shouldBeEqualToString("negInf.toPrecision()", "-Infinity"); 41 shouldBeEqualToString("nan.toPrecision()", "NaN"); 10 42 11 43 var successfullyParsed = true;
Note:
See TracChangeset
for help on using the changeset viewer.