为什么这两条代码输出不同?
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"
}
为什么这两条代码输出不同?
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"
}
在 8.5 之前,这两个评估的结果很可能是不同的。使用带括号的表达式,这些小数值将保留为 IEEE 双精度浮点数,而使用无括号的表达式,这些值将转换为字符串(默认使用 15 位精度的十进制数字),然后再次转换回来。正是这些转化导致了价值的变化。
从 Tcl 8.5 开始,双精度浮点序列化引擎发生了变化,因此它改为序列化为最短的字符串表示形式,该表示形式将被反序列化回相同的 IEEE 双精度。这意味着这两个脚本——在事物是否被支撑上有所不同——再次表现相同,关闭了一个微妙的语义漏洞。
但是你仍然应该支持你的表达式,因为这样 Tcl 可以积极地使用有效的处理来处理你的代码。这也意味着——因为你没有重新编译表达式——你永远不会遇到杂散“<code>[file delete -force "/"]”或其他此类奇怪的用户输入的问题(因为它只是“不是一个有效的数字”而不是“一段脚本”)。
输出应该是一样的。但是,处理时间肯定会有所不同。中的无括号表达式eval
将使函数需要更多时间来计算,而有括号的表达式将快 80% 左右。您可以在wiki上阅读更多内容。
您还会发现一些最好省略括号的情况,以及使用或不使用括号如何改变可能看起来相同的表达式的结果。