Ignore:
Timestamp:
Aug 24, 2010, 6:04:31 PM (15 years ago)
Author:
[email protected]
Message:

JavaScriptCore: https://bugs.webkit.org/show_bug.cgi?id=44487

Reviewed by Oliver Hunt.

Number.toExponential/toFixed/toPrecision all contain a spaghetti of duplicated
code & unnecessary complexity. Add a new DecimalNumber class to encapsulate
double to string conversion, share the implementations of rounding &
decimal-fraction/exponential formatting.

Update exports.

  • runtime/NumberPrototype.cpp:

(JSC::toThisNumber):
(JSC::getIntegerArgumentInRange):

Helper methods used in implementing toExponential/toFixed/toString.

(JSC::numberProtoFuncToExponential):
(JSC::numberProtoFuncToFixed):
(JSC::numberProtoFuncToPrecision):

Reimplemented using new DecimalNumber class.


  • runtime/UString.cpp:

(JSC::UString::number):

Updated to call numberToString.

  • wtf/DecimalNumber.h: Added.

(WTF::):
(WTF::DecimalNumber::DecimalNumber):
(WTF::DecimalNumber::toStringDecimal):
(WTF::DecimalNumber::toStringExponential):
(WTF::DecimalNumber::sign):
(WTF::DecimalNumber::exponent):
(WTF::DecimalNumber::significand):
(WTF::DecimalNumber::precision):
(WTF::DecimalNumber::init):
(WTF::DecimalNumber::isZero):
(WTF::DecimalNumber::roundToPrecision):

New class to perform double to string conversion.
Has three constructors, which allow conversion with no rounding,
rounding to significant-figures, or rounding to decimal-places,
and two methods for formatting strings, either using decimal
fraction or exponential encoding. Internal implementation uses
pre-rounding of the values before calling dtoa rather than
relying on dtoa to correctly round, which does not produce
fully accurate results. Hopefully we can address this in the
near future.

  • wtf/dtoa.cpp:

(WTF::intPow10):

  • wtf/dtoa.h:

intPow10 is used internally by DecimalNumber.


  • wtf/text/WTFString.cpp:

(WTF::copyToString):
(WTF::nanOrInfToString):

Used internally in numberToString for NaN/Infinity handling.

(WTF::numberToString):

Added new method to convert doubles to strings.

  • wtf/text/WTFString.h:

Added declaration for numberToString. This is here because
we should switch over to using this for all double to string
conversion in WebCore (see section 2.4.4.3 of the HTML5 spec).

JavaScriptGlue: https://bugs.webkit.org/show_bug.cgi?id=44487

Reviewed by Oliver Hunt.

  • ForwardingHeaders/wtf/text/WTFString.h: Added.

WebCore: https://bugs.webkit.org/show_bug.cgi?id=44487

Reviewed by Oliver Hunt.

  • html/LegacyHTMLTreeBuilder.cpp:

(WebCore::serializeForNumberType):

Update function call to numberToString.

LayoutTests: Bug 44487 - Clean up NumberPrototype.cpp

Reviewed by Oliver Hunt.

This patch changes some layout test results - in all these cases we were
not previously accurate to spec defined behaviour, and we are still not

  • but overall this changes reduces the overall magnitude of error due to

rounding differences. The underlying problem is that we should be using
dtoa to generate results to a specified accuracy, rather than relying on
pre-rounding the input values. We should look at reenabling our dtoa
implementation to work in this fashion as a separate change.

  • fast/js/kde/Number-expected.txt:
  • fast/js/kde/script-tests/Number.js:
  • fast/js/number-toExponential-expected.txt:
  • fast/js/number-tofixed-expected.txt:
  • fast/js/number-toprecision-expected.txt:
  • fast/js/script-tests/number-toExponential.js:
  • fast/js/script-tests/number-tofixed.js:
  • fast/js/script-tests/number-toprecision.js:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/wtf/text/WTFString.cpp

    r65593 r65959  
    2626#include <stdarg.h>
    2727#include <wtf/ASCIICType.h>
    28 #include <wtf/text/CString.h>
     28#include <wtf/DecimalNumber.h>
    2929#include <wtf/StringExtras.h>
    3030#include <wtf/Vector.h>
    31 #include <wtf/dtoa.h>
     31#include <wtf/text/CString.h>
    3232#include <wtf/unicode/UTF8.h>
    3333#include <wtf/unicode/Unicode.h>
     
    948948}
    949949
     950static unsigned copyToString(const char* string, unsigned length, NumberToStringBuffer& buffer)
     951{
     952    for (unsigned i = 0; i < length; ++i)
     953        buffer[i] = string[i];
     954    return length;
     955}
     956
     957static NEVER_INLINE unsigned nanOrInfToString(double x, NumberToStringBuffer& buffer)
     958{
     959    ASSERT(isnan(x) || isinf(x));
     960    if (isnan(x))
     961        return copyToString("NaN", 3, buffer);
     962    if (x < 0)
     963        return copyToString("-Infinity", 9, buffer);
     964    return copyToString("Infinity", 8, buffer);
     965}
     966
     967// toString converts a number to a string without rounding. For values in the range
     968// 1e-6 <= x < 1e+21 the result is formatted as a decimal, with values outside of
     969// this range being formatted as an exponential.
     970unsigned numberToString(double x, NumberToStringBuffer& buffer)
     971{
     972    // Handle NaN and Infinity.
     973    if (UNLIKELY(isnan(x) || isinf(x)))
     974        return nanOrInfToString(x, buffer);
     975
     976    // Convert to decimal, no rounding.
     977    DecimalNumber number(x);
     978
     979    // Format as decimal or exponential, depending on the exponent.
     980    return number.exponent() >= -6 && number.exponent() < 21
     981        ? number.toStringDecimal(buffer)
     982        : number.toStringExponential(buffer);
     983}
     984
    950985} // namespace WTF
    951986
Note: See TracChangeset for help on using the changeset viewer.