Implementing remainder operation according to ECMA. Checking that implementations of other arithmetic operations already conform to ECMA and removing corresponding TODOs from them.
This commit is contained in:
@@ -350,6 +350,31 @@ ecma_number_get_fraction_and_exponent (ecma_number_t num, /**< ecma-number */
|
||||
return ECMA_NUMBER_FRACTION_WIDTH;
|
||||
} /* ecma_number_get_fraction_and_exponent */
|
||||
|
||||
/**
|
||||
* Make normalised positive Number from given fraction and exponent
|
||||
*
|
||||
* @return ecma-number
|
||||
*/
|
||||
ecma_number_t
|
||||
ecma_number_make_normal_positive_from_fraction_and_exponent (uint64_t fraction, /**< fraction */
|
||||
int32_t exponent) /**< exponent */
|
||||
{
|
||||
union
|
||||
{
|
||||
ecma_number_fields_t fields;
|
||||
ecma_number_t value;
|
||||
} u;
|
||||
|
||||
uint32_t biased_exp = (uint32_t) (exponent + ecma_number_exponent_bias);
|
||||
JERRY_ASSERT (biased_exp > 0 && biased_exp < (1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1);
|
||||
|
||||
u.fields.biased_exp = biased_exp & ((1u << ECMA_NUMBER_BIASED_EXP_WIDTH) - 1);
|
||||
u.fields.fraction = fraction & ((1u << ECMA_NUMBER_FRACTION_WIDTH) - 1);
|
||||
u.fields.sign = 0;
|
||||
|
||||
return u.value;
|
||||
} /* ecma_number_make_normal_positive_from_fraction_and_exponent */
|
||||
|
||||
/**
|
||||
* Negate ecma-number
|
||||
*
|
||||
|
||||
@@ -124,6 +124,8 @@ extern bool ecma_number_is_infinity (ecma_number_t num);
|
||||
extern int32_t ecma_number_get_fraction_and_exponent (ecma_number_t num,
|
||||
uint64_t *out_fraction_p,
|
||||
int32_t *out_exponent_p);
|
||||
extern ecma_number_t ecma_number_make_normal_positive_from_fraction_and_exponent (uint64_t fraction,
|
||||
int32_t exponent);
|
||||
extern ecma_number_t ecma_number_negate (ecma_number_t num);
|
||||
|
||||
/* ecma-helpers-values-collection.c */
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-number-arithmetic.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
@@ -37,8 +38,6 @@ ecma_number_t
|
||||
ecma_op_number_add (ecma_number_t left_num, /**< left operand */
|
||||
ecma_number_t right_num) /**< right operand */
|
||||
{
|
||||
TODO(Implement according to ECMA);
|
||||
|
||||
return left_num + right_num;
|
||||
} /* ecma_op_number_add */
|
||||
|
||||
@@ -69,8 +68,6 @@ ecma_number_t
|
||||
ecma_op_number_multiply (ecma_number_t left_num, /**< left operand */
|
||||
ecma_number_t right_num) /**< right operand */
|
||||
{
|
||||
TODO(Implement according to ECMA);
|
||||
|
||||
return left_num * right_num;
|
||||
} /* ecma_op_number_multiply */
|
||||
|
||||
@@ -86,8 +83,6 @@ ecma_number_t
|
||||
ecma_op_number_divide (ecma_number_t left_num, /**< left operand */
|
||||
ecma_number_t right_num) /**< right operand */
|
||||
{
|
||||
TODO(Implement according to ECMA);
|
||||
|
||||
return left_num / right_num;
|
||||
} /* ecma_op_number_divide */
|
||||
|
||||
@@ -103,11 +98,54 @@ ecma_number_t
|
||||
ecma_op_number_remainder (ecma_number_t left_num, /**< left operand */
|
||||
ecma_number_t right_num) /**< right operand */
|
||||
{
|
||||
TODO(Implement according to ECMA);
|
||||
TODO (Check precision);
|
||||
|
||||
ecma_number_t n = left_num, d = right_num;
|
||||
|
||||
return (n - d * (ecma_number_t) ((int32_t) (n / d)));
|
||||
if (ecma_number_is_nan (n)
|
||||
|| ecma_number_is_nan (d)
|
||||
|| ecma_number_is_infinity (n)
|
||||
|| ecma_number_is_zero (d))
|
||||
{
|
||||
return ecma_number_make_nan ();
|
||||
}
|
||||
else if (ecma_number_is_infinity (d)
|
||||
|| (ecma_number_is_zero (n)
|
||||
&& !ecma_number_is_zero (d)))
|
||||
{
|
||||
return n;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (!ecma_number_is_nan (n)
|
||||
&& !ecma_number_is_zero (n)
|
||||
&& !ecma_number_is_infinity (n));
|
||||
JERRY_ASSERT (!ecma_number_is_nan (d)
|
||||
&& !ecma_number_is_zero (d)
|
||||
&& !ecma_number_is_infinity (d));
|
||||
|
||||
ecma_number_t q = n / d;
|
||||
|
||||
uint64_t fraction;
|
||||
int32_t exponent;
|
||||
int32_t dot_shift = ecma_number_get_fraction_and_exponent (q, &fraction, &exponent);
|
||||
|
||||
if (exponent < 0)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
else if (exponent >= dot_shift)
|
||||
{
|
||||
return n - d * q;
|
||||
}
|
||||
else
|
||||
{
|
||||
fraction &= ~((1ull << (dot_shift - exponent)) - 1);
|
||||
|
||||
q = ecma_number_make_normal_positive_from_fraction_and_exponent (fraction,
|
||||
exponent);
|
||||
|
||||
return n - d * q;
|
||||
}
|
||||
} /* ecma_op_number_remainder */
|
||||
|
||||
/**
|
||||
@@ -121,8 +159,6 @@ ecma_op_number_remainder (ecma_number_t left_num, /**< left operand */
|
||||
ecma_number_t
|
||||
ecma_op_number_negate (ecma_number_t num) /**< operand */
|
||||
{
|
||||
TODO(Implement according to ECMA);
|
||||
|
||||
return -num;
|
||||
} /* ecma_op_number_negate */
|
||||
|
||||
|
||||
@@ -29,3 +29,6 @@ assert((number - 9) == 72);
|
||||
assert((number * 10) == 810);
|
||||
assert((number / 9) == 9);
|
||||
assert((number % 79) == 2);
|
||||
|
||||
var num1 = 1234567, num2 = 1234000;
|
||||
assert((num1 % num2) == 567);
|
||||
|
||||
Reference in New Issue
Block a user