Finish the work on __round__ and __trunc__.
With Alex Martelli and Keir Mierle.
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 908258c..09efa12 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -743,14 +743,7 @@
 }
 
 static PyObject *
-float_long(PyObject *v)
-{
-	double x = PyFloat_AsDouble(v);
-	return PyLong_FromDouble(x);
-}
-
-static PyObject *
-float_int(PyObject *v)
+float_trunc(PyObject *v)
 {
 	double x = PyFloat_AsDouble(v);
 	double wholepart;	/* integral portion of x, rounded toward 0 */
@@ -776,6 +769,55 @@
 }
 
 static PyObject *
+float_round(PyObject *v, PyObject *args)
+{
+#define UNDEF_NDIGITS (-0x7fffffff) /* Unlikely ndigits value */
+	double x;
+	double f;
+	double flr, cil;
+	double rounded;
+	int i;
+	int ndigits = UNDEF_NDIGITS;
+
+	if (!PyArg_ParseTuple(args, "|i", &ndigits))
+		return NULL;
+
+	x = PyFloat_AsDouble(v);
+
+	if (ndigits != UNDEF_NDIGITS) {
+		f = 1.0;
+		i = abs(ndigits);
+		while  (--i >= 0)
+			f = f*10.0;
+		if (ndigits < 0)
+			x /= f;
+		else
+			x *= f;
+	}
+
+	flr = floor(x);
+	cil = ceil(x);
+
+	if (x-flr > 0.5)
+		rounded = cil;
+	else if (x-flr == 0.5) 
+		rounded = fmod(flr, 2) == 0 ? flr : cil;
+	else
+		rounded = flr;
+
+	if (ndigits != UNDEF_NDIGITS) {
+		if (ndigits < 0)
+			rounded *= f;
+		else
+			rounded /= f;
+		return PyFloat_FromDouble(rounded);
+	}
+
+	return PyLong_FromDouble(rounded);
+#undef UNDEF_NDIGITS
+}
+
+static PyObject *
 float_float(PyObject *v)
 {
 	if (PyFloat_CheckExact(v))
@@ -976,6 +1018,11 @@
 static PyMethodDef float_methods[] = {
   	{"conjugate",	(PyCFunction)float_float,	METH_NOARGS,
 	 "Returns self, the complex conjugate of any float."},
+	{"__trunc__",	(PyCFunction)float_trunc, METH_NOARGS,
+         "Returns the Integral closest to x between 0 and x."},
+	{"__round__",	(PyCFunction)float_round, METH_VARARGS,
+         "Returns the Integral closest to x, rounding half toward even.\n"
+         "When an argument is passed, works like built-in round(x, ndigits)."},
 	{"__getnewargs__",	(PyCFunction)float_getnewargs,	METH_NOARGS},
 	{"__getformat__",	(PyCFunction)float_getformat,	
 	 METH_O|METH_CLASS,		float_getformat_doc},
@@ -1020,8 +1067,8 @@
 	0,		/*nb_xor*/
 	0,		/*nb_or*/
 	(coercion)0,	/*nb_coerce*/
-	float_int, 	/*nb_int*/
-	float_long, 	/*nb_long*/
+	float_trunc,	/*nb_int*/
+	float_trunc,	/*nb_long*/
 	float_float,	/*nb_float*/
 	0,		/* nb_oct */
 	0,		/* nb_hex */
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 518e607..ddf359d 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -3592,9 +3592,45 @@
 	return PyLong_FromLong((intptr_t)context);
 }
 
+static PyObject *
+long_round(PyObject *self, PyObject *args)
+{
+#define UNDEF_NDIGITS (-0x7fffffff) /* Unlikely ndigits value */
+	int ndigits = UNDEF_NDIGITS;
+	double x;
+	PyObject *res;
+	
+	if (!PyArg_ParseTuple(args, "|i", &ndigits))
+		return NULL;
+
+	if (ndigits == UNDEF_NDIGITS)
+		return long_long(self);
+
+	/* If called with two args, defer to float.__round__(). */
+	x = PyLong_AsDouble(self);
+	if (x == -1.0 && PyErr_Occurred())
+		return NULL;
+	self = PyFloat_FromDouble(x);
+	if (self == NULL)
+		return NULL;
+	res = PyObject_CallMethod(self, "__round__", "i", ndigits);
+	Py_DECREF(self);
+	return res;
+#undef UNDEF_NDIGITS
+}
+
 static PyMethodDef long_methods[] = {
 	{"conjugate",	(PyCFunction)long_long,	METH_NOARGS,
 	 "Returns self, the complex conjugate of any int."},
+	{"__trunc__",	(PyCFunction)long_long,	METH_NOARGS,
+         "Truncating an Integral returns itself."},
+	{"__floor__",	(PyCFunction)long_long,	METH_NOARGS,
+         "Flooring an Integral returns itself."},
+	{"__ceil__",	(PyCFunction)long_long,	METH_NOARGS,
+         "Ceiling of an Integral returns itself."},
+	{"__round__",	(PyCFunction)long_round, METH_VARARGS,
+         "Rounding an Integral returns itself.\n"
+	 "Rounding with an ndigits arguments defers to float.__round__."},
 	{"__getnewargs__",	(PyCFunction)long_getnewargs,	METH_NOARGS},
 	{NULL,		NULL}		/* sentinel */
 };