2014-07-11 119 views
2
# the unit of period is picosecond 
set period 625000.0 

set period_sec [format %3.6g [expr $period * 1e-12]] 
puts $period_sec 

结果:6.25e-07TCL格式化浮点

有没有办法迫使TCL获得像625E-09

+0

我想要的结果无论是在E-09或E-12 –

+0

A排序的工程符号的东西?好问题;想不到任何简单的事情(而且我将在一天的其余时间里失去互联网,所以不能找出更复杂的东西......) –

+0

如果你的结果是'6.25e-10',应该怎么办? ?它应该成为'e-09'还是'e-12'? (基本上,总是指数上下或最接近的一个? – Jerry

回答

1

假设你希望把它格式化到最近的指数,你可以使用一个proc哪些格式是这样的:

proc fix_sci {n} { 

    # Not a sci-fmt number with negative exponent 
    if {![string match "*e-*" $n]} {return $n} 

    # The set of exponents 
    set a 9 
    set b 12 

    # Grab the number (I called it 'front') and the exponent (called 'exp') 
    regexp -- {(-?[0-9.]+)e-0*([0-9]+)} $n - front exp 

    # Check which set of exponent is closer to the exponent of the number 
    if {[expr {abs($exp-$a)}] < [expr {abs($exp-$b)}]} { 

    # If it's the first, get the difference and adjust 'front' 
    set dif [expr {$exp-$a}] 
    set front [expr {$front/(10.0**$dif)}] 
    set exp $a 
    } else { 

    # If it's the first, get the difference and adjust 'front' 
    set dif [expr {$exp-$b}] 
    set front [expr {$front/(10.0**$dif)}] 
    set exp $b 
    } 

    # Return the formatted numbers, front in max 3 digits and exponent in 2 digits 
    return [format %3ge-%.2d $front $exp] 
} 

请注意,您原有的代码返回6.25e-007(3个位数指数)。

如果您需要更改规则或舍入指数,则必须更改if部分(即[expr {abs($exp-$a)}] < [expr {abs($exp-$b)}])。例如$exp >= $a可以用来格式化指数为9或以下的格式。

ideone demo上面代码为'最接近'的指数。


为TCL 8.5版本之前,使用的pow(10.0,$dif)代替10.0**$dif

+0

你的proc为我工作,非常感谢 –

+1

@TigranKhachikyan真棒!另外,看到了你的其他评论,你可以简化它只获得e-09/e-12只使用'如果'和选择你需要的一个(无论是'a'还是'b'),如果你需要这两者中的任何一个。 – Jerry

0

我不认为这有什么的结果格式化命令,这将直接帮助你。但是,如果考虑对格式代码略有变化,那么它可能是一个更容易得到你想要的东西(有位字符串操作):

format %#3.6g $number 

给出了一个数字,如:6.25000e-007

这可以更容易地解析:

  • 提取指数
  • 确定位置的数量来移动小数点
  • 移动它并替换指数

这不是完全直截了当,但我认为它应该是可行的。维基页面http://wiki.tcl.tk/5000可能会给你一些启发。