Diary

Diary

日々学んだことをアウトプットする場として初めてみました

awk で四捨五入を行う

AWK は非常に強力な言語なのですが、残念なことに標準の関数として四捨五入を行うことができません。

そこで今回、任意の桁に対して四捨五入を行う方法をメモしておこうと思います。

小数点以下で四捨五入する

つまり、小数点第1位の数を四捨五入することを考えます

AWK にはint(x)が用意されているので、それをうまく使います。

元の数に対して 0.5 を足したもののintをとってあげる(整数部分のみ取り出す)と、元々の小数点いかが 0.5 以上のもののみ、1つ上の整数になり 0.4 以下と差別化できることがわかります

$ echo 3.14 | awk '{print int($1 + 0.5)}'
3
$ echo 3.73 | awk '{print int($1 + 0.5)}' 
4

任意の桁で四捨五入する

今回は一例として、

<number> <digit>

のような標準入力が与えられたとき、少数第<digit>位を四捨五入する、といったケースを考えます。(先程の例で言うと、num=3.14, digit=1です)

方針としては、

  1. 0.05 や 0.0005 など、四捨五入したい桁の部分に 5 を足して、0~4と5~9で差別化を図る
  2. 差が出る<digit>-1桁の部分がちょうど整数一桁となるように、数を10**(<digit>-1)倍だけする
  3. 整数部分のみを取る
  4. 元のオーダーに戻すために、10**(<digit>-1)でわる

となります。これを AWK で書いたものがしたになります。

# 直感的な考え方
## step 1
$ echo 14.36 2 | awk '{print $1+5*10**(-$2)}'
14.41
## step 2
$ echo 14.36 2 | awk '{print ($1+5*10**(-$2))*10**($2-1)}'
144.1
## step 3
$ echo 14.36 2 | awk '{print int(($1+5*10**(-$2))*10**($2-1))}'
144
## step 4(最終形)
$ echo 14.36 2 |\
awk '{print int(($1+5*10**(-$2))*10**($2-1))/(10**($2-1))}'
14.4

# 式的にまとめたもの
$ echo 3.14159265 5 |\
awk '{print int(($1*10**($2-1)+0.5))/(10**($2-1))}'
3.1416

おわりに

おわり