我试图在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这样的浮点数呢?
当前回答
There are scenarios in wich you cannot use bc becouse it might simply not be present, like in some cut down versions of busybox or embedded systems. In any case limiting outer dependencies is always a good thing to do so you can always add zeroes to the number being divided by (numerator), that is the same as multiplying by a power of 10 (you should choose a power of 10 according to the precision you need), that will make the division output an integer number. Once you have that integer treat it as a string and position the decimal point (moving it from right to left) a number of times equal to the power of ten you multiplied the numerator by. This is a simple way of obtaining float results by using only integer numbers.
其他回答
您需要多精确的输出?如果你的用例已经可以接受通过bin的近似值,你甚至可以更进一步,利用POSIX退出码[0:256)(所有其他整数修改回该范围)。
在gawk/nawk/mawk-1中,它已经给了我epoch秒到整数级别,但我想扩展它以提取近毫秒的精度,但不是过分迂迂的,我在POSIX shell中运行这个命令
exit $(( 10#` gdate +%5N ` * 256 / 100000 ))
直接分配一个表示0的5位整数。将gnu-date的XXXXXX输出到256个bin中的1个,然后在awk获得system()调用的退出码(即所选的bin #)后撤销这256个bin。我发现这种方法比使用完整的getline调用开销更低。
该方法还直接将输出捕获到POSIX退出码中,而不是打印出一个额外的终端。
(如果以这种方式编写,shell算术自动将其转换为整数而不是* 0.0256)。把它们放在awk函数中,就像这样。10#强制以10为基数,以防止posix shell将“01733”解释为八进制数。
function msecs() { # n x 2**-8 = n divided by 256
return 2^-8 * \
system( "exit \44\50\50 " \
" 10\43\140 gdate \53" \
"%5N\140 \52 " \
"256 \57 100000 \51\51" )
}
对于我自己的代码,我应用了另外0.6%的理发来考虑shell开销。
如何在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
对于那些试图用公认的答案计算百分比,但失去精度的人:
如果你运行这个:
echo "scale=2; (100/180) * 180" | bc
你只能得到99.00,这就失去了精确度。
如果你这样运行:
echo "result = (100/180) * 180; scale=2; result / 1" | bc -l
现在你得到99.99。
因为你只在打印的时候缩放。
参考此处
There are scenarios in wich you cannot use bc becouse it might simply not be present, like in some cut down versions of busybox or embedded systems. In any case limiting outer dependencies is always a good thing to do so you can always add zeroes to the number being divided by (numerator), that is the same as multiplying by a power of 10 (you should choose a power of 10 according to the precision you need), that will make the division output an integer number. Once you have that integer treat it as a string and position the decimal point (moving it from right to left) a number of times equal to the power of ten you multiplied the numerator by. This is a simple way of obtaining float results by using only integer numbers.
在浮点数出现之前,固定小数逻辑是被使用的:
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得到两个小数。