Ejemplo n.º 1
0
// toFixed converts a number to a string, always formatting as an a decimal fraction.
// This method takes an argument specifying a number of decimal places to round the
// significand to. However when converting large values (1e+21 and above) this
// method will instead fallback to calling ToString.
EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec)
{
    double x;
    if (!toThisNumber(exec->thisValue(), x))
        return throwVMTypeError(exec);

    // Get the argument.
    int decimalPlaces;
    bool isUndefined; // This is ignored; undefined treated as 0.
    if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlaces, isUndefined))
        return throwVMError(exec, createRangeError(exec, ASCIILiteral("toFixed() argument must be between 0 and 20")));

    // 15.7.4.5.7 states "If x >= 10^21, then let m = ToString(x)"
    // This also covers Ininity, and structure the check so that NaN
    // values are also handled by numberToString
    if (!(fabs(x) < 1e+21))
        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));

    // The check above will return false for NaN or Infinity, these will be
    // handled by numberToString.
    ASSERT(std::isfinite(x));

    NumberToStringBuffer buffer;
    return JSValue::encode(jsString(exec, String(numberToFixedWidthString(x, decimalPlaces, buffer))));
}
Ejemplo n.º 2
0
// toExponential converts a number to a string, always formatting as an expoential.
// This method takes an optional argument specifying a number of *decimal places*
// to round the significand to (or, put another way, this method optionally rounds
// to argument-plus-one significant figures).
EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec)
{
    double x;
    if (!toThisNumber(exec->thisValue(), x))
        return throwVMTypeError(exec);

    // Get the argument.
    int decimalPlacesInExponent;
    bool isUndefined;
    if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlacesInExponent, isUndefined))
        return throwVMError(exec, createRangeError(exec, ASCIILiteral("toExponential() argument must be between 0 and 20")));

    // Handle NaN and Infinity.
    if (!std::isfinite(x))
        return JSValue::encode(jsNontrivialString(exec, String::numberToStringECMAScript(x)));

    // Round if the argument is not undefined, always format as exponential.
    char buffer[WTF::NumberToStringBufferLength];
    DoubleConversionStringBuilder builder(buffer, WTF::NumberToStringBufferLength);
    const DoubleToStringConverter& converter = DoubleToStringConverter::EcmaScriptConverter();
    builder.Reset();
    isUndefined
    ? converter.ToExponential(x, -1, &builder)
    : converter.ToExponential(x, decimalPlacesInExponent, &builder);
    return JSValue::encode(jsString(exec, String(builder.Finalize())));
}
Ejemplo n.º 3
0
// toPrecision converts a number to a string, takeing an argument specifying a
// number of significant figures to round the significand to. For positive
// exponent, all values that can be represented using a decimal fraction will
// be, e.g. when rounding to 3 s.f. any value up to 999 will be formated as a
// decimal, whilst 1000 is converted to the exponential representation 1.00e+3.
// For negative exponents values >= 1e-6 are formated as decimal fractions,
// with smaller values converted to exponential representation.
EncodedTiValue JSC_HOST_CALL numberProtoFuncToPrecision(TiExcState* exec)
{
    // Get x (the double value of this, which should be a Number).
    TiValue thisValue = exec->hostThisValue();
    TiValue v = thisValue.getJSNumber();
    if (!v)
        return throwVMTypeError(exec);
    double x = v.uncheckedGetNumber();

    // Get the argument. 
    int significantFigures;
    bool isUndefined;
    if (!getIntegerArgumentInRange(exec, 1, 21, significantFigures, isUndefined))
        return throwVMError(exec, createRangeError(exec, "toPrecision() argument must be between 1 and 21"));

    // To precision called with no argument is treated as ToString.
    if (isUndefined)
        return TiValue::encode(jsString(exec, UString::number(x)));

    // Handle NaN and Infinity.
    if (isnan(x) || isinf(x))
        return TiValue::encode(jsString(exec, UString::number(x)));

    // Convert to decimal with rounding.
    DecimalNumber number(x, RoundingSignificantFigures, significantFigures);
    // If number is in the range 1e-6 <= x < pow(10, significantFigures) then format
    // as decimal. Otherwise, format the number as an exponential.  Decimal format
    // demands a minimum of (exponent + 1) digits to represent a number, for example
    // 1234 (1.234e+3) requires 4 digits. (See ECMA-262 15.7.4.7.10.c)
    NumberToStringBuffer buffer;
    unsigned length = number.exponent() >= -6 && number.exponent() < significantFigures
        ? number.toStringDecimal(buffer, WTI::NumberToStringBufferLength)
        : number.toStringExponential(buffer, WTI::NumberToStringBufferLength);
    return TiValue::encode(jsString(exec, UString(buffer, length)));
}
Ejemplo n.º 4
0
// toFixed converts a number to a string, always formatting as an a decimal fraction.
// This method takes an argument specifying a number of decimal places to round the
// significand to. However when converting large values (1e+21 and above) this
// method will instead fallback to calling ToString. 
EncodedTiValue JSC_HOST_CALL numberProtoFuncToFixed(TiExcState* exec)
{
    // Get x (the double value of this, which should be a Number).
    TiValue thisValue = exec->hostThisValue();
    TiValue v = thisValue.getJSNumber();
    if (!v)
        return throwVMTypeError(exec);
    double x = v.uncheckedGetNumber();

    // Get the argument. 
    int decimalPlaces;
    bool isUndefined; // This is ignored; undefined treated as 0.
    if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlaces, isUndefined))
        return throwVMError(exec, createRangeError(exec, "toFixed() argument must be between 0 and 20"));

    // 15.7.4.5.7 states "If x >= 10^21, then let m = ToString(x)"
    // This also covers Ininity, and structure the check so that NaN
    // values are also handled by numberToString
    if (!(fabs(x) < 1e+21))
        return TiValue::encode(jsString(exec, UString::number(x)));

    // The check above will return false for NaN or Infinity, these will be
    // handled by numberToString.
    ASSERT(!isnan(x) && !isinf(x));

    // Convert to decimal with rounding, and format as decimal.
    NumberToStringBuffer buffer;
    unsigned length = DecimalNumber(x, RoundingDecimalPlaces, decimalPlaces).toStringDecimal(buffer, WTI::NumberToStringBufferLength);
    return TiValue::encode(jsString(exec, UString(buffer, length)));
}
Ejemplo n.º 5
0
// toExponential converts a number to a string, always formatting as an expoential.
// This method takes an optional argument specifying a number of *decimal places*
// to round the significand to (or, put another way, this method optionally rounds
// to argument-plus-one significant figures).
EncodedTiValue JSC_HOST_CALL numberProtoFuncToExponential(TiExcState* exec)
{
    // Get x (the double value of this, which should be a Number).
    double x;
    if (!toThisNumber(exec->hostThisValue(), x))
        return throwVMTypeError(exec);

    // Get the argument. 
    int decimalPlacesInExponent;
    bool isUndefined;
    if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlacesInExponent, isUndefined))
        return throwVMError(exec, createRangeError(exec, "toExponential() argument must be between 0 and 20"));

    // Handle NaN and Infinity.
    if (isnan(x) || isinf(x))
        return TiValue::encode(jsString(exec, UString::number(x)));

    // Round if the argument is not undefined, always format as exponential.
    NumberToStringBuffer buffer;
    unsigned length = isUndefined
        ? DecimalNumber(x).toStringExponential(buffer, WTI::NumberToStringBufferLength)
        : DecimalNumber(x, RoundingSignificantFigures, decimalPlacesInExponent + 1).toStringExponential(buffer, WTI::NumberToStringBufferLength);

    return TiValue::encode(jsString(exec, UString(buffer, length)));
}
Ejemplo n.º 6
0
// toPrecision converts a number to a string, takeing an argument specifying a
// number of significant figures to round the significand to. For positive
// exponent, all values that can be represented using a decimal fraction will
// be, e.g. when rounding to 3 s.f. any value up to 999 will be formated as a
// decimal, whilst 1000 is converted to the exponential representation 1.00e+3.
// For negative exponents values >= 1e-6 are formated as decimal fractions,
// with smaller values converted to exponential representation.
EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec)
{
    double x;
    if (!toThisNumber(exec->thisValue(), x))
        return throwVMTypeError(exec);

    // Get the argument.
    int significantFigures;
    bool isUndefined;
    if (!getIntegerArgumentInRange(exec, 1, 21, significantFigures, isUndefined))
        return throwVMError(exec, createRangeError(exec, ASCIILiteral("toPrecision() argument must be between 1 and 21")));

    // To precision called with no argument is treated as ToString.
    if (isUndefined)
        return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x)));

    // Handle NaN and Infinity.
    if (!std::isfinite(x))
        return JSValue::encode(jsNontrivialString(exec, String::numberToStringECMAScript(x)));

    NumberToStringBuffer buffer;
    return JSValue::encode(jsString(exec, String(numberToFixedPrecisionString(x, significantFigures, buffer))));
}