Inf

RS 2007-02-23: Inf is for infinity. From Tcl 8.5 it is a valid double (though not integer) value, as these experiments in an 8.5a4 tclkit show:

 (bin) 3 % set x [expr 1/0.]
 Inf
 (bin) 4 % expr $x+1
 Inf
 (bin) 5 % expr $x*$x
 Inf
 (bin) 6 % expr $x-$x
 domain error: argument not in valid range
 (bin) 7 % expr -$x
 -Inf
 (bin) 8 % expr -$x+$x
 domain error: argument not in valid range
 (bin) 9 % expr {$x+1 == $x}
 1

LV Note that this appears to be platform specific, since the various examples on this page don't produce the same results on a SPARC Solaris machine.


LV Besides expr, where else does a Tcl programmer need to worry about Inf (or NaN for that matter?) - RS: binary scan may return it for a double. A general test for Inf and Nan would be

 proc is'special'float x {expr {$x != $x || [catch {expr $x-$x}]}}

Kroc : A Tcl programmer may need Inf as start value when he's looking for the smallest value in a test:

 while {[array size r]} { 
    set m Inf 
    foreach p [array names r] { 
      if {[llength $r($p)] < $m} { 
        set m [llength $r($p)] 
        set t $p 
      } 
    } 
    lappend R {*}$r($t) 
    unset r($t) 
  } 

DGP Just a bit of fair warning. I would not assume that all Inf and Nan behaviors seen in current alpha releases of Tcl 8.5 will necessarily remain unchanged. Users are only now confronting these issues and offering feedback. Sorting out what defaults are most useful, and what alternatives should be possible could still lead to changes during beta development.

LV Can I also assume that if, because it does some expr like stuff, is another place one should be aware that Inf or NaN might show up? - RS: Easily tested, in 8.5a4:

 % set n [expr sqrt(-1)]
 -NaN
 % if {$n != $n} {puts YES}
 YES
 % set i [expr 1/0.]
 Inf
 % if {$i+1 == $i} {puts YES}
 YES

KBK notes that the above test, because of roundoff issues, can be true for non-infinite quantities:

 % set x 9007199254740992.0
 9007199254740992.0
 % expr {$x + 1}
 9007199254740992.0

LV Yikes! When I first saw you use the word "roundoff", I was thinking decimal values... but in this case, we are talking the loss of whole numbers! Is there nothing that can be done in Tcl to counter this?

RS We discussed the issue in the chat, and a more robust Inf test seems to be

 ![catch {expr {$x-$x}}]

DKF: What about this:

 % expr Inf/65536.
 Inf

This operates on the exponent for non-Inf values, so odd roundoff won't bite.

Lars H: That still leaves 0 invariant. I think $i+1 == $i is probably better for many practical applications (treating "astronomically large" as "infinite" is sometimes The Right Thing).

AMG: Tcl 8.5+ version, returns true for finite numbers:

proc ::tcl::mathfunc::finite {x} {
    expr {[string is double -strict $x] && $x == $x && $x + 1 != $x}
}