Fix rounding issue (#2890)

Fixes #2802

JerryScript-DCO-1.0-Signed-off-by: Daniella Barsony bella@inf.u-szeged.hu
This commit is contained in:
Daniella Barsony 2019-05-31 08:31:36 +02:00 committed by László Langó
parent 076f515d61
commit b6fc4e13ae
3 changed files with 59 additions and 4 deletions

View File

@ -46,9 +46,22 @@ typedef struct
/**
* Round high part of 128-bit integer to uint64_t
*
* @return rounded high to uint64_t
*/
#define ECMA_UINT128_ROUND_HIGH_TO_UINT64(name) \
(name.hi + (name.lo >> 63u))
static uint64_t
ecma_round_high_to_uint64 (ecma_uint128_t *num_p)
{
uint64_t masked_lo = num_p->lo & ~(1ULL << 63u);
uint64_t masked_hi = num_p->hi & 0x1;
if ((num_p->lo >> 63u != 0)
&& (masked_lo > 0 || masked_hi != 0))
{
return (num_p->hi + 1);
}
return num_p->hi;
} /* ecma_round_high_to_uint64 */
/**
* Check if 128-bit integer is zero
@ -650,7 +663,7 @@ ecma_utf8_string_to_number (const lit_utf8_byte_t *str_p, /**< utf-8 string */
JERRY_ASSERT (ECMA_UINT128_CLZ_MAX63 (fraction_uint128) == 11);
fraction_uint64 = ECMA_UINT128_ROUND_HIGH_TO_UINT64 (fraction_uint128);
fraction_uint64 = ecma_round_high_to_uint64 (&fraction_uint128);
return ecma_number_make_from_sign_mantissa_and_exponent (sign, fraction_uint64, binary_exponent);
#elif !ENABLED (JERRY_NUMBER_TYPE_FLOAT64)

View File

@ -23,8 +23,35 @@ assert(big == 2147483648); // overflow on 32bit numbers
big++;
assert(big == 2147483649); // overflow on 32bit numbers
assert ((1152921504606846976).toString() === "1152921504606847000")
assert ((1152921504606846976).toString() === "1152921504606847000");
assert (1.797693134862315808e+308 === Infinity);
assert (9999999999999999 == 10000000000000000);
assert((9007199254740993).toString() === "9007199254740992");
assert((9007199254740992).toString() === "9007199254740992");
assert((9007199254740994).toString() === "9007199254740994");
assert((1.00517e+21).toString() === "1.0051699999999999e+21");
assert((1.00001e+21).toString() === "1.0000099999999999e+21");
assert((9007199254740995).toString() === "9007199254740996");
assert((18014398509481989).toString() === "18014398509481988");
assert((18014398509481990).toString() === "18014398509481992");
assert((18014398509481991).toString() === "18014398509481992");
assert((18014398509481993).toString() === "18014398509481992");
assert((18014398509481994).toString() === "18014398509481992");
assert((18014398509481997).toString() === "18014398509481996");
assert((18014398509481998).toString() === "18014398509482000");

View File

@ -0,0 +1,15 @@
// Copyright JS Foundation and other contributors, http://js.foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
assert(2e23 == 1.9999999999999998e+23);