Refactor Number.prototype methods toFixed, toExponential, toPrecision (#3911)
JerryScript-DCO-1.0-Signed-off-by: Adam Szilagyi aszilagy@inf.u-szeged.hu
This commit is contained in:
@@ -877,142 +877,6 @@ ecma_number_to_decimal (ecma_number_t num, /**< ecma-number */
|
||||
return ecma_errol0_dtoa ((double) num, out_digits_p, out_decimal_exp_p);
|
||||
} /* ecma_number_to_decimal */
|
||||
|
||||
/**
|
||||
* Calculate the number of digits from the given double value whithout franction part
|
||||
*
|
||||
* @return number of digits
|
||||
*/
|
||||
inline static int32_t JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_number_of_digits (double val) /**< ecma number */
|
||||
{
|
||||
JERRY_ASSERT (fabs (fmod (val, 1.0)) < EPSILON);
|
||||
int32_t exponent = 0;
|
||||
|
||||
while (val >= 1.0)
|
||||
{
|
||||
val /= 10.0;
|
||||
exponent++;
|
||||
}
|
||||
|
||||
return exponent;
|
||||
} /* ecma_number_of_digits */
|
||||
|
||||
/**
|
||||
* Convert double value to ASCII
|
||||
*/
|
||||
inline static void JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_double_to_ascii (double val, /**< ecma number */
|
||||
lit_utf8_byte_t *buffer_p, /**< buffer to generate digits into */
|
||||
int32_t num_of_digits, /**< number of digits */
|
||||
int32_t *exp_p) /**< [out] exponent */
|
||||
{
|
||||
int32_t char_cnt = 0;
|
||||
|
||||
double divider = 10.0;
|
||||
double prev_residual;
|
||||
double mod_res = fmod (val, divider);
|
||||
|
||||
buffer_p[num_of_digits - 1 - char_cnt++] = (lit_utf8_byte_t) ((int) mod_res + '0');
|
||||
divider *= 10.0;
|
||||
prev_residual = mod_res;
|
||||
|
||||
while (char_cnt < num_of_digits)
|
||||
{
|
||||
mod_res = fmod (val, divider);
|
||||
double residual = mod_res - prev_residual;
|
||||
buffer_p[num_of_digits - 1 - char_cnt++] = (lit_utf8_byte_t) ((int) (residual / (divider / 10.0)) + '0');
|
||||
|
||||
divider *= 10.0;
|
||||
prev_residual = mod_res;
|
||||
}
|
||||
|
||||
*exp_p = char_cnt;
|
||||
} /* ecma_double_to_ascii */
|
||||
|
||||
/**
|
||||
* Double to binary floating-point number conversion
|
||||
*
|
||||
* @return number of generated digits
|
||||
*/
|
||||
static inline lit_utf8_size_t JERRY_ATTR_ALWAYS_INLINE
|
||||
ecma_double_to_binary_floating_point (double val, /**< ecma number */
|
||||
lit_utf8_byte_t *buffer_p, /**< buffer to generate digits into */
|
||||
int32_t *exp_p) /**< [out] exponent */
|
||||
{
|
||||
int32_t char_cnt = 0;
|
||||
double integer_part, fraction_part;
|
||||
|
||||
fraction_part = fmod (val, 1.0);
|
||||
integer_part = floor (val);
|
||||
int32_t num_of_digits = ecma_number_of_digits (integer_part);
|
||||
|
||||
if (fabs (integer_part) < EPSILON)
|
||||
{
|
||||
buffer_p[0] = '0';
|
||||
char_cnt++;
|
||||
}
|
||||
else if (num_of_digits <= 16) /* Ensure that integer_part is not rounded */
|
||||
{
|
||||
while (integer_part > 0.0)
|
||||
{
|
||||
buffer_p[num_of_digits - 1 - char_cnt++] = (lit_utf8_byte_t) ((int) fmod (integer_part, 10.0) + '0');
|
||||
integer_part = floor (integer_part / 10.0);
|
||||
}
|
||||
}
|
||||
else if (num_of_digits <= 21)
|
||||
{
|
||||
ecma_double_to_ascii (integer_part, buffer_p, num_of_digits, &char_cnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* According to ECMA-262 v5, 15.7.4.5, step 7: if x >= 10^21, then execution will continue with
|
||||
* ToString(x) so in this case no further conversions are required. Number 21 in the else if condition
|
||||
* above must be kept in sync with the number 21 in ecma_builtin_number_prototype_object_to_fixed
|
||||
* method, step 7. */
|
||||
*exp_p = num_of_digits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*exp_p = char_cnt;
|
||||
|
||||
while (fraction_part > 0 && char_cnt < ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER - 1)
|
||||
{
|
||||
fraction_part *= 10;
|
||||
double tmp = fraction_part;
|
||||
fraction_part = fmod (fraction_part, 1.0);
|
||||
integer_part = floor (tmp);
|
||||
buffer_p[char_cnt++] = (lit_utf8_byte_t) ('0' + (int) integer_part);
|
||||
}
|
||||
|
||||
buffer_p[char_cnt] = '\0';
|
||||
|
||||
return (lit_utf8_size_t) (char_cnt - *exp_p);
|
||||
} /* ecma_double_to_binary_floating_point */
|
||||
|
||||
/**
|
||||
* Perform conversion of ecma-number to equivalent binary floating-point number representation with decimal exponent.
|
||||
*
|
||||
* Note:
|
||||
* The calculated values correspond to s, n, k parameters in ECMA-262 v5, 9.8.1, item 5:
|
||||
* - parameter out_digits_p corresponds to s, the digits of the number;
|
||||
* - parameter out_decimal_exp_p corresponds to n, the decimal exponent;
|
||||
* - return value corresponds to k, the number of digits.
|
||||
*
|
||||
* @return the number of digits
|
||||
*/
|
||||
lit_utf8_size_t
|
||||
ecma_number_to_binary_floating_point_number (ecma_number_t num, /**< ecma-number */
|
||||
lit_utf8_byte_t *out_digits_p, /**< [out] buffer to fill with digits */
|
||||
int32_t *out_decimal_exp_p) /**< [out] decimal exponent */
|
||||
{
|
||||
JERRY_ASSERT (!ecma_number_is_nan (num));
|
||||
JERRY_ASSERT (!ecma_number_is_zero (num));
|
||||
JERRY_ASSERT (!ecma_number_is_infinity (num));
|
||||
JERRY_ASSERT (!ecma_number_is_negative (num));
|
||||
|
||||
return ecma_double_to_binary_floating_point ((double) num, out_digits_p, out_decimal_exp_p);
|
||||
} /* ecma_number_to_binary_floating_point_number */
|
||||
|
||||
/**
|
||||
* Convert ecma-number to zero-terminated string
|
||||
*
|
||||
|
||||
@@ -421,9 +421,6 @@ ecma_value_t ecma_number_parse_float (const lit_utf8_byte_t *string_buff,
|
||||
lit_utf8_size_t string_buff_size);
|
||||
ecma_value_t ecma_integer_multiply (ecma_integer_value_t left_integer, ecma_integer_value_t right_integer);
|
||||
lit_utf8_size_t ecma_number_to_decimal (ecma_number_t num, lit_utf8_byte_t *out_digits_p, int32_t *out_decimal_exp_p);
|
||||
lit_utf8_size_t ecma_number_to_binary_floating_point_number (ecma_number_t num,
|
||||
lit_utf8_byte_t *out_digits_p,
|
||||
int32_t *out_decimal_exp_p);
|
||||
|
||||
/* ecma-helpers-collection.c */
|
||||
ecma_collection_t *ecma_new_collection (void);
|
||||
|
||||
Reference in New Issue
Block a user