abs is one of several extended math commands available in Tclx. It makes the expr abs function available as a command, and takes expressions as arguments. (Tcl 8.5 has its own copy that it puts in the ::tcl::mathfunc namespace.)
If you don't have that, it can easily be emulated:
proc abs x {expr {abs($x)}}
AMG: In Tcl 8.4.7, expr {abs(-0.0)} returns -0.0. In Tcl 8.6b1, it returns 0.0. This is on an Intel Xeon platform running CentOS 4.2 (RedHat). Look for ExprAbsFunc in the 8.4.7 source code: [L1 ]:
d = valuePtr->internalRep.doubleValue; if (d < 0.0) { dResult = -d; } else { dResult = d; }
If d is -0.0, it's not less than 0.0, so it gets copied directly to dResult. This may be SF bug #2954959 [L2 ] and/or SF bug #1893815 [L3 ].
AMG: I found another problem with Tcl 8.4.7 abs. It seems I somehow convinced Tcl that "0" is a double, so "set x 0; expr {abs($x)}" returns 0.0. (This is actually fatal to my program.) My guess is that I used a "0"-valued Tcl_Obj somewhere else in a double-precision context, so Tcl imbued it with a double internal representation. When I later set a variable to "0", Tcl grabs the existing Tcl_Obj from its cache, and the intrep comes along for the ride. When this value is passed to abs, it sees it has a double intrep (never mind the fact that its string representation is not that of a double), so it returns a double.
Running the same program on the same machine in Tcl 8.6b1 doesn't trigger this problem. Either it's been fixed, or the problem is better hidden. ;^)
By the way, if I change from "set x 0" to "set x [expr 0]", my program works.
See also: