Tsuruoka@postman.riken.go.jp said:
> My program is polling Counter type data by snmp-get with scotty, but
> I don't know how to take difference of two counter values because of
> scotty's interger may be 32bits. In generaly, how do you program to
> evaluate SNMP Counter?
This is a sad story. I complained about Tcl's arithmetic at the Tcl/Tk
workshop but I did not get the impression that John Ousterhout will do
anything to fix the problems. It is a Tcl problem and well known for
years but you simply don't get in touch with it if you are writing
user interface with Tk.
Gorm Haug Eriksen <g.h.eriksen@usit.uio.no> wrote:
Gorm> My advice would be to either subtract a value from both
Gorm> counters as fast as you get it. This might not be possibile if
Gorm> the values are very big.
Gorm> Another soloution would be to use the double function in
Gorm> Tcl. Scotty must pad the values with some 0's, but in most
Gorm> cases this will not affect things that much.
The second solution does not work well because an unsigned 32 bit
value will automatically become a negative value whenever you pass it
to a function in expr:
expr double(2147483648) -> -2.14748e+09
Tcl is broken here. Why does scotty not simply return floating point
numbers? There are two important reasons:
set vbl [$s get ifNumber.0]
puts [format "ifNumber = %2d" [lindex [lindex $vbl 0] 2]]
This script does not work as the lindex command returns a floating
point value wich does not match the format specifier. I simply find it
ugly to either cast the value using an expr command to an integer in
cases like this or to use floating point format specifiers for integer
values or counter. A more serious problem is the second reason:
set vbl [$s get ifInUcastPkts.$i ifInNUcastPkts.$i]
set new [expr [lindex [lindex $vbl 0] 2] + [lindex [lindex $vbl 1] 2]]
set delta [expr $new - $old]
The result of this script depends on the value of tcl_precision as the
first expr command returns the result in a precision defined by
tcl_precision. To get accurate results, you have to set tcl_precision
to 17 all over the code.
I am convinced that there is no real solution without fixing the expr
command. However, most things actually work because if you substract a
big unsigned value from another big unsigned value, you will usually
get the correct result:
expr 2147483848 - 2147483648
If you want to convert an integer to a float, you have to use the ugly
way by appendig the string `.0'. Obviously, this only works if you are
sure that you do not already have a floating point value.
Juergen