zsh while循环使用浮点运算在三重嵌套循环中过早退出

时间:2014-10-24 20:21:27

标签: shell floating-point zsh

我有一个zsh脚本应该生成一堆Z矩阵文件,但它在一次迭代后退出while循环。 N和M永远不会增加

#!/bin/zsh
n=0.5 
m=0.5
a=60.0
i=1

while [[ $n -le 1.5 ]];do
    while [[ $m -le 1.5 ]];do
        while [[ $a -le 160 ]];do
            echo $i
            echo "o" > H2O.$i.Z
            eval echo "h  1" $n >> H2O.$i.Z
            eval echo "h  1" $m "2" $a >> H2O.$i.Z

            let i=$i+1
            let a=$a+5.0
        done
        let m=$m+0.05
    done
    let n=$n+0.05
done

我是zsh的新手;我的语法错了吗?

2 个答案:

答案 0 :(得分:5)

-le运算符对整数运算。对于浮点数,请使用内置算法。 我也相信你可能真的想重新初始化内部循环中ma的值。然后问题是你只在开始时初始化它们一次,而第二次迭代的内部循环条件是假的。

您可以使用for((;;))循环来编写更紧凑的内容:

#!/usr/local/bin/zsh
i=1
for ((n=0.5; n <= 1.5; n+=0.05)); do
  for ((m=0.5; m <= 1.5; m+=0.05)); do
    for ((a=60.0; a <= 160; a+=5.0)); do
      echo $i $a $m $n
      let i=$i+1
    done
  done
done

另请注意,将浮点数用作循环计数 不明智。你知道十次0.1几乎不是一个吗?这可以解释为什么你会失去或获得额外的迭代。 相反,您应该使用整数N进行迭代,并将所需的浮点数计算为0.5 + N * 0.05,例如。

答案 1 :(得分:1)

-le运算符仅支持整数比较。对于浮点数,您需要使用((...))命令。此外,您不需要eval,并且您可以将三个回声合并为一个命令,因此您只需重定向一次。

while (( n < 1.5 )); do
  while (( m < 1.5 )); do
    while (( a <= 160 )); do
      echo $i
      { echo "o"; echo "h  1" $n; echo "h   1" $m "2" $a; } > H20.$i.Z
      ((i+=1))
      ((a+=5.0))
    done
    ((m+=0.05))
  done
  ((n+=0.5))
done