Attachment "round.patch" to
ticket [1340260fff]
added by
mdejong
2005-10-28 11:22:55.
2005-10-27 Mo DeJong <[email protected]>
* 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