web-dev-qa-db-ja.com

Bashで分割数を丸める

2つの分割された数字からの結果をどのように丸めますか?.

3/2

私がするときのように

testOne=$((3/2))

$ testOneには、3/2 = 1.5からの回答として「2」に切り上げられるべき場合に「1」が含まれます。

44
Mint

算術の切り捨てで切り上げを行うには、分子に(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
70
Ben Voigt

良い解決策は、最も近いラウンド数を取得することです

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

Var decimal値が.5より小さい場合、ロジックは単純です。最も近い値は整数値です。 10進値が.5より大きい場合、次の整数値が追加されます。awkは整数部分のみを取得するためです。解決した問題

32
Ashish

bashは、浮動小数点演算を行わないため、3/2の正しい結果を提供しません。 awkのようなツールを使用できます

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

またはbc

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

ゼロに丸める正の数値の整数除算がある場合、除数に除数より1少ない値を加算して切り上げます。

つまり、_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_になります。これは、動作が切り上げられることを示しています。 Xk倍数である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
_

除数が偶数の正の数である場合は常に、分子がその数の半分に一致する場合は切り上げられ、それより1つ少ない場合は切り捨てられます。

たとえば、_round 6 12_は_1_になり、_6_に等しいすべての値は、_12_を法として、_18_(2になります)のようになり、など。 _round 5 12_は_0_になります。

奇数の場合、動作は正しいです。正確な有理数は、2つの連続した倍数の中間ではありません。たとえば、_11_の分母では、5/11 < 5.5/11 (exact middle) < 6/11;があります。 _round 5 11_は切り捨てられますが、_round 6 11_は切り上げられます。

9
Kaz

切り上げるには、モジュラスを使用できます。

残りの部分がある場合、方程式の2番目の部分はTrueに追加されます。 (True = 1; False = 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
4
sk8asd123

浮動小数点値を指定すると、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
4
N. Ingersoll

別の解決策は、pythonコマンド内で分割を行うことです。例えば:

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

私にはawkを使用するよりも古風ではないようです。

2
Sean Staats

小数点記号がコンマの場合(例: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
1
Q-D

これで十分だと思います。

$ echo "3/2" | bc 
1
guest

次は私のために働いた。

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