我试图在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这样的浮点数呢?
当前回答
** bash/shell中的注入安全浮点数学
注意:这个回答的重点是为在bash(或其他shell)中执行数学的注入安全解决方案提供思路。当然,同样也可以使用,只需稍作调整即可执行高级字符串处理等。
所提出的大多数解决方案都是使用外部数据(变量、文件、命令行、环境变量)动态构造小脚本。外部输入可用于向引擎中注入恶意代码,其中很多是恶意代码
下面是使用各种语言进行基本数学计算的比较,其中结果为浮点数。它计算A + B * 0.1(作为浮点数)。
所有的解决方案都试图避免创建难以维护的动态脚本,而是使用静态程序,并将参数传递给指定的变量。它们将安全地处理具有特殊字符的参数-减少代码注入的可能性。例外是'BC',它不提供输入/输出功能
例外是'bc',它不提供任何输入/输出,所有数据都来自stdin中的程序,所有输出都到stdout。所有计算都在沙箱中执行,不允许出现副作用(打开文件等)。理论上,注射是安全的设计!
A=5.2
B=4.3
# Awk: Map variable into awk
# Exit 0 (or just exit) for success, non-zero for error.
#
awk -v A="$A" -v B="$B" 'BEGIN { print A + B * 0.1 ; exit 0}'
# Perl
perl -e '($A,$B) = @ARGV ; print $A + $B * 0.1' "$A" "$B"
# Python 2
python -c 'import sys ; a = float(sys.argv[1]) ; b = float(sys.argv[2]) ; print a+b*0.1' "$A" "$B"
# Python 3
python3 -c 'import sys ; a = float(sys.argv[1]) ; b = float(sys.argv[2]) ; print(a+b*0.1)' "$A" "$B"
# BC
bc <<< "scale=1 ; $A + $B * 0.1"
其他回答
如何在bash中进行浮点计算:
不同于在bc命令中使用"here strings"(<<<),这是我最喜欢的bc浮点示例,来自bc手册页的示例部分(参见man bc手册页)。
在我们开始之前,知道pi的方程是:pi = 4*atan(1)。下面的A()是atan()的BC数学函数。
This is how to store the result of a floating point calculation into a bash variable--in this case into a variable called pi. Note that scale=10 sets the number of decimal digits of precision to 10 in this case. Any decimal digits after this place are truncated. pi=$(echo "scale=10; 4*a(1)" | bc -l) Now, to have a single line of code that also prints out the value of this variable, simply add the echo command to the end as a follow-up command, as follows. Note the truncation at 10 decimal places, as commanded: pi=$(echo "scale=10; 4*a(1)" | bc -l); echo $pi 3.1415926532 Finally, let's throw in some rounding. Here we will use the printf function to round to 4 decimal places. Note that the 3.14159... rounds now to 3.1416. Since we are rounding, we no longer need to use scale=10 to truncate to 10 decimal places, so we'll just remove that part. Here's the end solution: pi=$(printf %.4f $(echo "4*a(1)" | bc -l)); echo $pi 3.1416
下面是上述技术的另一个非常棒的应用程序和演示:测量和打印运行时。
(参见我的另一个答案)。
注意,dt_min从0.01666666666…0.017:
start=$SECONDS; sleep 1; end=$SECONDS; dt_sec=$(( end - start )); dt_min=$(printf %.3f $(echo "$dt_sec/60" | bc -l)); echo "dt_sec = $dt_sec; dt_min = $dt_min"
dt_sec = 1; dt_min = 0.017
相关:
(我的回答)https://unix.stackexchange.com/questions/52313/how-to-get-execution-time-of-a-script-effectively/547849#547849 [我的问题]三个左尖括号(' <<< ')在bash中是什么意思? https://unix.stackexchange.com/questions/80362/what-does-mean/80368#80368 https://askubuntu.com/questions/179898/how-to-round-decimals-using-bc-in-bash/574474#574474
现在是尝试zsh的最佳时机,它是一个(几乎)bash超集,具有许多其他不错的特性,包括浮点数学。下面是你的例子在zsh中的样子:
% IMG_WIDTH=1080
% IMG2_WIDTH=640
% result=$((IMG_WIDTH*1.0/IMG2_WIDTH))
% echo $result
1.6875
这篇文章可能会帮助你:bash -值得切换到zsh随意使用?
让我们举个例子来理解,如果你想找到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"来进行浮动计算
它不是真正的浮点数,但如果你想在一次调用bc时设置多个结果…
source /dev/stdin <<<$(bc <<< '
d='$1'*3.1415926535897932384626433832795*2
print "d=",d,"\n"
a='$1'*'$1'*3.1415926535897932384626433832795
print "a=",a,"\n"
')
echo bc radius:$1 area:$a diameter:$d
计算半径为$1的圆的面积和直径
对于那些试图用公认的答案计算百分比,但失去精度的人:
如果你运行这个:
echo "scale=2; (100/180) * 180" | bc
你只能得到99.00,这就失去了精确度。
如果你这样运行:
echo "result = (100/180) * 180; scale=2; result / 1" | bc -l
现在你得到99.99。
因为你只在打印的时候缩放。
参考此处