[pypy-commit] lang-js default: fixed signed zero
stepahn
noreply at buildbot.pypy.org
Fri Dec 28 11:34:25 CET 2012
Author: Stephan <stephan at stzal.com>
Branch:
Changeset: r244:2987de3357a0
Date: 2012-06-03 15:17 +0200
http://bitbucket.org/pypy/lang-js/changeset/2987de3357a0/
Log: fixed signed zero
diff --git a/js/baseop.py b/js/baseop.py
--- a/js/baseop.py
+++ b/js/baseop.py
@@ -89,8 +89,22 @@
return W_FloatNumber(math.fmod(left, right))
+def sign(x):
+ from math import copysign
+ return copysign(1.0, x)
+
# 11.5.2
def division(ctx, nleft, nright):
+ def sign_of(a, b):
+ sign_a = sign(a)
+ sign_b = sign(b)
+ return sign_a * sign_b
+
+ def w_signed_inf(sign):
+ if sign < 0.0:
+ return w_NEGATIVE_INFINITY
+ return w_POSITIVE_INFINITY
+
fleft = nleft.ToNumber()
fright = nright.ToNumber()
if isnan(fleft) or isnan(fright):
@@ -100,7 +114,8 @@
return w_NAN
if isinf(fleft) and fright == 0:
- return nleft
+ s = sign_of(fleft, fright)
+ return w_signed_inf(s)
if isinf(fright):
return _w(0)
@@ -108,11 +123,9 @@
if fleft == 0 and fright == 0:
return w_NAN
- if fleft == 0:
- return _w(0)
-
if fright == 0:
- return w_POSITIVE_INFINITY
+ s = sign_of(fleft, fright)
+ return w_signed_inf(s)
val = fleft / fright
return W_FloatNumber(val)
@@ -157,6 +170,7 @@
s5 = s2.to_string()
return s4 >= s5
+# 11.9.3
def AbstractEC(ctx, x, y):
"""
Implements the Abstract Equality Comparison x == y
@@ -248,5 +262,8 @@
def uminus(obj, ctx):
if isinstance(obj, W_IntNumber):
- return W_IntNumber(-obj.ToInteger())
+ intval = obj.ToInteger()
+ if intval == 0:
+ return W_FloatNumber(-float(intval))
+ return W_IntNumber(-intval)
return W_FloatNumber(-obj.ToNumber())
diff --git a/js/builtins_math.py b/js/builtins_math.py
--- a/js/builtins_math.py
+++ b/js/builtins_math.py
@@ -12,8 +12,8 @@
put_property(global_object, 'Math', w_Math)
put_native_function(w_Math, 'abs', js_abs, params = ['x'])
- put_native_function(w_Math, 'floor', floor)
- put_native_function(w_Math, 'round', js_round)
+ put_native_function(w_Math, 'floor', floor, params = ['x'])
+ put_native_function(w_Math, 'round', js_round, params = ['x'])
put_native_function(w_Math, 'random', random)
put_native_function(w_Math, 'min', js_min, params = ['value1', 'value2'])
put_native_function(w_Math, 'max', js_max, params = ['value1', 'value2'])
@@ -58,16 +58,13 @@
# 15.8.2.9
def floor(this, args):
- if len(args) < 1:
+ arg0 = get_arg(args, 0)
+ x = arg0.ToNumber()
+
+ if isnan(x):
return NAN
- val = args[0].ToNumber()
-
- pos = math.floor(val)
- if isnan(val):
- pos = INFINITY
-
- return pos
+ return math.floor(x)
# 15.8.2.1
def js_abs(this, args):
@@ -81,10 +78,52 @@
# 15.8.2.15
def js_round(this, args):
- return floor(this, args)
+ arg0 = get_arg(args, 0)
+ x = arg0.ToNumber()
+
+ if isnan(x):
+ return x
+
+ if x == 0:
+ return x
+
+ if x > 0 and x < 0.5:
+ return 0
+
+ if x < 0 and x >= -0.5:
+ return -0.0
+
+ if isinf(x):
+ return x
+
+ return math.floor(x + 0.5)
def isodd(i):
- isinstance(i, int) and i % 2 == 1
+ return i % 2 == 1
+
+CMP_LT = -1
+CMP_GT = 1
+CMP_EQ = 0
+def cmp_signed_zero(a, b):
+ from js.baseop import sign
+ sign_a = sign(a)
+ sign_b = sign(b)
+
+ if a == 0 and b == 0:
+ if sign_a < sign_b:
+ return CMP_LT
+ if sign_a > sign_b:
+ return CMP_GT
+ return CMP_EQ
+
+ if a < b:
+ return CMP_LT
+ if a > b:
+ return CMP_GT
+ return CMP_EQ
+
+def eq_signed_zero(a, b):
+ return cmp_signed_zero(a, b) is CMP_EQ
# 15.8.2.13
def js_pow(this, args):
@@ -118,20 +157,20 @@
if x == -INFINITY and y > 0 and not isodd(y):
return INFINITY
if x == -INFINITY and y < 0 and isodd(y):
- return -0
+ return -0.0
if x == -INFINITY and y < 0 and not isodd(y):
return 0
- if x == 0 and y > 0:
+ if eq_signed_zero(x, 0.0) and y > 0:
return 0
- if x == 0 and y < 0:
+ if eq_signed_zero(x, 0.0) and y < 0:
return INFINITY
- if x == -0 and y > 0 and isodd(y):
- return -0
- if x == -0 and y > 0 and not isodd(y):
+ if eq_signed_zero(x, -0.0) and y > 0 and isodd(y):
+ return -0.0
+ if eq_signed_zero(x, -0.0) and y > 0 and not isodd(y):
return +0
- if x == -0 and y < 0 and isodd(y):
+ if eq_signed_zero(x, -0.0) and y < 0 and isodd(y):
return -INFINITY
- if x == -0 and y < 0 and not isodd(y):
+ if eq_signed_zero(x, -0.0) and y < 0 and not isodd(y):
return INFINITY
if x < 0 and not isinstance(y, int):
return NAN
@@ -188,7 +227,11 @@
if not values:
return INFINITY
- return min(values)
+ result = min(values)
+ if result == 0 and -0.0 in values:
+ return -0.0
+
+ return result
# 15.8.2.12
def js_max(this, args):
diff --git a/js/test/ecma/Expressions/11.13.2-2.js b/js/test/ecma/Expressions/11.13.2-2.js
--- a/js/test/ecma/Expressions/11.13.2-2.js
+++ b/js/test/ecma/Expressions/11.13.2-2.js
@@ -141,15 +141,15 @@
Number.POSITIVE_INFINITY,
eval("VAR1 = 0; VAR2 = Number.POSITIVE_INFINITY; VAR2 /= VAR1; VAR2") );
-//new TestCase( SECTION,
-// "VAR1 = -0; VAR2= Infinity; VAR2 /= VAR1",
-// Number.NEGATIVE_INFINITY,
-// eval("VAR1 = -0; VAR2 = Number.POSITIVE_INFINITY; VAR2 /= VAR1; VAR2") );
-//
-//new TestCase( SECTION,
-// "VAR1 = -0; VAR2= -Infinity; VAR2 /= VAR1",
-// Number.POSITIVE_INFINITY,
-// eval("VAR1 = -0; VAR2 = Number.NEGATIVE_INFINITY; VAR2 /= VAR1; VAR2") );
+new TestCase( SECTION,
+ "VAR1 = -0; VAR2= Infinity; VAR2 /= VAR1",
+ Number.NEGATIVE_INFINITY,
+ eval("VAR1 = -0; VAR2 = Number.POSITIVE_INFINITY; VAR2 /= VAR1; VAR2") );
+
+new TestCase( SECTION,
+ "VAR1 = -0; VAR2= -Infinity; VAR2 /= VAR1",
+ Number.POSITIVE_INFINITY,
+ eval("VAR1 = -0; VAR2 = Number.NEGATIVE_INFINITY; VAR2 /= VAR1; VAR2") );
new TestCase( SECTION,
"VAR1 = 0; VAR2= -Infinity; VAR2 /= VAR1",
@@ -201,15 +201,15 @@
Number.POSITIVE_INFINITY,
eval("VAR1 = 1; VAR2 = 0; VAR1 /= VAR2; VAR1") );
-//new TestCase( SECTION,
-// "VAR1 = 1; VAR2= -0; VAR1 /= VAR2",
-// Number.NEGATIVE_INFINITY,
-// eval("VAR1 = 1; VAR2 = -0; VAR1 /= VAR2; VAR1") );
+new TestCase( SECTION,
+ "VAR1 = 1; VAR2= -0; VAR1 /= VAR2",
+ Number.NEGATIVE_INFINITY,
+ eval("VAR1 = 1; VAR2 = -0; VAR1 /= VAR2; VAR1") );
-//new TestCase( SECTION,
-// "VAR1 = -1; VAR2= 0; VAR1 /= VAR2",
-// Number.NEGATIVE_INFINITY,
-// eval("VAR1 = -1; VAR2 = 0; VAR1 /= VAR2; VAR1") );
+new TestCase( SECTION,
+ "VAR1 = -1; VAR2= 0; VAR1 /= VAR2",
+ Number.NEGATIVE_INFINITY,
+ eval("VAR1 = -1; VAR2 = 0; VAR1 /= VAR2; VAR1") );
new TestCase( SECTION,
"VAR1 = -1; VAR2= -0; VAR1 /= VAR2",
diff --git a/js/test/ecma/Expressions/11.5.2.js b/js/test/ecma/Expressions/11.5.2.js
--- a/js/test/ecma/Expressions/11.5.2.js
+++ b/js/test/ecma/Expressions/11.5.2.js
@@ -95,8 +95,8 @@
new TestCase( SECTION, "Number.POSITIVE_INFINITY / 0", Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY / 0 );
new TestCase( SECTION, "Number.NEGATIVE_INFINITY / 0", Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY / 0 );
-//new TestCase( SECTION, "Number.POSITIVE_INFINITY / -0", Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY / -0 );
-//new TestCase( SECTION, "Number.NEGATIVE_INFINITY / -0", Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY / -0 );
+new TestCase( SECTION, "Number.POSITIVE_INFINITY / -0", Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY / -0 );
+new TestCase( SECTION, "Number.NEGATIVE_INFINITY / -0", Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY / -0 );
// Division of an infinity by a non-zero finite value results in a signed infinity.
@@ -139,8 +139,8 @@
// Division of a non-zero finite value by a zero results in a signed infinity.
new TestCase( SECTION, "1 / 0", Number.POSITIVE_INFINITY, 1/0 );
-//new TestCase( SECTION, "1 / -0", Number.NEGATIVE_INFINITY, 1/-0 );
-//new TestCase( SECTION, "-1 / 0", Number.NEGATIVE_INFINITY, -1/0 );
+new TestCase( SECTION, "1 / -0", Number.NEGATIVE_INFINITY, 1/-0 );
+new TestCase( SECTION, "-1 / 0", Number.NEGATIVE_INFINITY, -1/0 );
new TestCase( SECTION, "-1 / -0", Number.POSITIVE_INFINITY, -1/-0 );
new TestCase( SECTION, "0 / Number.POSITIVE_INFINITY", 0, 0 / Number.POSITIVE_INFINITY );
diff --git a/js/test/ecma/Math/15.8.2.11.js b/js/test/ecma/Math/15.8.2.11.js
--- a/js/test/ecma/Math/15.8.2.11.js
+++ b/js/test/ecma/Math/15.8.2.11.js
@@ -166,11 +166,10 @@
-0,
Math.max(-0,-0) );
-// we do not have a -0
-//new TestCase( SECTION,
-// "Infinity/Math.max(-0,-0)",
-// -Infinity,
-// Infinity/Math.max(-0,-0) );
+new TestCase( SECTION,
+ "Infinity/Math.max(-0,-0)",
+ -Infinity,
+ Infinity/Math.max(-0,-0) );
new TestCase( SECTION,
"Math.max(Infinity, Number.MAX_VALUE)", Number.POSITIVE_INFINITY,
diff --git a/js/test/ecma/Math/15.8.2.12.js b/js/test/ecma/Math/15.8.2.12.js
--- a/js/test/ecma/Math/15.8.2.12.js
+++ b/js/test/ecma/Math/15.8.2.12.js
@@ -162,14 +162,14 @@
-0,
Math.min(-0,-0) );
-//new TestCase( SECTION,
-// "Infinity/Math.min(0,-0)",
-// -Infinity,
-// Infinity/Math.min(0,-0) );
-//
-//new TestCase( SECTION,
-// "Infinity/Math.min(-0,-0)",
-// -Infinity,
-// Infinity/Math.min(-0,-0) );
+new TestCase( SECTION,
+ "Infinity/Math.min(0,-0)",
+ -Infinity,
+ Infinity/Math.min(0,-0) );
+
+new TestCase( SECTION,
+ "Infinity/Math.min(-0,-0)",
+ -Infinity,
+ Infinity/Math.min(-0,-0) );
test();
diff --git a/js/test/ecma/Math/15.8.2.13.js b/js/test/ecma/Math/15.8.2.13.js
--- a/js/test/ecma/Math/15.8.2.13.js
+++ b/js/test/ecma/Math/15.8.2.13.js
@@ -195,15 +195,15 @@
0,
Math.pow(Number.POSITIVE_INFINITY, -1) );
-//new TestCase( SECTION,
-// "Math.pow(-Infinity, 1)",
-// Number.NEGATIVE_INFINITY,
-// Math.pow(Number.NEGATIVE_INFINITY, 1) );
+new TestCase( SECTION,
+ "Math.pow(-Infinity, 1)",
+ Number.NEGATIVE_INFINITY,
+ Math.pow(Number.NEGATIVE_INFINITY, 1) );
-//new TestCase( SECTION,
-// "Math.pow(-Infinity, 333)",
-// Number.NEGATIVE_INFINITY,
-// Math.pow(Number.NEGATIVE_INFINITY, 333) );
+new TestCase( SECTION,
+ "Math.pow(-Infinity, 333)",
+ Number.NEGATIVE_INFINITY,
+ Math.pow(Number.NEGATIVE_INFINITY, 333) );
new TestCase( SECTION,
"Math.pow(Infinity, 2)",
@@ -230,10 +230,10 @@
-0,
Math.pow(Number.NEGATIVE_INFINITY, -1) );
-//new TestCase( SECTION,
-// "Infinity/Math.pow(-Infinity, -1)",
-// -Infinity,
-// Infinity/Math.pow(Number.NEGATIVE_INFINITY, -1) );
+new TestCase( SECTION,
+ "Infinity/Math.pow(-Infinity, -1)",
+ -Infinity,
+ Infinity/Math.pow(Number.NEGATIVE_INFINITY, -1) );
new TestCase( SECTION,
"Math.pow(-Infinity, -3)",
@@ -320,15 +320,15 @@
-0,
Math.pow(-0,3) );
-//new TestCase( SECTION,
-// "Infinity/Math.pow(-0, 1)",
-// -Infinity,
-// Infinity/Math.pow(-0, 1) );
+new TestCase( SECTION,
+ "Infinity/Math.pow(-0, 1)",
+ -Infinity,
+ Infinity/Math.pow(-0, 1) );
-//new TestCase( SECTION,
-// "Infinity/Math.pow(-0, 3)",
-// -Infinity,
-// Infinity/Math.pow(-0,3) );
+new TestCase( SECTION,
+ "Infinity/Math.pow(-0, 3)",
+ -Infinity,
+ Infinity/Math.pow(-0,3) );
new TestCase( SECTION,
"Math.pow(-0, 2)",
@@ -340,15 +340,15 @@
0,
Math.pow(-0, Number.POSITIVE_INFINITY) );
-//new TestCase( SECTION,
-// "Math.pow(-0, -1)",
-// Number.NEGATIVE_INFINITY,
-// Math.pow(-0, -1) );
+new TestCase( SECTION,
+ "Math.pow(-0, -1)",
+ Number.NEGATIVE_INFINITY,
+ Math.pow(-0, -1) );
-//new TestCase( SECTION,
-// "Math.pow(-0, -10001)",
-// Number.NEGATIVE_INFINITY,
-// Math.pow(-0, -10001) );
+new TestCase( SECTION,
+ "Math.pow(-0, -10001)",
+ Number.NEGATIVE_INFINITY,
+ Math.pow(-0, -10001) );
new TestCase( SECTION,
"Math.pow(-0, -2)",
diff --git a/js/test/ecma/Math/15.8.2.17.js b/js/test/ecma/Math/15.8.2.17.js
--- a/js/test/ecma/Math/15.8.2.17.js
+++ b/js/test/ecma/Math/15.8.2.17.js
@@ -122,10 +122,10 @@
-0,
Math.sqrt(-0));
-//new TestCase( SECTION,
-// "Infinity/Math.sqrt(-0)",
-// -Infinity,
-// Infinity/Math.sqrt(-0) );
+new TestCase( SECTION,
+ "Infinity/Math.sqrt(-0)",
+ -Infinity,
+ Infinity/Math.sqrt(-0) );
new TestCase( SECTION,
"Math.sqrt(Infinity)",
diff --git a/js/test/ecma/Math/15.8.2.18.js b/js/test/ecma/Math/15.8.2.18.js
--- a/js/test/ecma/Math/15.8.2.18.js
+++ b/js/test/ecma/Math/15.8.2.18.js
@@ -133,10 +133,10 @@
-1,
Math.tan(7*Math.PI/4));
-//new TestCase( SECTION,
-// "Infinity/Math.tan(-0)",
-// -Infinity,
-// Infinity/Math.tan(-0) );
+new TestCase( SECTION,
+ "Infinity/Math.tan(-0)",
+ -Infinity,
+ Infinity/Math.tan(-0) );
/*
Arctan (x) ~ PI/2 - 1/x for large x. For x = 1.6x10^16, 1/x is about the last binary digit of double precision PI/2.
diff --git a/js/test/ecma/Math/15.8.2.3.js b/js/test/ecma/Math/15.8.2.3.js
--- a/js/test/ecma/Math/15.8.2.3.js
+++ b/js/test/ecma/Math/15.8.2.3.js
@@ -128,10 +128,10 @@
-0,
Math.asin(-0) );
-//new TestCase( SECTION,
-// "Infinity/Math.asin(-0)",
-// -Infinity,
-// Infinity/Math.asin(-0) );
+new TestCase( SECTION,
+ "Infinity/Math.asin(-0)",
+ -Infinity,
+ Infinity/Math.asin(-0) );
new TestCase( SECTION,
"Math.asin(1)",
diff --git a/js/test/ecma/Math/15.8.2.4.js b/js/test/ecma/Math/15.8.2.4.js
--- a/js/test/ecma/Math/15.8.2.4.js
+++ b/js/test/ecma/Math/15.8.2.4.js
@@ -125,10 +125,10 @@
-0,
Math.atan(-0) );
-//new TestCase( SECTION,
-// "Infinity/Math.atan(-0)",
-// -Infinity,
-// Infinity/Math.atan(-0) );
+new TestCase( SECTION,
+ "Infinity/Math.atan(-0)",
+ -Infinity,
+ Infinity/Math.atan(-0) );
new TestCase( SECTION,
"Math.atan(Infinity)",
diff --git a/js/test/ecma/Math/15.8.2.5.js b/js/test/ecma/Math/15.8.2.5.js
--- a/js/test/ecma/Math/15.8.2.5.js
+++ b/js/test/ecma/Math/15.8.2.5.js
@@ -104,10 +104,10 @@
0,
Math.atan2(0,0) );
-//new TestCase( SECTION,
-// "Math.atan2(0, -0)",
-// Math.PI,
-// Math.atan2(0,-0) );
+new TestCase( SECTION,
+ "Math.atan2(0, -0)",
+ Math.PI,
+ Math.atan2(0,-0) );
new TestCase( SECTION,
"Math.atan2(0, -1)",
@@ -119,25 +119,25 @@
-0,
Math.atan2(-0, 1) );
-//new TestCase( SECTION,
-// "Infinity/Math.atan2(-0, 1)",
-// -Infinity,
-// Infinity/Math.atan2(-0,1) );
+new TestCase( SECTION,
+ "Infinity/Math.atan2(-0, 1)",
+ -Infinity,
+ Infinity/Math.atan2(-0,1) );
new TestCase( SECTION,
"Math.atan2(-0, 0)",
-0,
Math.atan2(-0,0) );
-//new TestCase( SECTION,
-// "Math.atan2(-0, -0)",
-// -Math.PI,
-// Math.atan2(-0, -0) );
+new TestCase( SECTION,
+ "Math.atan2(-0, -0)",
+ -Math.PI,
+ Math.atan2(-0, -0) );
-//new TestCase( SECTION,
-// "Math.atan2(-0, -1)",
-// -Math.PI,
-// Math.atan2(-0, -1) );
+new TestCase( SECTION,
+ "Math.atan2(-0, -1)",
+ -Math.PI,
+ Math.atan2(-0, -1) );
new TestCase( SECTION,
"Math.atan2(-1, 0)",
@@ -164,10 +164,10 @@
-0,
Math.atan2(-1,Number.POSITIVE_INFINITY) );
-//new TestCase( SECTION,
-// "Infinity/Math.atan2(-1, Infinity)",
-// -Infinity,
-// Infinity/Math.atan2(-1,Infinity) );
+new TestCase( SECTION,
+ "Infinity/Math.atan2(-1, Infinity)",
+ -Infinity,
+ Infinity/Math.atan2(-1,Infinity) );
new TestCase( SECTION,
"Math.atan2(-1,-Infinity)",
diff --git a/js/test/ecma/Math/15.8.2.6.js b/js/test/ecma/Math/15.8.2.6.js
--- a/js/test/ecma/Math/15.8.2.6.js
+++ b/js/test/ecma/Math/15.8.2.6.js
@@ -100,10 +100,10 @@
Infinity,
Infinity/Math.ceil('0'));
-//new TestCase( SECTION,
-// "Infinity/Math.ceil('-0')",
-// -Infinity,
-// Infinity/Math.ceil('-0'));
+new TestCase( SECTION,
+ "Infinity/Math.ceil('-0')",
+ -Infinity,
+ Infinity/Math.ceil('-0'));
new TestCase( SECTION,
"Math.ceil(0)",
@@ -120,10 +120,10 @@
Infinity,
Infinity/Math.ceil(0));
-//new TestCase( SECTION,
-// "Infinity/Math.ceil(-0)",
-// -Infinity,
-// Infinity/Math.ceil(-0));
+new TestCase( SECTION,
+ "Infinity/Math.ceil(-0)",
+ -Infinity,
+ Infinity/Math.ceil(-0));
new TestCase( SECTION,
@@ -141,10 +141,10 @@
-0,
Math.ceil(-Number.MIN_VALUE) );
-//new TestCase( SECTION,
-// "Infinity/Math.ceil(-Number.MIN_VALUE)",
-// -Infinity,
-// Infinity/Math.ceil(-Number.MIN_VALUE) );
+new TestCase( SECTION,
+ "Infinity/Math.ceil(-Number.MIN_VALUE)",
+ -Infinity,
+ Infinity/Math.ceil(-Number.MIN_VALUE) );
new TestCase( SECTION,
"Math.ceil(1)",
@@ -161,10 +161,10 @@
-0,
Math.ceil(-0.9) );
-//new TestCase( SECTION,
-// "Infinity/Math.ceil(-0.9)",
-// -Infinity,
-// Infinity/Math.ceil(-0.9) );
+new TestCase( SECTION,
+ "Infinity/Math.ceil(-0.9)",
+ -Infinity,
+ Infinity/Math.ceil(-0.9) );
new TestCase( SECTION,
"Math.ceil(0.9 )",
More information about the pypy-commit
mailing list