bc
関数内で1つの値だけを丸める方法に対する純粋な答えを探していますが、ここに純粋なbash
答えがあります。
#!/bin/bash
echo "Insert the price you want to calculate:"
read float
echo "This is the price without taxes:"
embiggen() {
local int precision fraction=""
if [ "$1" != "${1#*.}" ]; then # there is a decimal point
fraction="${1#*.}" # just the digits after the dot
fi
int="${1%.*}" # the float as a truncated integer
precision="${#fraction}" # the number of fractional digits
echo $(( 10**10 * $int$fraction / 10**$precision ))
}
# round down if negative
if [ "$float" != "${float#-}" ]
then round="-5000000000"
else round="5000000000"
fi
# calculate rounded answer (sans decimal point)
answer=$(( ( `embiggen $float` * 100 + $round ) / `embiggen 1.18` ))
int=${answer%??} # the answer as a truncated integer
echo $int.${answer#$int} # reassemble with correct precision
read -p "Press any key to continue..."
基本的に、これは小数点を慎重に抽出し、すべてを1,000億(10¹⁰、10**10
in bash
)で乗算し、精度と丸めを調整し、実際の除算を実行して適切な大きさに分割し、小数点を再挿入します。
ステップバイステップ:
embiggen()
関数は、に引数の切り捨て整数フォームを割り当てる$int
とのドットの後に番号を保存します$fraction
。小数桁数はに記載されてい$precision
ます。数学は、10¹⁰を連結して乗算$int
し$fraction
、それを調整して精度に一致させます(たとえば、embiggen 48.86
10¹⁰×4886/100になり、488,600,000,000になります488600000000
)。
100分の1の最終精度が必要なので、最初の数値に100を掛け、丸めのために5を加算してから、2番目の数値を除算します。この割り当てにより$answer
、最終的な回答の100倍になります。
次に、小数点を追加する必要があります。最後の2桁$int
を$answer
除外するために新しい値を割り当ててからecho
、ドットと既に処理されて$answer
いる$int
値を除外します。(これがコメントのように見える構文強調表示バグを気にしないでください)
(バシズム:べき乗はPOSIXではないため、これはバシズムです。純粋なPOSIXソリューションでは、10の累乗を使用するのではなく、ループをゼロに追加する必要があります。
zsh
シェルとして使用する主な理由の1つは、浮動小数点演算をサポートしていることです。この質問の解決策は、zsh
次のとおりです。
printf %.2f $((float/1.18))
(私は誰かがこの答えにコメントを追加して、浮動小数点演算を有効にするトリックを見てみたいと思っていますが、bash
そのような機能はまだ存在しないと確信しています。)