Bash乘法和加法


18
for k in {0..49};
do
a=$(($((2*$k))+1));
echo $a;
done

嗨,我需要第三行的简化表达式,也许是不使用命令替换的表达式。


@Theophrastus:正如建议的那样,它工作正常,但是如果我想使用expr而不是(())呢?
AVS 2016年

bashC,所以删除所有;-除非你是在一个单一的线写。
ott--


declare -i a; for k in {0..49}; do a=2*$k+1; echo $a; done
赛勒斯

1
撇开:$(( ... ))算术扩展不是命令替换。
dave_thompson_085

Answers:


27

使用算术扩展:

for (( k = 0; k < 50; ++k )); do
  a=$(( 2*k + 1 ))
  echo "$a"
done

使用过时的expr实用程序:

for (( k = 0; k < 50; ++k )); do
  a=$( expr 2 '*' "$k" + 1 )
  echo "$a"
done

使用bc -l-l在这种情况下实际上不需要,因为未使用任何数学函数):

for (( k = 0; k < 50; ++k )); do
  a=$( bc -l <<<"2*$k + 1" )
  echo "$a"
done

使用bc -l作为共同加工的(它就像在background¹一种计算服务的):

coproc bc -l

for (( k = 0; k < 50; ++k )); do
  printf "2*%d + 1\n" "$k" >&${COPROC[1]}
  read -u "${COPROC[0]}" a
  echo "$a"
done

kill "$COPROC_PID"

最后一个看起来(可以说)更清洁 ksh93

bc -l |&
bc_pid="$!"

for (( k = 0; k < 50; ++k )); do
  print -p "2*$k + 1"
  read -p a
  print "$a"
done

kill "$bc_pid"

¹这一次为我解决了一个问题,我需要循环处理大量输入。该处理需要一些浮点计算,但会产生bc在循环中生成几次证明非常慢。是的,我可以通过许多其他方式解决它,但是我很无聊...



5

您可以使用该let命令强制进行计算。

let a="2*k+1"

注意,我们不需要$k这种结构。简单k就能胜任。


4
如果a=2whateverk+1当前目录中有一个文件,那将失败。更糟糕的是,如果有一个名为的文件a=2+b[$(reboot)]k+1,它将调用reboot命令。最好是用((...))在这里(((a = 2 * k + 1))),或POSIX语法:a=$((2 * k + 1))
斯特凡Chazelas

我们可以引用它;let a="2*k+1"解决这个问题。
史蒂芬·哈里斯

2

您可能需要的算术扩展是:

a=$(( 1+2*k ))

实际上,您不需要使用变量:

for k in {0..49}; do
    echo "$(( 1 + 2*k ))"
done

或将计数变量移至for ((…))循环中:

for (( k=0;k<50;k++ )); do
    a=$(( 1+2*k ))
    printf '%s\n' "$a"
done

for((...))循环

而且,在那种情况下,算术扩展也可以移到for循环内部:

for (( k=0 ; a=1+2*k , k<50 ;  k++)); do
    printf '%s\n' "$a"
done

或者,要获取数组中的所有值:

for (( k=0 ; a[k]=1+2*k , k<49 ;  k++ )); do :; done
printf '%s\n' "${a[@]}"

没有公式

但是,避免任何算术扩展的最短方法可能是将变量增加两次:

for (( k=0,a=1 ; k<50 ;  k++,a++,a++ )); do
    printf '%s\n' "$a"
done

或者,甚至更简单,只需使用seq:

seq 1 2 100
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.