diff -r 76e9c3e876d4 Lib/test/test_math.py --- a/Lib/test/test_math.py Sun May 29 20:46:27 2011 +0200 +++ b/Lib/test/test_math.py Sun Jun 05 11:03:39 2011 +0900 @@ -335,21 +335,34 @@ @requires_IEEE_754 def testCopysign(self): - self.assertEqual(math.copysign(1, 42), 1.0) + self.assertEqual(math.copysign(1, 42), 1) + self.assertEqual(math.copysign(1, -42), -1) self.assertEqual(math.copysign(0., 42), 0.0) self.assertEqual(math.copysign(1., -42), -1.0) - self.assertEqual(math.copysign(3, 0.), 3.0) + self.assertEqual(math.copysign(3, 0.), 3) self.assertEqual(math.copysign(4., -0.), -4.0) + # for big integer + n = 10 ** 100 + self.assertEqual(n + 1, math.copysign(-(n + 1), 1)) + self.assertEqual(-(n + 1), math.copysign(n + 1, -1)) self.assertRaises(TypeError, math.copysign) # copysign should let us distinguish signs of zeros + self.assertEqual(math.copysign(1, 0), 1) + self.assertEqual(math.copysign(-1, 0), -1) self.assertEqual(math.copysign(1., 0.), 1.) + self.assertEqual(math.copysign(-1., 0.), -1.) + self.assertEqual(math.copysign(1, 0.), 1) + self.assertEqual(math.copysign(-1, 0.), -1) + self.assertEqual(math.copysign(1, -0.), -1) self.assertEqual(math.copysign(1., -0.), -1.) self.assertEqual(math.copysign(INF, 0.), INF) self.assertEqual(math.copysign(INF, -0.), NINF) self.assertEqual(math.copysign(NINF, 0.), INF) self.assertEqual(math.copysign(NINF, -0.), NINF) # and of infinities + self.assertEqual(math.copysign(1, INF), 1) + self.assertEqual(math.copysign(1, NINF), -1) self.assertEqual(math.copysign(1., INF), 1.) self.assertEqual(math.copysign(1., NINF), -1.) self.assertEqual(math.copysign(INF, INF), INF) @@ -364,6 +377,8 @@ # we don't know whether the sign bit of NAN is set on any # given platform. self.assertTrue(math.isinf(math.copysign(INF, NAN))) + # similarly, copysign(2, NAN) could be 2 or -2 + self.assertEqual(abs(math.copysign(2, NAN)), 2) # similarly, copysign(2., NAN) could be 2. or -2. self.assertEqual(abs(math.copysign(2., NAN)), 2.) diff -r 76e9c3e876d4 Modules/mathmodule.c --- a/Modules/mathmodule.c Sun May 29 20:46:27 2011 +0200 +++ b/Modules/mathmodule.c Sun Jun 05 11:03:39 2011 +0900 @@ -821,14 +821,35 @@ static PyObject * math_2(PyObject *args, double (*func) (double, double), char *funcname) { - PyObject *ox, *oy; + PyObject *ox, *oy, *or, *zero, *absox; double x, y, r; if (! PyArg_UnpackTuple(args, funcname, 2, 2, &ox, &oy)) return NULL; x = PyFloat_AsDouble(ox); y = PyFloat_AsDouble(oy); - if ((x == -1.0 || y == -1.0) && PyErr_Occurred()) + if ((x == -1.0 || y == -1.0) && PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, "a float or integer is required"); return NULL; + } + if (strcmp(funcname, "copysign") == 0 && PyLong_Check(ox)) { + absox = PyNumber_Absolute(ox); + zero = PyLong_FromLong(0); + // occur error + //if (_PyLong_Sign(oy) < 0) + if (((PyFloatObject *)oy)->ob_fval < 0) + printf("((PyFloatObject *)oy)->ob_fval < 0\n"); + else + printf("((PyFloatObject *)oy)->ob_fval >= 0\n"); + if (PyObject_RichCompareBool(oy, zero, Py_LT)) + or = PyNumber_Negative(absox); + else if (PyObject_RichCompareBool(oy, zero, Py_GT)) + or = PyNumber_Positive(absox); + else + or = PyNumber_Long(ox); + Py_DECREF(zero); + Py_DECREF(absox); + return or; + } errno = 0; PyFPE_START_PROTECT("in math_2", return 0); r = (*func)(x, y);