[英]Round a divided number in Bash
我将如何从两个相除的数字中取整结果,例如
3/2
就像我做的那样
testOne=$((3/2))
$testOne 包含“1”,而它应该四舍五入为“2”作为 3/2=1.5 的答案
要在截断算术中进行四舍五入,只需将(denom-1)
添加到分子。
示例,四舍五入:
N/2
M/5
K/16
示例,四舍五入:
(N+1)/2
(M+4)/5
(K+15)/16
要进行四舍五入,请将(denom/2)
添加到分子(一半将向上取整):
(N+1)/2
(M+2)/5
(K+8)/16
好的解决方案是获得最近的整数是
var=2.5
echo $var | awk '{print int($1+0.5)}'
如果 var 十进制值小于 0.5,则逻辑很简单,则采用的最接近的值是整数值。 好吧,如果十进制值大于 0.5,则添加下一个整数值,因为 awk 只取整数部分。 问题已解决
bash 不会给你 3/2 的正确结果,因为它不做浮动 pt 数学。 你可以使用awk之类的工具
$ awk 'BEGIN { rounded = sprintf("%.0f", 3/2); print rounded }'
2
或公元前
$ printf "%.0f" $(echo "scale=2;3/2" | bc)
2
如果您有向零舍入的正数的整数除法,那么您可以在被除数上加上比除数少 1 以使其四舍五入。
也就是说,将X / Y
替换为(X + Y - 1) / Y
。
证明:
情况 1: X = k * Y
(X 是X = k * Y
整数倍):在这种情况下,我们有(k * Y + Y - 1) / Y
,分为(k * Y) / Y + (Y - 1) / Y
。 (Y - 1)/Y
部分四舍五入为零,我们剩下的商为k
。 这正是我们想要的:当输入可整除时,我们希望调整后的计算仍然产生正确的精确商。
情况 2: X = k * Y + m
,其中0 < m < Y
(X 不是 Y 的倍数)。 在这种情况下,我们有一个k * Y + m + Y - 1
或k * Y + Y + m - 1
的分子,我们可以将除法写为(k * Y)/Y + Y/Y + (m - 1)/Y
。 由于0 < m < Y
, 0 <= m - 1 < Y - 1
,所以最后一项(m - 1)/Y
变为零。 我们剩下(k * Y)/Y + Y/Y
,结果为k + 1
。 这表明该行为四舍五入。 如果我们有一个X
是Y
的k
Y
,如果我们只给它加 1,除法会向上k + 1
整为k + 1
。
但这种四舍五入是极其相反的; 所有不精确的除法都从零开始。 介于两者之间怎么样?
这可以通过用Y/2
“启动”分子来实现。 而不是X/Y
,计算(X+Y/2)/Y
。 代替证明,让我们对这一点进行实证:
$ round()
> {
> echo $((($1 + $2/2) / $2))
> }
$ round 4 10
0
$ round 5 10
1
$ round 6 10
1
$ round 9 10
1
$ round 10 10
1
$ round 14 10
1
$ round 15 10
2
当除数是偶数、正数时,如果分子等于该数的一半,则向上舍入,如果小于 1,则向下舍入。
例如, round 6 12
等于1
,所有等于6
值也是如此,取模12
,例如18
(等于 2)等等。 round 5 12
下降到0
。
对于奇数,行为是正确的。 没有一个精确的有理数介于两个连续的倍数之间。 例如,当分母为11
我们有5/11 < 5.5/11 (exact middle) < 6/11
; round 5 11
轮向下round 6 11
,而round 6 11
轮向上round 6 11
。
要四舍五入,您可以使用模数。
如果有余数,等式的第二部分将与 True 相加。 (真 = 1;假 = 0)
例如:3/2
answer=$(((3 / 2) + (3 % 2 > 0)))
echo $answer
2
例如:100 / 2
answer=$(((100 / 2) + (100 % 2 > 0)))
echo $answer
50
例如:100 / 3
answer=$(((100 / 3) + (100 % 3 > 0)))
echo $answer
34
给定一个浮点值,我们可以用printf
对其进行四舍五入:
# round $1 to $2 decimal places
round() {
printf "%.${2:-0}f" "$1"
}
然后,
# do some math, bc style
math() {
echo "$*" | bc -l
}
$ echo "Pi, to five decimal places, is $(round $(math "4*a(1)") 5)"
Pi, to five decimal places, is 3.14159
或者,使用原始请求:
$ echo "3/2, rounded to the nearest integer, is $(round $(math "3/2") 0)"
3/2, rounded to the nearest integer, is 2
如果小数点分隔符是逗号(例如:LC_NUMERIC=fr_FR.UTF-8,请参见此处):
$ printf "%.0f" $(echo "scale=2;3/2" | bc)
bash: printf: 1.50: nombre non valable
0
ghostdog74 解决方案需要替换:
$ printf "%.0f" $(echo "scale=2;3/2" | bc | sed 's/[.]/,/')
2
或者
$ printf "%.0f" $(echo "scale=2;3/2" | bc | tr '.' ',')
2
另一种解决方案是在 python 命令中进行除法。 例如:
$ numerator=90
$ denominator=7
$ python -c "print (round(${numerator}.0 / ${denominator}.0))"
对我来说似乎不如使用 awk 过时。
我认为这应该足够了。
$ echo "3/2" | bc
以下为我工作。
#!/bin/bash
function float() {
bc << EOF
num = $1;
base = num / 1;
if (((num - base) * 10) > 1 )
base += 1;
print base;
EOF
echo ""
}
float 3.2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.