首页 > 解决方案 > 我是否正确比较了 tcl 中的十六进制值?

问题描述

我在 if 语句中做一些简单的十六进制比较。

0x7843E0 大于 0x780000 但下面的代码不输出任何内容。

if {"780000" <= "7843E0"} {
    puts "True!"
}
>>

但是,省略尾随 0 可以正常工作。

if {"780000" <= "7843E"} {
    puts "True!"
}
>>> True!

后面的 0 一定有问题,但我不明白它是什么。有任何想法吗?

标签: comparisontcl

解决方案


您在expr命令解析数字的方式上遇到问题。(Tcl 的其余部分对此更加放松。)问题是:

  • "780000"被解释为十进制整数
  • "7843E0"被解释为双精度浮点数。(比较1.2e10; 数字解析器认为它适合相同的模式。)
  • "780000"被解释为十进制整数
  • "7843E"被解释为非数字字符串(回退,因为没有数字解释是合法的)。

如果<=两个数字都是数字,则操作员会很高兴地比较两个数字,如果至少有一个参数是非数字的,则操作员会很乐意比较两个字符串。(是的,这确实偶尔会产生奇怪的语义。)此外,expr如果可能的话,他的命令渴望将值解释为数字,但它仍然具有 Tcl 的语法规则,用于说明什么是数字,以及这些东西是什么类型的数字。当你不遵守规则时,它会变得有点奇怪。

要获得解释为十六进制的值,您必须在其字符串表示前面加上0x(例如, 0x7843E0)使用命令强制执行操作,例如scanwith %x

scan "780000" %x a
scan "7843E0" %x b
if {$a <= $b} {
    puts "True"
}

强制解释scan被认为是处理此问题的最佳方法之一,因为它只会将规范值写入变量。(如果您一直想要处理八进制数,或者想要真正始终是十进制数,您可以分别使用%o%d%f用于浮点数。)

最后,如果您真的将值作为字符串与普通的类似 ASCII 的规则进行比较,请查看string compare而不是<=直接使用。

if {[string compare $input1 $input2] <= 0} {
    ...
}

推荐阅读