我试图在Bash脚本中划分两个图像宽度,但Bash给我0作为结果:
RESULT=$(($IMG_WIDTH/$IMG2_WIDTH))
我确实研究了Bash指南,我知道我应该使用bc,在互联网上的所有例子中,他们都使用bc。在echo中,我试图把同样的东西放在我的SCALE中,但它不起作用。
以下是我在教程中找到的例子:
echo "scale=2; ${userinput}" | bc
我怎么能让巴斯给我0.5这样的浮点数呢?
我试图在Bash脚本中划分两个图像宽度,但Bash给我0作为结果:
RESULT=$(($IMG_WIDTH/$IMG2_WIDTH))
我确实研究了Bash指南,我知道我应该使用bc,在互联网上的所有例子中,他们都使用bc。在echo中,我试图把同样的东西放在我的SCALE中,但它不起作用。
以下是我在教程中找到的例子:
echo "scale=2; ${userinput}" | bc
我怎么能让巴斯给我0.5这样的浮点数呢?
当前回答
让我们举个例子来理解,如果你想找到n个数组元素的平均值(当然平均值将是浮点数/小数)
declare -a arr
echo "How many numbers you want to enter?"
read n
echo "Enter the Array Elements"
for(( i=0 ; i<$n ; i++))
do
read array_elements
arr[$i]="$array_elements"
done
sum=0
for i in "${arr[@]}"
do
#sum and avg
sum=$(($sum + $i))
#average will come in decimals
avg=`echo $sum / $n | bc -l`
done
# Output results:
printf "Average of Array Elements %.2f:" $avg
因此,我们将使用"| bc -l"来进行浮动计算
其他回答
bash
正如其他人指出的那样,bash不支持浮点运算,尽管您可以使用一些固定的小数技巧来伪造它,例如使用两个小数:
echo $(( 100 * 1 / 3 )) | sed -e 's/..$/.&/;t' -e 's/.$/.0&/'
输出:
.33
请参阅Nilfred的回答,了解类似但更简洁的方法。
选择
除了提到的bc和awk的替代品,还有以下:
clisp
clisp -x '(/ 1.0 3)'
清理输出:
clisp --quiet -x '(/ 1.0 3)'
或者通过stdin:
echo '(/ 1.0 3)' | clisp --quiet | tail -n1
dc
echo 2k 1 3 /p | dc
天才cli计算器
echo 1/3.0 | genius
ghostscript
echo 1 3 div = | gs -dNODISPLAY -dQUIET | sed -n '1s/.*>//p'
gnuplot
echo 'pr 1/3.' | gnuplot
Imagemagick
convert xc: -format '%[fx:1/3]' info:
或者通过stdin:
echo 1/3 | { convert xc: -format "%[fx:$(cat)]" info:; }
jq
jq -n 1/3
或者通过stdin:
echo 1/3 | jq -nf /dev/stdin
ksh
echo 'print $(( 1/3. ))' | ksh
lua
lua -e 'print(1/3)'
或者通过stdin:
echo 'print(1/3)' | lua
maxima
echo '1/3,numer;' | maxima
清理输出:
echo '1/3,numer;' | maxima --quiet | sed -En '2s/[^ ]+ [^ ]+ +//p'
node
echo 1/3 | node -p
倍频程
echo 1/3 | octave
perl
echo print 1/3 | perl
python2
echo print 1/3. | python2
python3
echo 'print(1/3)' | python3
R
echo 1/3 | R --no-save
清理输出:
echo 1/3 | R --vanilla --quiet | sed -n '2s/.* //p'
ruby
echo puts 1/3.0 | ruby
单位
units 1/3
输出紧凑:
units --com 1/3
水垢
echo 1/3 | wcalc
清理输出:
echo 1/3 | wcalc | tr -d ' ' | cut -d= -f2
zsh
print $(( 1/3. ))
或者通过stdin:
echo 'print $(( 1/3. ))' | zsh
其他来源
Stéphane Chazelas在UL上回答了类似的问题。
在浮点数出现之前,固定小数逻辑是被使用的:
IMG_WIDTH=100
IMG2_WIDTH=3
RESULT=$((${IMG_WIDTH}00/$IMG2_WIDTH))
echo "${RESULT:0:-2}.${RESULT: -2}"
33.33
最后一行是bashim,如果不使用bash,试试下面的代码:
IMG_WIDTH=100
IMG2_WIDTH=3
INTEGER=$(($IMG_WIDTH/$IMG2_WIDTH))
DECIMAL=$(tail -c 3 <<< $((${IMG_WIDTH}00/$IMG2_WIDTH)))
RESULT=$INTEGER.$DECIMAL
echo $RESULT
33.33
代码背后的基本原理是:在除之前乘以100得到两个小数。
如果你找到了你喜欢的变体,你也可以把它包装到一个函数中。
这里我将一些bashism包装到div函数中:
一个衬套:
function div { local _d=${3:-2}; local _n=0000000000; _n=${_n:0:$_d}; local _r=$(($1$_n/$2)); _r=${_r:0:-$_d}.${_r: -$_d}; echo $_r;}
或多行:
function div {
local _d=${3:-2}
local _n=0000000000
_n=${_n:0:$_d}
local _r=$(($1$_n/$2))
_r=${_r:0:-$_d}.${_r: -$_d}
echo $_r
}
现在你得到了这个函数
div <dividend> <divisor> [<precision=2>]
然后像这样使用它
> div 1 2
.50
> div 273 123 5
2.21951
> x=$(div 22 7)
> echo $x
3.14
更新 我添加了一个小脚本,为您提供了bash的基本浮点数操作:
用法:
> add 1.2 3.45
4.65
> sub 1000 .007
999.993
> mul 1.1 7.07
7.7770
> div 10 3
3.
> div 10 3.000
3.333
这里是脚本:
#!/bin/bash
__op() {
local z=00000000000000000000000000000000
local a1=${1%.*}
local x1=${1//./}
local n1=$((${#x1}-${#a1}))
local a2=${2%.*}
local x2=${2//./}
local n2=$((${#x2}-${#a2}))
local n=$n1
if (($n1 < $n2)); then
local n=$n2
x1=$x1${z:0:$(($n2-$n1))}
fi
if (($n1 > $n2)); then
x2=$x2${z:0:$(($n1-$n2))}
fi
if [ "$3" == "/" ]; then
x1=$x1${z:0:$n}
fi
local r=$(($x1"$3"$x2))
local l=$((${#r}-$n))
if [ "$3" == "*" ]; then
l=$(($l-$n))
fi
echo ${r:0:$l}.${r:$l}
}
add() { __op $1 $2 + ;}
sub() { __op $1 $2 - ;}
mul() { __op $1 $2 "*" ;}
div() { __op $1 $2 / ;}
下面是awk命令:-F =字段分隔符== +
echo "2.1+3.1" | awk -F "+" '{print ($1+$2)}'
正如其他人指出的那样,bash没有内置的浮点运算符。
您可以在bash中实现浮点数,甚至不使用bc和awk之类的计算器程序,或者任何与此相关的外部程序。
我在我的项目shellmath中正是这样做的,分三个基本步骤:
把数字分成整数部分和小数部分 使用内置的整数运算符分别处理各个部分,同时注意位值和进位 重新组合结果
作为一个挑逗,我添加了一个演示脚本,使用以x=0为中心的泰勒级数计算e。
如果您有时间,请查看一下。欢迎您的反馈!