зеркало из https://github.com/mozilla/gecko-dev.git
Bug 622348 - JavaScript Math.round incorrect for (2^53)-1. r=Waldo
--HG-- extra : rebase_source : 51a780cf5ce9cbcc84c56d8a8dbe2c5d9867b36b
This commit is contained in:
Родитель
7637869e5b
Коммит
4f4a9cacd2
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
assertEq(Math.round(9007199254740991), 9007199254740991);
|
||||
assertEq(Math.round(-19007199254740990), -19007199254740990);
|
||||
|
||||
assertEq(Math.round("9007199254740991"), 9007199254740991);
|
||||
assertEq(Math.round("-19007199254740990"), -19007199254740990);
|
|
@ -577,26 +577,39 @@ js_copysign(double x, double y)
|
|||
}
|
||||
#endif
|
||||
|
||||
jsdouble
|
||||
js_math_round_impl(jsdouble x)
|
||||
{
|
||||
return js_copysign(floor(x + 0.5), x);
|
||||
}
|
||||
|
||||
JSBool
|
||||
JSBool /* ES5 15.8.2.15. */
|
||||
js_math_round(JSContext *cx, uintN argc, Value *vp)
|
||||
{
|
||||
jsdouble x, z;
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
if (argc == 0) {
|
||||
vp->setDouble(js_NaN);
|
||||
return JS_TRUE;
|
||||
if (args.length() == 0) {
|
||||
args.rval().setDouble(js_NaN);
|
||||
return true;
|
||||
}
|
||||
if (!ToNumber(cx, vp[2], &x))
|
||||
return JS_FALSE;
|
||||
z = js_copysign(floor(x + 0.5), x);
|
||||
vp->setNumber(z);
|
||||
return JS_TRUE;
|
||||
|
||||
double x;
|
||||
if (!ToNumber(cx, args[0], &x))
|
||||
return false;
|
||||
|
||||
int32_t i;
|
||||
if (JSDOUBLE_IS_INT32(x, &i)) {
|
||||
args.rval().setInt32(i);
|
||||
return true;
|
||||
}
|
||||
|
||||
jsdpun u;
|
||||
u.d = x;
|
||||
|
||||
/* Some numbers are so big that adding 0.5 would give the wrong number */
|
||||
int exponent = ((u.s.hi & JSDOUBLE_HI32_EXPMASK) >> JSDOUBLE_HI32_EXPSHIFT) - JSDOUBLE_EXPBIAS;
|
||||
if (exponent >= 52) {
|
||||
args.rval().setNumber(x);
|
||||
return true;
|
||||
}
|
||||
|
||||
args.rval().setNumber(js_copysign(floor(x + 0.5), x));
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
|
|
@ -121,7 +121,4 @@ js_math_ceil_impl(jsdouble x);
|
|||
extern jsdouble
|
||||
js_math_floor_impl(jsdouble x);
|
||||
|
||||
extern jsdouble
|
||||
js_math_round_impl(jsdouble x);
|
||||
|
||||
#endif /* jsmath_h___ */
|
||||
|
|
|
@ -65,6 +65,16 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* Low-level floating-point predicates. See bug 640494. */
|
||||
#define JSDOUBLE_HI32_SIGNBIT 0x80000000
|
||||
#define JSDOUBLE_HI32_EXPMASK 0x7ff00000
|
||||
#define JSDOUBLE_HI32_MANTMASK 0x000fffff
|
||||
#define JSDOUBLE_HI32_NAN 0x7ff80000
|
||||
#define JSDOUBLE_LO32_NAN 0x00000000
|
||||
|
||||
#define JSDOUBLE_HI32_EXPSHIFT 20
|
||||
#define JSDOUBLE_EXPBIAS 1023
|
||||
|
||||
typedef union jsdpun {
|
||||
struct {
|
||||
#if defined(IS_LITTLE_ENDIAN) && !defined(FPU_IS_ARM_FPA)
|
||||
|
@ -77,13 +87,6 @@ typedef union jsdpun {
|
|||
jsdouble d;
|
||||
} jsdpun;
|
||||
|
||||
/* Low-level floating-point predicates. See bug 640494. */
|
||||
#define JSDOUBLE_HI32_SIGNBIT 0x80000000
|
||||
#define JSDOUBLE_HI32_EXPMASK 0x7ff00000
|
||||
#define JSDOUBLE_HI32_MANTMASK 0x000fffff
|
||||
#define JSDOUBLE_HI32_NAN 0x7ff80000
|
||||
#define JSDOUBLE_LO32_NAN 0x00000000
|
||||
|
||||
static inline int
|
||||
JSDOUBLE_IS_NaN(jsdouble d)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче