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

帅比萌擦擦* 提交于 2019-12-11 17:39:58

问题


The 0x3f800000 represents 1.0 in single precision floating maths. I tried this but could not get the correct result from the program:

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

I just want to "cast" the value of x into a float so it will print on screen as float. How do I do this in tcl?

Please note that in the original problem that I am trying to solve, a tcl script reads value from a hardware register in Quartus II System Console debug system. However, I have given a simple example code to make it easy for others to understand what I need to do.


回答1:


You can obtain the floating point value by converting the integer to a 4-byte binary string and then converting the binary string to a float:

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



回答2:


There's nothing builtin for that. But some time at https://en.wikipedia.org/wiki/Single-precision_floating-point_format led me to:

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}
}

And demonstrating:

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

And we can turn that an expr function like this:

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

So that:

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

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


来源:https://stackoverflow.com/questions/58935990/tcl-a-variable-stores-a-hex-value-that-represents-a-floating-point-number-how

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!