如何在Tcl中生成数字序列

时间:2016-07-18 11:34:34

标签: list numbers tcl generator sequence

我正在寻找根据输入fromtostep参数生成数字列表的方法。

使用incr并不好,因为我也想支持floatdouble个数字。

例如,如果from=-0.3to=0.25step=0.1,我想生成列表-0.3 -0.2 -0.1 0 0.1 0.2。我在格式化和舍入方面遇到了麻烦。

4 个答案:

答案 0 :(得分:2)

这是classic problem in computing。严重。

您需要做的是无论如何都要使用整数迭代,然后按步长进行缩放。这最大限度地减少了错误。您还需要仔细使用format

set from -0.3
set to 0.25
set step 0.1
for {set i 0} true {incr i} {
    set x [expr {$i*$step + $from}]
    if {$x > $to} break
    set printable [format "%.1f" $x]
    puts "$i => $printable"
}

答案 1 :(得分:1)

如果您可以自己删除字符串前缀:

proc genNums {{from 0} {to 1} {step .1} {prec 1}} {
    if {$step < 0} {
        set op ::tcl::mathop::>
    } else {
        set op ::tcl::mathop::<
    }
    for {set n $from} {[$op $n $to]} {set n [expr {$n + $step}]} {
        lappend res [format %.*f $prec $n]
    }
    return $res 
}

% genNums -0.3 0.25 0.1
# => -0.3 -0.2 -0.1 0.0 0.1 0.2
% genNums -0.3 0.25 0.1 2
# => -0.30 -0.20 -0.10 0.00 0.10 0.20

但是如果你愿意,你可以设置它,以便你可以将字符串传递给命令:

proc genNums args {
    array set params {from 0 to 1 step .1 prec 1}
    array set params [split [string map {= { }} $args]]
    if {$params(step) < 0} {
        set op ::tcl::mathop::>
    } else {
        set op ::tcl::mathop::<
    }
    for {set n $params(from)} {[$op $n $params(to)]} {set n [expr {$n + $params(step)}]} {
        lappend res [format %.*f $params(prec) $n]
    }
    return $res 
}

genNums from=-0.3 to=0.25 step=0.1
# => -0.3 -0.2 -0.1 0.0 0.1 0.2
% genNums from=-0.3 to=0.25 step=0.1 prec=2
# => -0.30 -0.20 -0.10 0.00 0.10 0.20

文档: + (operator)< (operator)arrayexprforformatiflappendprocreturnsetsplitstringMathematical operators as Tcl commands

答案 2 :(得分:0)

您如何看待以下解决方案:

if($('#Element_name').is(':visible')) { // you code goes here }

答案 3 :(得分:0)

以下是使用Tcl协程生成按需范围内的下一个值的示例

% proc range {from to step} {
    yield
    set value $from
    while {$value <= $to} {
        yield $value
        set value [expr {$value + $step}]
    }
}
% coroutine generator range -0.35 0.25 0.1
% puts [generator]
-0.35
% puts [generator]
-0.24999999999999997
% puts [generator]
-0.14999999999999997
% puts [generator]
-0.04999999999999996
% puts [generator]
0.050000000000000044
% puts [generator]
0.15000000000000005
% puts [generator]

% puts [generator]
invalid command name "generator"

正如Donal所说,在这里我们看到了累积的浮点错误。运用他的方法:

proc range {from to step} {
    yield
    set i 0
    while 1 {
        set value [expr {$from + $i * $step}]
        yield $value
        if {$value > $to} break
        incr i
    }
}

我们得到序列

-0.35
-0.24999999999999997
-0.14999999999999997
-0.04999999999999993
0.050000000000000044
0.15000000000000002
0.2500000000000001