我需要使用TCL添加2个非常长的字符串格式的十六进制数字。如果字符串很短,我可以使用这样的东西:
set a "BEEF"
set b "F00D"
format "%X" [expr 0x$a+0x$b]
但是我的十六进制字符串非常长,上面最后一行的输出将导致"整数值太大而无法表示"。我正在考虑编写自己的proc来逐个添加数字(同时跟踪进位)或者在较小的块中打破字符串然后求和并合并在一起。那里有更好的解决方案吗?就像可能有帮助的内置TCL命令一样?
编辑:我需要使用TCL 8.4。
答案 0 :(得分:3)
(我在知道Tcl 8.4要求之前写了这个答案。这个解决方案适用于Tcl 8.5及更高版本。我将它留在这里,因为它可能对其他人有用。)
尝试使用
proc add {a b} {
expr {[tcl::mathfunc::entier 0x$a] + [tcl::mathfunc::entier 0x$b]}
}
函数entier
返回无限整数值。我用
add beefbeefbeefbeefbeefbeefbeefbeefbeefbeef f00df00df00df00df00df00df00df00df00df00d
# => 2460523363851273071965346074055892853050711060220
这可能足够好。我不知道答案是否正确,也无法弄清楚为什么函数被调用" entier",这通常是floor
函数的替代名称。
另请注意,format
命令无法将此大小的数字转换为十六进制表示法。
(经过我自己的聪明才智后,我意识到这也会起作用,无限整数显然是现在的默认值:(注意仍然是Tcl 8.6))
proc add {a b} {
expr [list 0x$a + 0x$b]
}
答案 1 :(得分:3)
尝试使用tcllib的::math::bignum
包。
package require math::bignum
set a [::math::bignum::fromstr $yourlargestring1 16]
set b [::math::bignum::fromstr $yourlargestring2 16]
set c [::math::bignum::add $a $b]
set result [::math::bignum::tostr $c 16]
文档:http://docs.activestate.com/activetcl/8.5/tcllib/math/bignum.html#1