TCL:变量存储表示浮点数的十六进制值,如何将其作为浮点数打印在屏幕上?

TCL: A variable stores a hex value that represents a floating point number, how can this be printed on screen as a float?

0x3f800000 在单精度浮点数学中表示 1.0。我试过了,但无法从程序中得到正确的结果:

set x 0x3f800000
set y [expr double($x)]
puts $y

我只是想 "cast" 将 x 的值转换为浮点数,以便它在屏幕上打印为浮点数。我如何在 tcl 中执行此操作?

请注意,在我试图解决的原始问题中,tcl 脚本从 Quartus II 系统控制台调试系统的硬件寄存器中读取值。但是,我给出了一个简单的示例代码,以方便其他人理解我需要做什么。

没有内置的东西。但在 https://en.wikipedia.org/wiki/Single-precision_floating-point_format 的某个时间让我:

proc binary32_to_double {value} {
    set sign [expr {($value & 0b10000000000000000000000000000000) >> 31}]
    set exp  [expr {($value & 0b01111111100000000000000000000000) >> 23}]
    set frac [expr {($value & 0b00000000011111111111111111111111) >>  0}]

    set frac_bits [format {%023b} $frac]
    set fraction 1.0

    for {set i 1} {$i <= 23} {incr i} {
        set bit [string range $frac_bits $i-1 $i-1]
        set fraction [expr {$fraction + $bit * 2**double(-$i)}]
    }

    expr {(-1)**$sign * 2**double($exp - 127) * $fraction}
}

并演示:

% binary32_to_double 0x3f800000
1.0
% binary32_to_double 0b00111110001000000000000000000000
0.15625
% binary32_to_double 0b10111110001000000000000000000000
-0.15625

我们可以像这样转换一个 expr 函数:

proc ::tcl::mathfunc::binary32 {value} {
    binary32_to_double $value
    # or, put that proc body here
}

这样:

set x 0x3f800000
set y [expr {binary32($x)}]   ;# => 1.0

set x 0b00111110001000000000000000000000
set y [expr {binary32($x)}]   ;# => 0.15625

您可以通过将整数转换为4字节的二进制字符串,然后将二进制字符串转换为浮点数来获取浮点值:

set x 0x3f800000
binary scan [binary format i $x] f y
puts $y