2005-10-27  Mo DeJong  <mdejong@users.sourceforge.net>

	* generic/tclBasic.c (ExprRoundFunc): Simplify
        the round() implementation by incrementing
        the integer part and then casting to a big
        num or a long type.
	* tests/expr.test: Add round() test cases near
        the min and max int values.

Index: generic/tclBasic.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclBasic.c,v
retrieving revision 1.176
diff -u -r1.176 tclBasic.c
--- generic/tclBasic.c	9 Oct 2005 20:05:17 -0000	1.176
+++ generic/tclBasic.c	28 Oct 2005 04:07:59 -0000
@@ -5637,30 +5637,20 @@
 
 	fractPart = modf(*((CONST double *)ptr), &intPart);
 	if (fractPart <= -0.5) {
-	    min++;
+	    intPart += -1.0;
 	} else if (fractPart >= 0.5) {
-	    max--;
+	    intPart += 1.0;
 	}
-	if ((intPart >= (double)max) || (intPart <= (double)min)) {
+	if ((intPart > (double)max) || (intPart < (double)min)) {
 	    mp_int big;
 	    if (TclInitBignumFromDouble(interp, intPart, &big) != TCL_OK) {
 		/* Infinity */
 		return TCL_ERROR;
 	    }
-	    if (fractPart <= -0.5) {
-		mp_sub_d(&big, 1, &big);
-	    } else if (fractPart >= 0.5) {
-		mp_add_d(&big, 1, &big);
-	    }
 	    Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big));
 	    return TCL_OK;
 	} else {
 	    long result = (long)intPart;
-	    if (fractPart <= -0.5) {
-		result--;
-	    } else if (fractPart >= 0.5) {
-		result++;
-	    }
 	    Tcl_SetObjResult(interp, Tcl_NewLongObj(result));
 	    return TCL_OK;
 	}
Index: tests/expr.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/expr.test,v
retrieving revision 1.47
diff -u -r1.47 expr.test
--- tests/expr.test	21 Oct 2005 21:49:35 -0000	1.47
+++ tests/expr.test	28 Oct 2005 04:08:06 -0000
@@ -6555,6 +6555,37 @@
     expr {round($x)}
 } 0
 
+test expr-46.13 {round() boundary case - largest int} {
+    set imax 2147483647
+    expr {round($imax - 0.51)}
+} 2147483646
+
+test expr-46.14 {round() boundary case - largest int} {
+    set imax 2147483647
+    expr {round($imax - 0.50)}
+} 2147483647
+
+test expr-46.15 {round() boundary case - becomes wide int} {
+    set imax 2147483647
+    expr {round($imax + 0.50)}
+} 2147483648
+
+test expr-46.16 {round() boundary case - smallest int} {
+    set imin -2147483648
+    expr {round($imin + 0.51)}
+} -2147483647
+
+test expr-46.17 {round() boundary case - smallest int} {
+    set imin -2147483648
+    expr {round($imin + 0.50)}
+} -2147483648
+
+test expr-46.18 {round() boundary case - becomes wide int} {
+    set imin -2147483648
+    expr {round($imin - 0.50)}
+} -2147483649
+
+
 # cleanup
 if {[info exists a]} {
     unset a
