Mac端末では、大きな数字を丸めたいと思います。例えばシェルコマンドで大きな数値を丸める方法は?
、10時
^13位:
1234567812345678 - > 1230000000000000
または10^12位で:
1234567812345678 - > 1235000000000000
だから私は希望場所を指定し、丸められた番号を取得します。 どうすればいいですか?
Mac端末では、大きな数字を丸めたいと思います。例えばシェルコマンドで大きな数値を丸める方法は?
、10時
^13位:
1234567812345678 - > 1230000000000000
または10^12位で:
1234567812345678 - > 1235000000000000
だから私は希望場所を指定し、丸められた番号を取得します。 どうすればいいですか?
あなたはarithmetic expansion使用することができます。
$ val=1234567812345678
$ echo $((${val: -13:1} < 5 ? val - val % 10**13 : val - val % 10**13 + 10**13))
1230000000000000
$ echo $((${val: -12:1} < 5 ? val - val % 10**12 : val - val % 10**12 + 10**12))
1235000000000000
このチェックを最も重要な削除桁が5以上であり、かつそれがある場合は、最後の重要な除去されなかった桁が1増加した場合、次に、(潜在的に変更された)初期値から除算剰余を減算する。
あなたはそれをこのように記述する必要はしたくない場合は、少しの機能でそれをラップすることができます:
round() {
echo $((${1: -$2:1} < 5 ? $1 - $1 % 10**$2 : $1 - $1 % 10**$2 + 10**$2))
}
このように使用することができます:
$ round "$val" 13
1230000000000000
$ round "$val" 12
1235000000000000
お知らせ$val
の引用は厳密には必要ではありませんが、それは単なる良い習慣です。
ワンライナーはあまりにも不可解である場合、これは同じのより読みやすいバージョンです:
round() {
local rounded=$(($1 - $1 % 10**$2)) # Truncate
# Check if most significant removed digit is >= 5
if ((${1: -$2:1} >= 5)); then
((rounded += 10**$2))
fi
echo $rounded
}
別に算術展開から、これはまた、部分文字列を取得するには、パラメータの拡張を使用しています。「を取るため${1: -$2:1}
スタンド$1
、後ろから$2
を数え、1文字を取ります。 -$2
の前にスペースがなければなりません(またはカッコ内にある必要があります)。それ以外の場合は、別の拡張として解釈され、$1
が設定されていないか、nullであるかどうかがチェックされます。
実際には、n桁の有効数字に丸めたい場合は、伝統的な数学と文字列を混ぜることで最も効果的です。
深刻なデバッグが学生に任されているが、これは、私はすぐにbashシェルのために思い付いたものですし、MACが十分近いことを望む:
function rounder { local value=$1; local digits=${2:-3}; local zeros="$(eval "printf '0%.0s' {1..$digits}")"; #proper zeros # a bit of shell magic that repats the '0' $digits times. if ((value > 1$zeros)); then # large enough to require rounding local length=${#value}; local digits_1=$(($digits + 1)); #digits + 1 local tval="${value:0:$digits_1}"; #leading digits, plus one tval=$(($tval + 5)); #half-add local tlength=${#tval}; #check if carried a digit local zerox=""; if ((tlength > length)); then zerox="0"; fi value="${tval:0:$digits}${zeros:0:$((length-$digits))}$zerox"; fi echo "$value"; }
が、これははるかに短い行うことができる方法を参照してください、それはまた別です生徒のための運動。
inherit problems withinによる浮動小数点数の回避。
マイナスの数字のようなあらゆる特殊なケースはカバーされません。
'zeros =" $(eval "printf ...')の代わりに、 'printf -v zero 'を使って同じ効果を得ることができます。 –
awk
の[s]printf
機能は、倍精度浮動小数点演算の範囲内で、あなたのため丸め行うことができます。純粋なbash
実装については
$ for p in 13 12; do
awk -v p="$p" '{ n = sprintf("%.0f", $0/10^p); print n * 10^p }' <<<1234567812345678
done
1230000000000000
1235000000000000
は、Benjamin W.'s helpful answerを参照してください。
これは、丸めよりも切り捨てに似ており、正規表現を使用して文字の置換を行うことができます。 – mpez0