2つの分割された数字からの結果をどのように丸めますか?.
3/2
私がするときのように
testOne=$((3/2))
$ testOneには、3/2 = 1.5からの回答として「2」に切り上げられるべき場合に「1」が含まれます。
算術の切り捨てで切り上げを行うには、分子に(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 decimal値が.5より小さい場合、ロジックは単純です。最も近い値は整数値です。 10進値が.5より大きい場合、次の整数値が追加されます。awkは整数部分のみを取得するためです。解決した問題
bashは、浮動小数点演算を行わないため、3/2の正しい結果を提供しません。 awkのようなツールを使用できます
$ awk 'BEGIN { rounded = sprintf("%.0f", 3/2); print rounded }'
2
またはbc
$ printf "%.0f" $(echo "scale=2;3/2" | bc)
2
ゼロに丸める正の数値の整数除算がある場合、除数に除数より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
_になります。これは、動作が切り上げられることを示しています。 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
_
除数が偶数の正の数である場合は常に、分子がその数の半分に一致する場合は切り上げられ、それより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
_は切り上げられます。
切り上げるには、モジュラスを使用できます。
残りの部分がある場合、方程式の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
浮動小数点値を指定すると、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
別の解決策は、pythonコマンド内で分割を行うことです。例えば:
$ numerator=90
$ denominator=7
$ python -c "print (round(${numerator}.0 / ${denominator}.0))"
私にはawkを使用するよりも古風ではないようです。
小数点記号がコンマの場合(例: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
これで十分だと思います。
$ 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