TCL:将整数转换为任意长度的二进制字符串

发布于 2025-02-09 03:27:41 字数 216 浏览 3 评论 0原文

我需要一种将整数从小数形式转换为二进制形式的方法。我必须有可能指定输出位字符串的位长度。如果长度超过输入表示所需的长度,则根据输入的符号,额外的位将用0或1填充。如果指定的位长度太小,无法用于输入号,则该过程必须生成错误。

我认为应该使用TCL中的“二进制格式”程序存在解决方案,但我感到困惑。似乎该过程转化为十六进制。我不确定TCL是否可以按照内置功能进行直接转换,或者我必须编写自定义过程并逐步进行。

I need a way to convert integer from decimal form to binary form. I must be possible to specify the bit length of the output bit string. If the length is more than is required for input representation then the extra bits will be padded with 0 or 1 depending on the sign of the input. If the specified bit length is too small for the input number then the procedure must generate an error.

I believe that a solution should exist with the "binary format" procedure in TCL but it has me confused. It seem that the procedure converts into hexadecimal. I am not sure if TCL can do direct conversion the way I need using built-in functions, or I will have to write a custom procedure and do it step by step.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

葬﹪忆之殇 2025-02-16 03:27:41

>命令可以将一个数字表示为二进制:

set num 42
set width 10
puts [format "%0*b" $width $num]
# => 0000101010

set num -42
puts [format "%0*b" $width $num]
# => 1111111111111111111111111111111111111111111111111111111111010110

格式是TCL的sprintf


%b在TCL 8.6中介绍。

该代码改编自 http://rosettacode.org/wiki/wiki/binary_digits

proc num2bin {num width} {
    binary scan [binary format "I" $num] "B*" binval
    return [string range $binval end-$width end]
}

num2bin 42 10
# => 00000101010

be be告诉我,我发现二进制格式/扫描也令人困惑。


另一种方法:

set num 42
set wid
set bin_digits {}

while {$num > 0} {
    lappend bin_digits [expr {$num % 2}]
    set n [expr {$num / 2}]
}
set binval [join [lreverse $bin_digits] ""]

puts [format {%0*s} $width $binval]

The format command can express a number as binary:

set num 42
set width 10
puts [format "%0*b" $width $num]
# => 0000101010

set num -42
puts [format "%0*b" $width $num]
# => 1111111111111111111111111111111111111111111111111111111111010110

format is Tcl's sprintf


%b was introduced in Tcl 8.6.

This code was adapted from http://rosettacode.org/wiki/Binary_digits#Tcl

proc num2bin {num width} {
    binary scan [binary format "I" $num] "B*" binval
    return [string range $binval end-$width end]
}

num2bin 42 10
# => 00000101010

Truth be told, I find binary format/scan perplexing too.


Another approach:

set num 42
set wid
set bin_digits {}

while {$num > 0} {
    lappend bin_digits [expr {$num % 2}]
    set n [expr {$num / 2}]
}
set binval [join [lreverse $bin_digits] ""]

puts [format {%0*s} $width $binval]
人间☆小暴躁 2025-02-16 03:27:41

如果您使用的是TCL的版本太旧了,无法支持%B格式,则可以使用一次查看一位的PROC模拟它:

# Positive numbers only
proc num2binary {n width} {
    set bin ""
    while {$n > 0} {
        # Or set bin [string cat [expr {$n & 1}] $bin] in 8.6
        set bin "[expr {$n & 1}]$bin" 
        set n [expr {$n >> 1}]
    }
    format "%0*s" $width $bin
}

puts [num2binary 42 10]

此版本使用位操作和字符串而不是Modulo/部门和Glenn的列表。如果这是一个问题,可能会更有效。

If you're using a version of tcl too old to support the %b format, you can emulate it with a proc that looks at one bit at a time:

# Positive numbers only
proc num2binary {n width} {
    set bin ""
    while {$n > 0} {
        # Or set bin [string cat [expr {$n & 1}] $bin] in 8.6
        set bin "[expr {$n & 1}]$bin" 
        set n [expr {$n >> 1}]
    }
    format "%0*s" $width $bin
}

puts [num2binary 42 10]

This version uses bit operations and strings instead of the modulo/division and lists like Glenn's. Might be more efficient if that's a concern.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文