在tcl中是否有任何双最小正常变量来比较浮点数?

时间:2014-05-20 06:02:25

标签: compare double tcl

如果在tcl中它们相同,我想比较两个值(float)。这个我们可以直接用=运算符做,另外还有什么方法可以比较很小的差异。以下是不完整的代码,因为在tcl中我找不到 Tcl_Float_MIN_NORMAL

proc floatequal {a b {epsilon ""}} {
  if {[string is double -strict $a] && [string is double -strict $b]} {
    set diff [expr {$a -$b}]

    # handles infinities
    if {$a == $b} { 
      set ret 1;
    } elseif {$a == 0 || $b == 0 || $diff < $Tcl_Float_MIN_NORMAL} {
      # a or b is zero or both are extremely close to it
      # relative error is less meaningful here
      set ret [expr {$diff < ($epsilon * $Tcl_Float_MIN_NORMAL)}];
    } else { 
      # use relative error
      set ret [expr {$diff / ($a + $b) < $epsilon}];
    }
  }
}

1 个答案:

答案 0 :(得分:2)

Tcl没有定义这样的常量,但定义为使用IEEE双精度算术,后者又将MIN_NORMAL定义为2.2250738585072014e-308,即2 -1022 。如果您希望计算该值,请尝试expr {2.**-1022};请注意,Tcl在内部将可证明的常量子表达式转换为文字,因此使用计算形式不会产生显着的成本。另请注意,Tcl非常注意在字符串和双精度浮点数之间进行转换(包括恶意边缘情况!)和简约(因此使用最短字符串),因此转换可以被视为安全。

在Tcl中出现单精度浮点数的位置在binary formatbinary scan命令中,然后只是为了允许这些类型的值置于二元结构......


你的专栏:

set diff [expr $a -$b]

根本不安全,因为它可以对$a$b进行双重替换。这不是你的意思,Tcl小心翼翼地确保它不是你所需要的。您真正想要的是:

set diff [expr {$a - $b}]

大括号允许完整编译表达式。