abs

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: