相同代码的结果不同

时间:2013-06-25 15:28:59

标签: tcl

为什么这两段代码输出不同?

set j 0.0981747704247
set i 0.0981747704247
for { ; } { $i <= 25} {set i [expr {$i + $j}]} {
    puts "i = $i"
}
set j 0.0981747704247
set i 0.0981747704247
for {; } { $i <= 25 } {set i [expr $i + $j]} {
    puts "i = $i"
}

2 个答案:

答案 0 :(得分:2)

在8.5之前,这两次评估的结果可能会有所不同。使用括号表达式,这些小数值将保留为IEEE双精度浮点数,而使用 unbraced 表达式,值将转换为字符串(默认使用15位十进制数字),然后转回来了。正是那些导致价值变化的转换。

从Tcl 8.5开始,双精度浮点序列化引擎已更改,因此它会序列化为最短的字符串表示形式,该表示形式将被反序列化为相同的IEEE双倍。这意味着这两个脚本 - 不仅仅是事物是否被支撑 - 再次表现相同,关闭了一个微妙的语义洞。

但是你仍然应该支持你的表达式,因为Tcl可以主动使用有效的处理来处理你的代码。这也意味着 - 因为你没有重新编译表达式 - 你可以永远不会遇到杂散的“[file delete -force "/"]”或其他如此奇怪的用户输入的问题(因为它只是“不是有效数字”而不是“一块脚本”)。

答案 1 :(得分:1)

输出应该相同。但是,处理时间肯定会有所不同。 eval中的无支撑表达式将使该函数需要更多时间来评估,而支撑表达式将大约快80%。您可以在wiki上了解更多信息。

您还会发现一些更好地省略括号的实例,以及如何使用或不使用括号来改变可能看起来相同的表达式的结果。