Hi,
I wanted to handle NaN or Inf safely in a long math expression.
For example, sqrt(-1) results in domain error so I wrote a user defined function under tcl::mathfunc namespace.
proc is_computable_double {val} {
expr {[string is double -strict $val] && ![is_nan $val]}
}
proc is_nan {val} {
string match -nocase [string trimleft $val +-] "nan"
}
proc sqrtf {a} {
if {[is_computable_double $a] && $a >= 0} {
expr {sqrt($a)}
} else {
return NaN
}
}
proc tcl::mathfunc::sqrtf {a} {
::sqrtf $a
tcl::mathfunc::sqrtf -1; # => NaN
expr {sqrtf(-1)}; # => domain error: argument not in valid range
I noticed that expr never returns NaN. In such a case, it causes a domain error.
Is there any way to avoid it?
I had a danger expression like this.
set tau [expr {$uxy / (sqrt($uxx) * sqrt($uyy))}]
I made it safer by chaining some procedures.
set tau [divf $uxy [mulf [sqrtf $uxx] [sqrtf $uyy]]]
But I wanted to rewrite it as follows.
set tau [expr {divf($uxy,mulf(sqrtf($uxx),sqrtf($uyy)))}]
Above is a relatively short example but I have much longer expressions in my actual code.
So I wanted to make use of [expr] parser instead of nested procedures or something like tcl::mathfunc::sqrt...
Regards,
Yusuke