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

Min*_*int 44 linux math bash shell rounding

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

3/2
Run Code Online (Sandbox Code Playgroud)

就像我一样

testOne=$((3/2))
Run Code Online (Sandbox Code Playgroud)

$ testOne包含"1",它应该向上舍入为"2",作为3/2 = 1.5的答案

Ben*_*igt 72

要在截断算术中进行舍入,只需添加(denom-1)到分子中.

例如,四舍五入:

N/2
M/5
K/16
Run Code Online (Sandbox Code Playgroud)

例如,四舍五入:

(N+1)/2
(M+4)/5
(K+15)/16
Run Code Online (Sandbox Code Playgroud)

要舍入到最近,添加(denom/2)到分子(一半将向上舍入):

(N+1)/2
(M+2)/5
(K+8)/16
Run Code Online (Sandbox Code Playgroud)

  • @Mint:他正在使用代数表示法显示一个广义的答案.使用你的Bash示例,它看起来像这样:`testOne = $(((3 +(2 - 1)/ 2))`.更一般地说,但是在Bash语法中,它会像`answer = $( (($ numerator +($ denominator - 1)/ $ denomonator))`.你也可以这样做,消除所有的美元符号,并允许更多的空间自由(如等号周围):`((答案) =(分子+(分母-1)/ denomonator))` (12认同)
  • 你能解释一下这个吗?什么意思是一个人?我真的不知道所有这些括号和字母在做什么......?我觉得我应该知道,因为没有其他答案和5+以上 (4认同)
  • 这仅适用于正数. (4认同)
  • @Dennis:是的,除了你的括号不平衡. (2认同)
  • 不正确的`testOne = $(((3 +(2 - 1)/ 2))`correct:`testOne = $(((3 +(2 - 1))/ 2))` (2认同)

Ash*_*ish 33

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

var=2.5
echo $var | awk '{print int($1+0.5)}'
Run Code Online (Sandbox Code Playgroud)

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


gho*_*g74 26

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

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

或者

$ printf "%.0f" $(echo "scale=2;3/2" | bc)
2
Run Code Online (Sandbox Code Playgroud)

  • 你应该注意到这是无偏见的舍入. (3认同)

Kaz*_*Kaz 9

如果你有一个整数除数的正数向零舍入,那么你可以将一个小于除数的一个除数加到被除数上以使它向上舍入.

也就是说,替换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 - 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一个k倍数Y,如果我们只加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
Run Code Online (Sandbox Code Playgroud)

每当除数是一个偶数,正数,如果分子与该数字的一半相等,它就会向上舍入,如果它小于该值则向下舍入.

例如,round 6 121,因为这样做,其等于所有值6,模12,像18(其变为2)等. round 5 12下到0.

对于奇数,行为是正确的.没有一个确切的有理数在两个连续的倍数之间.例如,11我们有一个分母5/11 < 5.5/11 (exact middle) < 6/11; 然后round 5 11向上round 6 11舍入,然后向上舍入.


sk8*_*123 5

要四舍五入,您可以使用模数。

如果有余数,等式的第二部分将与 True 相加。(真 = 1;假 = 0)

例如:3/2

answer=$(((3 / 2) + (3 % 2 > 0)))
echo $answer
2
Run Code Online (Sandbox Code Playgroud)

例如:100 / 2

answer=$(((100 / 2) + (100 % 2 > 0)))
echo $answer
50
Run Code Online (Sandbox Code Playgroud)

例如:100 / 3

answer=$(((100 / 3) + (100 % 3 > 0)))
echo $answer
34
Run Code Online (Sandbox Code Playgroud)


小智 5

给定一个浮点值,我们可以用printf以下方法对其进行四舍五入:

# round $1 to $2 decimal places
round() {
    printf "%.${2:-0}f" "$1"
}
Run Code Online (Sandbox Code Playgroud)

然后,

# 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
Run Code Online (Sandbox Code Playgroud)

或者,使用原始请求:

$ echo "3/2, rounded to the nearest integer, is $(round $(math "3/2") 0)"
3/2, rounded to the nearest integer, is 2
Run Code Online (Sandbox Code Playgroud)