我仍在寻找关于bc如何在函数中仅舍入一个值的纯净bash答案,但这是一个纯净答案:
#!/bin/bash
echo "Insert the price you want to calculate:"
read float
echo "This is the price without taxes:"
embiggen() {
local int precision fraction=""
if [ "$1" != "${1#*.}" ]; then # there is a decimal point
fraction="${1#*.}" # just the digits after the dot
fi
int="${1%.*}" # the float as a truncated integer
precision="${#fraction}" # the number of fractional digits
echo $(( 10**10 * $int$fraction / 10**$precision ))
}
# round down if negative
if [ "$float" != "${float#-}" ]
then round="-5000000000"
else round="5000000000"
fi
# calculate rounded answer (sans decimal point)
answer=$(( ( `embiggen $float` * 100 + $round ) / `embiggen 1.18` ))
int=${answer%??} # the answer as a truncated integer
echo $int.${answer#$int} # reassemble with correct precision
read -p "Press any key to continue..."
基本上,这会仔细地提取小数点,然后将所有内容乘以1000亿(10 10**10英寸,英寸bash),调整精度和舍入,执行实际的除法,除以适当的大小,然后重新插入小数点。
一步步:
该embiggen()函数将其参数的截断整数形式分配给$int,并将数字保存在中的点之后$fraction。小数位数在中注明$precision。数学乘以10 10通过的级联$int和$fraction,然后调节其到精确匹配(例如embiggen 48.86变为10 10×百分之四千八百八十六并返回488600000000其为4886亿)。
我们希望最终精度为百分之一,因此我们将第一个数字乘以100,为取整目的加5,然后将第二个数字除。这项任务$answer使我们得到最终答案的一百倍。
现在我们需要添加小数点。我们为新$int值分配一个$answer不包括其最后两位数字的值,然后给echo它加上一个点和$answer不包含在内$int的已被处理的值。(不要担心语法突出显示错误,使它看起来像注释)
(Bashism:幂运算不是POSIX,所以这是bashism。纯POSIX解决方案将要求循环添加零而不是使用10的幂。而且,“ embiggen”是一个完美的单词。)
我zsh用作外壳程序的主要原因之一是它支持浮点数学运算。这个问题的解决方案非常简单zsh:
printf %.2f $((float/1.18))
(我很乐意看到有人对此答案添加注释,并在中启用了浮点运算bash,但我很确定这种功能尚不存在。)