在Bash中舍入一个分开的数字

时间:2010-03-07 05:25:18

标签: linux bash math shell rounding

如何从两个分开的数字中舍入结果,例如

3/2

就像我做的那样

testOne=$((3/2))

$ testOne包含“1”时应该向上舍入为“2”,因为答案来自3/2 = 1.5

10 个答案:

答案 0 :(得分:70)

要在截断算术中进行舍入,只需将(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

答案 1 :(得分:30)

良好的解决方案是获得最近的回合数

var=2.5
echo $var | awk '{print int($1+0.5)}'

如果var十进制值小于.5则逻辑很简单,那么最接近的值是整数值。好吧,如果十进制值大于.5,则添加下一个整数值,因为awk只接受整数部分。问题已解决

答案 2 :(得分:25)

bash不会给你正确的3/2结果,因为它不会做浮动pt数学。你可以使用像awk这样的工具

$ awk  'BEGIN { rounded = sprintf("%.0f", 3/2); print rounded }'
2

或bc

$ printf "%.0f" $(echo "scale=2;3/2" | bc)
2

答案 3 :(得分:8)

如果你有一个整数除数的正数向零舍入,那么你可以将一个小于除数的一个除数加到红利上,以使其向上舍入。

也就是说,将X / Y替换为(X + Y - 1) / Y

证明:

  • 案例1:X = k * Y(X是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 - 1k * Y + Y + m - 1,我们可以将分区写为(k * Y)/Y + Y/Y + (m - 1)/Y。自0 < m < Y0 <= m - 1 < Y - 1以来,最后一项(m - 1)/Y变为零。我们留下(k * Y)/Y + Y/Y,其结果为k + 1。这表明行为四舍五入。如果我们的Xk的{​​{1}}倍,如果我们只添加1,则该部分会向上舍入到Y

但这种四舍五入是完全相反的;所有不精确的分歧都会从零开始。两者之间怎么样?

这可以通过&#34;启动&#34;来实现。分子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 转到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向上舍入。

答案 4 :(得分:4)

要向上舍入,您可以使用模数。

如果剩下的话,等式的第二部分将加到True。 (True = 1; False = 0)

ex:3/2

answer=$(((3 / 2) + (3 % 2 > 0)))
echo $answer
2

ex:100/2

answer=$(((100 / 2) + (100 % 2 > 0)))
echo $answer
50

ex:100/3

answer=$(((100 / 3) + (100 % 3 > 0)))
echo $answer
34

答案 5 :(得分:4)

给定一个浮点值,我们可以用printf:

简单地舍入它
# round $1 to $2 decimal places
round() {
    printf "%.2f" "$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

答案 6 :(得分:2)

另一个解决方案是在python命令中进行除法。例如:

$ numerator=90
$ denominator=7
$ python -c "print (round(${numerator}.0 / ${denominator}.0))"

对我而言似乎比使用awk更为陈旧。

答案 7 :(得分:1)

我认为这应该足够了。

$ echo "3/2" | bc 

答案 8 :(得分:1)

如果小数点分隔符为逗号(例如:LC_NUMERIC = fr_FR.UTF-8,请参阅here):

$ 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

答案 9 :(得分:0)

以下为我工作。

 #!/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